{"record":{"id":"135a271c9efd4f54","repo":"stamparm/maltrail","slug":"forwarded-for-regex","errorCode":null,"errorMessage":"forwarded-for regex","messagePattern":"forwarded-for regex","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sensor/src/settings.rs","lineNumber":320,"sourceCode":"            suspicious_http_request,\n            suspicious_http_path,\n            code_execution,\n            param_value: pyre::compile(r\"(\\w+=)[^&=]+\"),\n            proxy_probe_path: pyre::compile(r\"(http://[^/]+/)(.+)\"),\n            proxy_probe_host: pyre::compile(r\"(http://)([^/(]+)\"),\n            // `unicode(false)` is what makes the Aho-Corasick pre-condition below EXACT rather\n            // than merely usually right. `the retired Python sensor, sensor.py:804` compiles this as a BYTES pattern\n            // with `re.I`, and in Python that folds ASCII only; the crate's default folds\n            // Unicode, so `(?i)k` here also matched U+212A KELVIN SIGN and `\\b`/`\\s` were\n            // Unicode classes. That accepted a header Python's `re` would not, and it would have\n            // slipped past an ASCII pre-filter. ASCII on both sides now agrees with the oracle.\n            forwarded_for: regex::bytes::RegexBuilder::new(\n                r\"\\b(CF-Connecting-IP|True-Client-IP|X-Forwarded-For):\\s*([0-9.]+)\",\n            )\n            .case_insensitive(true)\n            .unicode(false)\n            .build()\n            .expect(\"forwarded-for regex\"),\n            forwarded_for_pre_condition: ac_nocase(&[\"CF-Connecting-IP:\", \"True-Client-IP:\", \"X-Forwarded-For:\"]),\n\n            pre_condition: ac(SUSPICIOUS_HTTP_REQUEST_PRE_CONDITION),\n            proxy_probe_pre_condition: ac(SUSPICIOUS_PROXY_PROBE_PRE_CONDITION),\n            whitelist_request_paths: ac(WHITELIST_HTTP_REQUEST_PATHS),\n            whitelist_direct_download: ac(WHITELIST_DIRECT_DOWNLOAD_KEYWORDS),\n            whitelist_long_domain: ac(WHITELIST_LONG_DOMAIN_NAME_KEYWORDS),\n            local_subdomain_lookups: ac(LOCAL_SUBDOMAIN_LOOKUPS),\n            condense_on_info: ac(CONDENSE_ON_INFO_KEYWORDS),\n\n            ignore_dns_query_suffixes: IGNORE_DNS_QUERY_SUFFIXES.iter().copied().collect(),\n            suspicious_content_types: SUSPICIOUS_CONTENT_TYPES.iter().copied().collect(),\n            suspicious_download_extensions: SUSPICIOUS_DIRECT_DOWNLOAD_EXTENSIONS.iter().copied().collect(),\n        }\n    }\n}\n\n/// `IPPROTO_LUT` lookup (protocol number -> Maltrail label).","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/stamparm/maltrail/blob/77cfb06d7606506d101bbcec0786c77166c4255e/sensor/src/settings.rs#L302-L338","documentation":"Statics::build compiles the forwarded-for header regex (CF-Connecting-IP|True-Client-IP|X-Forwarded-For) with regex::bytes::RegexBuilder and panics with \"forwarded-for regex\" if build() returns Err. Since the pattern is a hard-coded literal, failure indicates a regex-crate construction problem (e.g. a compile-size limit or unsupported configuration combination), not bad user input.","triggerScenarios":"Statics::build() runs and regex::bytes::RegexBuilder::new(r\"\\b(CF-Connecting-IP|True-Client-IP|X-Forwarded-For):\\s*([0-9.]+)\").case_insensitive(true).unicode(false).build() returns Err — typically size_limit exceeded or a crate-level issue.","commonSituations":"Running in a build where the regex size_limit was lowered globally; a regex crate regression when upgrading; unusual feature-flag combinations disabling syntax used by the pattern.","solutions":["Include the underlying regex::Error in the panic message to identify the real cause","Raise RegexBuilder size_limit if the error is a compiled-size overflow","Check the regex crate version/feature flags for changes affecting bytes::Regex with unicode(false)","If the pattern were ever dynamic, validate it with RegexBuilder::new(..).build() at config-load time"],"exampleFix":"// before\n.build()\n.expect(\"forwarded-for regex\"),\n// after\n.build()\n.unwrap_or_else(|e| panic!(\"forwarded-for regex failed to compile: {e}\")),","handlingStrategy":"try-catch","validationCode":"regex::bytes::RegexBuilder::new(r\"\\b(CF-Connecting-IP|True-Client-IP|X-Forwarded-For):\\s*([0-9.]+)\").case_insensitive(true).unicode(false).build().map(|_| ()).map_err(|e| format!(\"forwarded-for regex: {e}\"))?;","typeGuard":null,"tryCatchPattern":"let re = builder.build().unwrap_or_else(|e| panic!(\"forwarded-for regex: {e}\"));","preventionTips":["Keep regex crate versions pinned and tested at startup","Test Statics::build() in CI so compile failures surface at build time","Include the regex::Error in panics"],"tags":["rust","regex","panic","initialization"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"77cfb06d7606506d101bbcec0786c77166c4255e","analyzedAt":"2026-09-13T03:50:16.010Z","contentChangedAt":"2026-09-13T03:50:16.010Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}