← Back to Research Index

CVE-2026-27784: Integer Overflow in nginx ngx_http_mp4_module causes Out of Bounds Read/Write

Vulnerability Research | March 23, 2026
CVSS 4.0 Score 8.5 (High)
CWE Identification CWE-190
CVSS Vector String CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
CVE CVE-2026-27784
Affected Component nginx — ngx_http_mp4_module

Summary

A critical integer overflow vulnerability was discovered in the ngx_http_mp4_module, specifically affecting nginx deployments on 32-bit architectures. The flaw is triggered when the module parses specially crafted MP4 files containing large entry counts in atom tables. Due to improper integer promotion during a multiplication operation, a security bounds check is silently bypassed. This allows the worker process to treat out-of-bounds heap memory as valid atom data, leading to memory corruption, sensitive information disclosure or a process crash.

Impact

  1. Heap Memory Disclosure: An attacker can write to/read adjacent memory chunks, causing unauthorized access of process memory.
  2. Worker Termination: If the read reaches unmapped memory segments, a segmentation fault will kill the nginx worker process, causing a persistent Denial of Service.

Attack Prerequisites

This vulnerability requires nginx to be compiled with --with-http_mp4_module (not built by default). The attacker must be able to cause nginx to serve a crafted MP4 file with a ?start= query parameter (pseudo-streaming seek). This means the MP4 must either be uploadable by the attacker or already accessible on the server.

Affected platform: 32-bit architectures only (x86, ARM32) — where sizeof(size_t) == 4. 64-bit builds are not affected.

Description

The vulnerability resides in ngx_http_mp4_module.c during the processing of atoms like stts (Time-to-Sample) and stss (Sync Sample). The code reads a 32-bit entry count from the MP4 header and calculates the expected table size by multiplying it by the size of the entry structure.

// The Vulnerable Precedence Trap
entries = ngx_mp4_get_32value(atom->entries);
if (header_size + entries * sizeof(entry_type) > atom_data_size) {
    return NGX_ERROR;
}

On 32-bit systems, sizeof(size_t) is 4. When entries is 0x40000001, the multiplication 0x40000001 * 4 equals 0x100000004. In a 32-bit register, the 33rd bit is lost, leaving only 0x00000004. This value is then promoted to 64-bit for the addition, but the overflow has already occurred.

Integer Overflow: 32-bit Arithmetic Walkthrough

entries × sizeof(uint32_t) = product (size_t) 0x40000001 × 4 = 0x100000004 33rd bit LOST on 32-bit 0x00000004 ← wraps to 4 bounds check: header_size(8) + 4 > atom_data_size(24)? 12 > 24? NO → Check BYPASSED. Code continues with original large entries value.

Once the check is bypassed, the original large entries value is used to calculate data->last and to advance data->pos. Since data->pos moves far past the actual buffer end, the next read operation (e.g., sample time update) pulls data from whatever memory resides immediately after the MP4 atom buffer on the heap.

Heap Layout: Out-of-Bounds Read

MP4 atom buffer [actual data, 24 bytes] data->pos (start) adjacent heap memory [other allocations / secrets] data->pos advances by entries*sizeof → OOB unmapped → SIGSEGV

Affected functions (7 total):

  • ngx_http_mp4_read_stts_atom — entry size: 8 bytes, overflow threshold: 0x20000001
  • ngx_http_mp4_read_stss_atom — entry size: 4 bytes, overflow threshold: 0x40000001
  • ngx_http_mp4_read_ctts_atom — entry size: 8 bytes, overflow threshold: 0x20000001
  • ngx_http_mp4_read_stsc_atom — entry size: 12 bytes, overflow threshold: 0x15555556
  • ngx_http_mp4_read_stsz_atom — entry size: 4 bytes, overflow threshold: 0x40000001
  • ngx_http_mp4_read_stco_atom — entry size: 4 bytes, overflow threshold: 0x40000001
  • ngx_http_mp4_read_co64_atom — entry size: 8 bytes, overflow threshold: 0x20000001

Conclusion

This vulnerability underscores the danger of C's implicit type promotion rules. To remediate this issue, administrators should upgrade to nginx 1.29.7 or later, where all arithmetic operands in the mp4 module are explicitly cast to uint64_t. If upgrading is not immediately possible, disabling the mp4 directive on 32-bit systems is the only reliable mitigation.

References

Special thanks to the F5 SIRT team for their exceptionally prompt response and effective coordination throughout the disclosure process.