You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
OpenJPEG's JPIP server component (opj_server, built with BUILD_JPIP_SERVER=ON) parses the HTTP QUERY_STRING. get_fieldparam() in src/lib/openjpip/query_parser.c copies attacker-controlled field names/values into fixed stack buffers fieldname[10]/fieldval[128] using unbounded strncpy() and an out-of-bounds NUL terminator, causing a network-triggerable stack-buffer-overflow (potential RCE or DoS). Present in 2.5.4 and current master; upstream fix PR #1656 is not merged.
assert((size_t)(eqp-stringptr));
strncpy(fieldname, stringptr, (size_t)(eqp-stringptr)); /* 228: length = up to '=' */fieldname[eqp-stringptr] ='\0';
assert(andp-eqp-1 >= 0);
strncpy(fieldval, eqp+1, (size_t)(andp-eqp-1)); /* 231: length = up to '&' */fieldval[andp-eqp-1] ='\0'; /* 232: OOB NUL */
The copy lengths are fully attacker-controlled via the =/& delimiters. A field value >= 128 bytes (or field name >= 10 bytes) overflows the stack. The only protection is assert(), which is compiled out under NDEBUG (release builds).
==ERROR: AddressSanitizer: stack-buffer-overflow on address ...
WRITE of size 137 at ...
#0 in get_fieldparam query_parser.c:232
#1 in parse_query query_parser.c:100
#2 in parse_querystring openjpip.c:85
#3 in main opj_server.c:100
Production build: Segmentation fault (core dumped) or RCE via return-address overwrite.
Suggested fix
Bound every copy by the destination capacity (per upstream PR openjpip: bound query parser field copies #1656: add copy_query_field(), reject when src_size >= dst_size, use length-checked memcpy with explicit NUL termination);
Reject input where '&' precedes '=' (guard the negative andp - eqp - 1 case);
Do not rely on assert() as a security control in release builds (NDEBUG strips it).
Summary
OpenJPEG's JPIP server component (
opj_server, built withBUILD_JPIP_SERVER=ON) parses the HTTPQUERY_STRING.get_fieldparam()insrc/lib/openjpip/query_parser.ccopies attacker-controlled field names/values into fixed stack buffersfieldname[10]/fieldval[128]using unboundedstrncpy()and an out-of-bounds NUL terminator, causing a network-triggerable stack-buffer-overflow (potential RCE or DoS). Present in 2.5.4 and current master; upstream fix PR #1656 is not merged.Affected: OpenJPEG 2.5.4 / master (2026-07-07). Status: candidate — static call chain verified.
Vulnerable code
Entry (
src/bin/jpip/opj_server.c:93-100):Fixed stack buffers (
src/lib/openjpip/query_parser.c:83-92):OOB write sink (
src/lib/openjpip/query_parser.c:228-233):The copy lengths are fully attacker-controlled via the
=/&delimiters. A field value>= 128bytes (or field name>= 10bytes) overflows the stack. The only protection isassert(), which is compiled out underNDEBUG(release builds).Discovery chain (call-stack level)
Reproduction
Run
opj_serverin FastCGI SERVER mode (BUILD_JPIP_SERVER=ON+FCGI), default port 60000.Option A: Python (full script)
Option B: Bash + nc
Expected (ASan):
Production build:
Segmentation fault (core dumped)or RCE via return-address overwrite.Suggested fix
copy_query_field(), reject whensrc_size >= dst_size, use length-checkedmemcpywith explicit NUL termination);'&'precedes'='(guard the negativeandp - eqp - 1case);assert()as a security control in release builds (NDEBUGstrips it).