CVE-2021-37789 - Heap Buffer Overflow in stb_image.h (stbi__jpeg_load) Enables Data Leak & Crashes

If you’re a game developer, graphics programmer, or just someone who enjoys simplifying image handling with stb_image.h, there’s a chance you’ve used version 2.27 or earlier. That’s a problem: CVE-2021-37789 identifies a major vulnerability — a heap-based buffer overflow in the stbi__jpeg_load function. This bug can let attackers crash your app, or worse, steal data from it.

In this deep dive, we’ll explain what went wrong, show you snippets, detail how an exploit works, and link you to everything you need to patch your project.

What is stb_image.h?

- What: A public-domain header file for C/C++ that lets you load and decode images (JPEG, PNG, GIF, and more) in just a few lines.
- Where: stb_image.h on GitHub
- Who uses it: Game engines (Godot, Unity plugins), scientific tools, indie devs, students—pretty much anyone needing images without library bloat.

Function: stbi__jpeg_load

- Result: Attacker can read heap memory (“info leak”) or crash your program (“denial of service”).

Where’s the Flaw?

When stb_image handles certain malformed JPEG data, it doesn’t properly check if its code ends up writing or reading outside the buffer it allocates. This potentially allows data from adjacent memory locations to get spilled or read. That could leak sensitive data or crash your application.

Here is a (simplified) excerpt from the problematic region (for educational purposes)

// Vulnerable code excerpt from stb_image.h (pre-2.28)
static stbi__uint8 *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
{
    // ...
    int n = /* calculated from JPEG data */;
    stbi__uint8 *out = (stbi__uint8 *) STBI_MALLOC(n * sizeof(stbi__uint8));
    // ...    
    for (i = ; i < n; ++i) {
        out[i] = /* data from JPEG decoder */;
        // <-- Here, if 'n' is wrong, out-of-bounds memory can be accessed
    }
    // ...
}

What’s wrong?
If the JPEG is malformed, n may not correspond to the actual data, so this loop can overrun the allocated buffer. There aren’t enough checks to make sure “writing out[i]” won’t scribble across the heap.

Patched:
The maintainers added stricter validation on input data and checks on buffer sizes as of version 2.28.  
Patch commit reference

How attackers can exploit this:

- Create a specially crafted JPEG file with headers that trick stb_image into allocating a buffer smaller than what’s actually needed.

Best case (for attacker): Data such as keys, passwords, or other images leak.

- Common result: The app tries to access/free bad memory and crashes (DoS).

PoC Example (Crash)

Here’s some C code that loads an attacker-crafted JPEG (see links below for test files). This can segfault or spit out system data if run:

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <stdio.h>

int main(int argc, char **argv) {
    int x, y, n;
    unsigned char *data = stbi_load("malicious.jpg", &x, &y, &n, );
    if (!data) {
        puts(stbi_failure_reason());
        return 1;
    }
    printf("Loaded %dx%d image\n", x, y);
    stbi_image_free(data);
    return ;
}

Attack effect:

Application may crash, or

- In rare but serious cases, reveal memory contents following the allocated buffer—which could be passwords, keys, or app secrets.

Patch Immediately!

Update: Download and use stb_image.h version 2.28 or newer.
 

- #include "stb_image.h" // version 2.27 or earlier (unsafe)
+ #include "stb_image.h" // version 2.28+ (safe)

Validate untrusted images before loading (especially in user-facing apps).

- Consider running image conversion/parsing in a sandbox (e.g., restrict memory, separate process).

More Resources

- Original CVE Record: CVE Details
- Project Upstream Issue: GitHub Issue #1036
- Patch Commit: stb/stb@dfd7eab
- Public Exploit Example: huntr.dev advisory

Summary

CVE-2021-37789 is a clear warning about trusting untested inputs—even from “header only” libraries like stb_image.h. If you found this in your codebase, update immediately. It’s painless, and you’ll be protecting both your app and your users from accidental leaks or easy DoS attacks.

Timeline

Published on: 11/02/2022 13:15:00 UTC
Last modified on: 02/28/2023 18:31:00 UTC