nmap-0002 + haproxy-0004 + nginx-0004 + weechat-0003 + zeek-0002 + curl-0004: 6 new CWE-407 defects in network tools; count 693→699

nmap-0002:     nmap.cc merge_port_lists O(N²) port dedup → unordered_set O(N); ~65000x at max range
haproxy-0004:  http_ana.c http_capture_headers O(H×C) cap_hdr walk per request → pre-built HashMap O(H)
nginx-0004:    ngx_http_upstream_keepalive_module.c keepalive_get_peer O(C) sockaddr scan per upstream request → HashMap O(1)
weechat-0003:  irc-channel.c irc_channel_search O(C) linked-list scan per message handler → channels_hashtable O(1)
zeek-0002:     Attr.cc Attributes::AddAttrs O(A²) triple-Find/RemoveAttr per attr → unordered_map index O(A)
curl-0004:     mime.c search_header O(P×H) 3x per part per mime_add_headers → pre-indexed header name set O(P)
This commit is contained in:
russell@unturf.com 2026-03-29 22:22:11 -04:00
parent 421f3352c7
commit ba818693db
21 changed files with 2213 additions and 0 deletions

View file

@ -0,0 +1,126 @@
package unit;
import java.util.*;
/**
* haproxy-0004 CWE-407: http_capture_headers O(H×C) per request
*
* Models http_ana.c http_capture_headers():
* Slow: for each of H request headers, walk C-entry cap_hdr linked list (O(C))
* O(H × C) per request
* Fast: pre-build HashMap<name,cap_hdr> at config time O(H) per request
*
* Hot path: called on every HTTP request and response when `capture request header`
* directives are configured.
*/
public class HaproxyCaptureHeadersAlgorithmTest {
// Simulates a cap_hdr linked-list entry (from include/haproxy/capture-t.h)
static class CapHdr {
final String name;
final int index;
CapHdr next;
CapHdr(String name, int index) { this.name = name; this.index = index; }
}
// Simulates an HTTP header (name + value)
static class HttpHeader {
final String name;
final String value;
HttpHeader(String name, String value) { this.name = name; this.value = value; }
}
// --- SLOW: O(H × C) per request (defect) ---
// Models: for each htx header for each cap_hdr strncasecmp
static long captureHeadersSlow(List<HttpHeader> headers, CapHdr capHdrHead) {
long ops = 0;
String[] cap = new String[64];
for (HttpHeader hdr : headers) {
for (CapHdr h = capHdrHead; h != null; h = h.next) {
ops++; // strncasecmp call
if (h.name.equalsIgnoreCase(hdr.name)) {
if (cap[h.index] == null)
cap[h.index] = hdr.value;
}
}
}
return ops;
}
// --- FAST: O(H) per request (fix) ---
// Models: pre-built HashMap<lowercaseName, cap_hdr> at config time
static long captureHeadersFast(List<HttpHeader> headers,
Map<String, CapHdr> capHdrMap) {
long ops = 0;
String[] cap = new String[64];
for (HttpHeader hdr : headers) {
ops++; // O(1) hash lookup
CapHdr h = capHdrMap.get(hdr.name.toLowerCase());
if (h != null && cap[h.index] == null)
cap[h.index] = hdr.value;
}
return ops;
}
// Build cap_hdr linked list
static CapHdr buildCapHdrList(int count) {
CapHdr head = null;
for (int i = count - 1; i >= 0; i--) {
CapHdr h = new CapHdr("X-Custom-Header-" + i, i);
h.next = head;
head = h;
}
return head;
}
// Build pre-indexed cap_hdr map
static Map<String, CapHdr> buildCapHdrMap(CapHdr head) {
Map<String, CapHdr> map = new HashMap<>();
for (CapHdr h = head; h != null; h = h.next)
map.put(h.name.toLowerCase(), h);
return map;
}
// Build HTTP request headers list
static List<HttpHeader> buildHeaders(int count, int captureHits) {
List<HttpHeader> headers = new ArrayList<>();
for (int i = 0; i < count; i++) {
String name;
if (i < captureHits)
name = "X-Custom-Header-" + i; // will match cap_hdr
else
name = "Standard-Header-" + i; // won't match cap_hdr
headers.add(new HttpHeader(name, "value-" + i));
}
return headers;
}
public static void main(String[] args) {
System.out.println("haproxy-0004 CWE-407: http_capture_headers O(H*C) vs O(H)");
System.out.println("==========================================================");
// Parameters: H request headers, C capture headers configured
int[][] params = { {30, 10}, {50, 20}, {100, 50} };
for (int[] p : params) {
int H = p[0], C = p[1];
CapHdr capHdrHead = buildCapHdrList(C);
Map<String, CapHdr> capHdrMap = buildCapHdrMap(capHdrHead);
List<HttpHeader> headers = buildHeaders(H, C / 2);
long slowOps = captureHeadersSlow(headers, capHdrHead);
long fastOps = captureHeadersFast(headers, capHdrMap);
double ratio = (double) slowOps / fastOps;
System.out.printf(" H=%3d headers, C=%2d captures: slow=%,5d ops fast=%,3d ops speedup=%.0fx%n",
H, C, slowOps, fastOps, ratio);
assert ratio >= (double) C / 2 :
"Expected speedup >= " + (C/2) + "x but got " + ratio;
}
System.out.println("\nPASS");
}
}