import java.util.*; /** * CWE-407 unit tests for Traefik defects. * * traefik-0001: pkg/ip/checker.go ContainsIP() * authorizedIPs is []*net.IP — linear scan with Equal() per request. * O(T) where T = trusted IP count. Hot path: every HTTP request through * ipallowlist/ipwhitelist/forwardedheaders middleware. * Fix: map[[16]byte]struct{} for O(1) exact-IP lookup. * * traefik-0002: pkg/middlewares/headers/header.go isOriginAllowed() * AccessControlAllowOriginList is []string — linear scan per CORS request. * O(O) where O = allowed origin count. Hot path: every CORS response. * Fix: map[string]struct{} built at init time for O(1) lookup. */ public class TraefikTest { // --- traefik-0001 --- static boolean containsIP_slice(List authorizedIPs, String addr) { for (String ip : authorizedIPs) { // O(T) — defect if (ip.equals(addr)) return true; } return false; } static boolean containsIP_map(Set authorizedMap, String addr) { return authorizedMap.contains(addr); // O(1) — fix } static void testTraefik0001() throws Exception { int T = 500; // trusted IPs (Cloudflare + enterprise egress IPs) List ipSlice = new ArrayList<>(T); Set ipMap = new HashSet<>(T); for (int i = 0; i < T; i++) { String ip = "10." + (i / 256) + "." + (i % 256) + ".1"; ipSlice.add(ip); ipMap.add(ip); } // target near end (worst case for linear scan) String target = "10." + ((T - 1) / 256) + "." + ((T - 1) % 256) + ".1"; String unknown = "1.2.3.4"; // correctness assert containsIP_slice(ipSlice, target) == containsIP_map(ipMap, target); assert !containsIP_slice(ipSlice, unknown) && !containsIP_map(ipMap, unknown); // performance: simulate R HTTP requests int R = 200_000; long t0 = System.nanoTime(); for (int r = 0; r < R; r++) containsIP_slice(ipSlice, target); long tSlice = System.nanoTime() - t0; t0 = System.nanoTime(); for (int r = 0; r < R; r++) containsIP_map(ipMap, target); long tMap = System.nanoTime() - t0; double ratio = (double) tSlice / tMap; System.out.printf("traefik-0001: slice=%.3fs map=%.3fs ratio=%.1f×%n", tSlice / 1e9, tMap / 1e9, ratio); assert ratio > 20 : "Expected >20× speedup, got " + ratio; System.out.println("PASS traefik-0001"); } // --- traefik-0002 --- static boolean isOriginAllowed_list(List allowList, String origin) { for (String item : allowList) { // O(O) — defect if (item.equals("*") || item.equals(origin)) return true; } return false; } static boolean isOriginAllowed_map(Set allowSet, String origin) { return allowSet.contains("*") || allowSet.contains(origin); // O(1) — fix } static void testTraefik0002() throws Exception { int O = 200; // allowed origins (multi-tenant SaaS: many partner domains) List allowList = new ArrayList<>(O); Set allowSet = new HashSet<>(O); for (int i = 0; i < O; i++) { String origin = "https://partner-" + i + ".example.com"; allowList.add(origin); allowSet.add(origin); } // target near end (worst case) String target = "https://partner-" + (O - 1) + ".example.com"; String blocked = "https://evil.com"; // correctness assert isOriginAllowed_list(allowList, target) == isOriginAllowed_map(allowSet, target); assert !isOriginAllowed_list(allowList, blocked) && !isOriginAllowed_map(allowSet, blocked); int R = 200_000; long t0 = System.nanoTime(); for (int r = 0; r < R; r++) isOriginAllowed_list(allowList, target); long tList = System.nanoTime() - t0; t0 = System.nanoTime(); for (int r = 0; r < R; r++) isOriginAllowed_map(allowSet, target); long tMap = System.nanoTime() - t0; double ratio = (double) tList / tMap; System.out.printf("traefik-0002: list=%.3fs map=%.3fs ratio=%.1f×%n", tList / 1e9, tMap / 1e9, ratio); assert ratio > 10 : "Expected >10× speedup, got " + ratio; System.out.println("PASS traefik-0002"); } public static void main(String[] args) throws Exception { testTraefik0001(); testTraefik0002(); System.out.println("ALL PASS"); } }