Project

General

Profile

Security #8642

Updated by Jason Ish 14 days ago

h2. Summary 

 Suricata's HTTP SWF decompression path can trigger a heap buffer overflow when 
 @swf-decompression.decompress-depth@ is configured to a @uint32_t@ value that 
 wraps after the internal SWF header adjustment. An ASAN-enabled build aborts in 
 @FileSwfDecompression()@ with a 4 GiB zero-fill write. 

 h2. Affected code 

 Confirmed on Suricata @9.0.0-dev@, commit @0eda09f302@ from 2026-06-03, built 
 with ASAN. 

 Relevant files: 

 * @src/util-file-decompression.c@ 
 * @src/detect-file-data.c@ 

 The vulnerable path is reached from HTTP to-client @file_data@ inspection when 
 SWF decompression is enabled: 

 * @FiledataGetDataCallback()@ calls @FileSwfDecompression()@ for HTTP1 
   to-client file data if @htp_state->cfg->swf_decompression_enabled@ is true 
   and the file data starts with a compressed SWF signature. 
 * @FileSwfDecompression()@ computes @decompressed_data_len@ from the configured 
   @decompress_depth@, then unconditionally adds 8 bytes for the generated FWS 
   header. 

 h2. Root cause 

 In @FileSwfDecompression()@: 

 <pre> 
 uint32_t decompressed_data_len = 
     (decompress_depth == 0) ? decompressed_swf_len : decompress_depth; 
 decompressed_data_len += 8; 

 SCInspectionBufferCheckAndExpand(out_buffer, decompressed_data_len); 
 ... 
 out_buffer->len = decompressed_data_len; 
 ... 
 memset(out_buffer->buf + 8, 0, decompressed_data_len - 8); 
 </pre> 

 With @decompress-depth=4294967295@, @decompressed_data_len += 8@ wraps to @7@. 
 The inspection buffer is only expanded to the default 4096-byte allocation, but 
 the later @memset(out_buffer->buf + 8, 0, decompressed_data_len - 8)@ underflows 
 the length argument to @4294967295@ and writes zeros past the heap allocation. 

 h2. Reproducer 

 The full reproducer will be provided in a suricata-verify test submitted 
 separately. That test includes a pcap with a single HTTP transaction returning a 
 small zlib-compressed @CWS@ SWF file, plus a @file_data@ rule that reaches the 
 HTTP file-data inspection path. 

 After the suricata-verify test is submitted, run from a Suricata ASAN build 
 using the pcap from that test: 

 <pre> 
 ASAN_OPTIONS=abort_on_error=1:detect_leaks=0 \ 
 src/suricata \ 
   -c suricata.yaml \ 
   -S <suricata-verify-test>/test.rules \ 
   -r <suricata-verify-test>/input.pcap \ 
   -l /tmp/suri-swf-depth-wrap \ 
   --runmode single \ 
   -k none \ 
   --set app-layer.protocols.http.libhtp.default-config.swf-decompression.enabled=yes \ 
   --set app-layer.protocols.http.libhtp.default-config.swf-decompression.decompress-depth=4294967295 
 </pre> 

 h2. Observed result 

 Suricata aborts with ASAN: 

 <pre> 
 ERROR: AddressSanitizer: heap-buffer-overflow 
 WRITE of size 4294967295 
     #1 FileSwfDecompression src/util-file-decompression.c:149 
     #2 FiledataGetDataCallback src/detect-file-data.c:456 

 0 bytes after 4096-byte region allocated by: 
     #2 SCInspectionBufferCheckAndExpand src/detect-engine-inspect-buffer.c:227 
     #3 FileSwfDecompression src/util-file-decompression.c:132 
 </pre> 

 h2. Expected result 

 Suricata should not perform an out-of-bounds write or abort when processing the 
 traffic under this configuration. 

 h2. Impact 

 This is config-dependent. A packet alone is not sufficient; the vulnerable path 
 requires: 

 * HTTP SWF decompression enabled. 
 * A rule or other detection path that inspects HTTP to-client @file_data@. 
 * A wrapping @swf-decompression.decompress-depth@ value. 

 The demonstrated impact is denial of service / memory safety violation. No 
 credible RCE path was identified from this primitive: the overwrite is a huge 
 zero-fill, the byte value is fixed, and the size is controlled by configuration 
 rather than packet contents. 

 h2. Validation 

 * With @decompress-depth=4294967295@, the ASAN build aborts with exit 134. 
 * With normal SWF decompression depth, the same pcap and rule complete cleanly 
   and emit one @file_data@ alert, confirming reachability of the SWF 
   decompression path. 
 * A suricata-verify regression test has been prepared locally at 
   @/home/jason/oisf/dev/verify/master/tests/security-swf-decompression-depth-wrap@ 
   and will be submitted separately. 

 Found by GPT 5.5 using Codex. 

Back