Using CVE-2023-43641 as an example, I’ll explain how to develop an exploit for a memory corruption vulnerability on Linux. The exploit has to bypass several mitigations to achieve code execution.
In the ever-evolving software development landscape, static application security solutions face a unique challenge: as applications grow in complexity, they rely heavily on a diverse array of libraries, frameworks, and custom code. Ensuring the security of such intricate systems requires a meticulous approach—and not all solutions are created equal. The effectiveness of a static application security solution hinges on its ability to provide extensive vulnerability coverage and support for a wide range of languages and frameworks.
Code scanning, for example, is equipped with broad coverage for the most popular languages and frameworks and can scrutinize all parts of the codebase, leaving no stone unturned. This approach leads to the identification of an expansive array of vulnerabilities, including those specific to certain technologies or development patterns. The result is a more thorough and reliable assessment of an organization’s security posture.
We’re always looking for ways to help you detect more vulnerabilities in your codebase, so today, we’re highlighting two releases aimed at providing better coverage for both languages and frameworks, improved C++ vulnerability coverage and Lombok support.
Detecting vulnerabilities in C++ code is uniquely challenging because of the language’s low-level memory manipulation, complexity, undefined behavior, platform discrepancies, and the absence of built-in memory safety features. Legacy code, concurrency issues, and dynamic memory allocation further compound this difficulty. Addressing these vulnerabilities must be done with precision, including rigorous code reviews, extensive testing, and the adoption of secure coding practices.
CodeQL for C and C++ has recently gained increased support for detecting complex memory corruption vulnerabilities. Broadly speaking, these vulnerabilities are all related to dereferencing pointers that should not be dereferenced at a given point in the code.
For those who are interested in delving deeper into the technical aspects of this topic, below we’ll explore a couple of new kinds of vulnerabilities CodeQL can now detect.
The default query suite can now detect double-free and use-after-free vulnerabilities using the queries cpp/double-free and cpp/use-after-free. These are classic memory corruption issues that C and C++ developers constantly have to keep in mind to avoid creating serious security incidents.
In addition, the default query suite now also detects dereferences that look suspicious in general using the query cpp/redundant-null-check-simple. Finding “suspicious dereferences” in general is very hard since there are so many ways to make the dereference “obviously” safe. The query gets around these problems by finding dereferences that are always performed regardless of the result of a null check, or where a null check is always performed after the dereference (which suggests that the pointer may, in fact, sometimes be null).
The security-extended suite has also gained much better support for reasoning about buffer overflows with two new queries cpp/overrun-write and cpp/invalid-pointer-deref, which detect different kinds of pointer dereferences that may be out of bounds.
cpp/overrun-write perform a novel analysis that finds the size of an allocation by doing two “parallel” dataflow analyses (one dataflow analysis to track the pointer and another dataflow analysis to track the size of the allocation), which enable us to find places in the code where a pointer dereference is incorrectly guarded. Such “off by one” errors are very common, and we have confirmed that
cpp/invalid-pointer-deref finds existing CVEs such as https://www.cvedetails.com/cve/CVE-2018-14599/.
This is a CVE from 2018 on the LibX11 project, where a pointer that points to an element that is one past the end of the allocation is both read from and written to. When running
cpp/invalid-pointer-deref on the project before applying the fix commit, we get exactly two results: one for the read and one for the write:
Another CVE we can now catch is https://www.cvedetails.com/cve/CVE-2016-10160/. This is an off-by-one error in the PHP interpreter, where a write to a buffer is guarded incorrectly and a write to an element one past the end of the buffer is possible with a cleverly crafted PHAR archive. When running
cpp/invalid-pointer-deref on the project before applying the fix commit, CodeQL finds one result: the offending write:
While we have already made important advancements in what kinds of vulnerabilities CodeQL can detect, we are just getting started! Our current memory corruption queries are heavily focused on not producing too many alerts (as we do not want our developers to suffer from alert fatigue). We will be continuously improving our analysis to (in particular) reduce the number of false negatives, while retaining the low false positive rate that CodeQL is known for.
Lombok streamlines code development by automating the creation of common methods and behaviors, which significantly reduces boilerplate code. By automating common tasks, it saves developers time and encourages best practices, making it an indispensable tool for Java projects.
In September, we announced that CodeQL now supports Java codebases that use Project Lombok. Previously, code scanning users were able to scan Java applications that contained Lombok code, but all the contents of files containing Lombok code were either skipped or users had to apply a workaround to prepare the applications for scanning. The improved support means that code with Lombok features will now be automatically scanned without requiring any workaround.
GitHub is committed to helping build safer and more secure software without compromising DevEx. To learn more or enable GitHub’s security features in repositories, check out the getting started guide.