stamparm/maltrail · critical

SUSPICIOUS_HTTP_REQUEST_REGEXES must carry a 'code…

Error message

SUSPICIOUS_HTTP_REQUEST_REGEXES must carry a 'code execution' entry

What it means

Statics::build requires one entry of SUSPICIOUS_HTTP_REQUEST_REGEXES whose description contains "code execution", because that entry is compiled separately into the code_execution regex used by detection logic. If the constant table lacks such a description, .expect panics with this message. This is a data-shape invariant on the shipped regex table, not a runtime condition.

Solutions

  1. Restore or re-add an entry in SUSPICIOUS_HTTP_REQUEST_REGEXES whose description contains "code execution"
  2. Replace the fragile substring .find with a keyed lookup (e.g. match on an enum or exact tag field)
  3. Add a unit test asserting the code-execution entry exists so edits fail in CI, not at startup

Example fix

// before
let code_execution = SUSPICIOUS_HTTP_REQUEST_REGEXES.iter()
    .find(|(desc, _)| desc.contains("code execution"))
    .map(|(_, src)| pyre::compile(&format!("(?is){src}")))
    .expect("SUSPICIOUS_HTTP_REQUEST_REGEXES must carry a 'code execution' entry");
// after
let code_execution = SUSPICIOUS_HTTP_REQUEST_REGEXES.iter()
    .find(|(desc, _)| desc.contains("code execution"))
    .map(|(_, src)| pyre::compile(&format!("(?is){src}")))
    .unwrap_or_else(|| panic!("code execution regex missing; have: {:?}", SUSPICIOUS_HTTP_REQUEST_REGEXES.iter().map(|(d, _)| *d).collect::<Vec<_>>()));
Defensive patterns

Strategy: validation

Validate before calling

assert!(SUSPICIOUS_HTTP_REQUEST_REGEXES.iter().any(|(d, _)| d.contains("code execution")), "code execution regex entry missing");

Type guard

fn has_code_execution_entry(table: &[(&str, &str)]) -> bool { table.iter().any(|(d, _)| d.contains("code execution")) }

Try / catch

let code_execution = find_code_execution().expect("SUSPICIOUS_HTTP_REQUEST_REGEXES must carry a 'code execution' entry");

Prevention

When it happens

Trigger: Running settings::init()/Statics::build() after SUSPICIOUS_HTTP_REQUEST_REGEXES was edited so that no (desc, src) pair has a description containing the substring "code execution", making .find(|(desc, _)| desc.contains("code execution")) return None.

Common situations: Renaming or rewording a regex description in the constant table; removing the code-execution entry during a cleanup; refactoring the table into a config file where the description no longer matches exactly.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of stamparm/maltrail@77cfb06d76 (2026-09-13). Data as JSON: /api/errors/4aa12fa000d5f370. Report an issue: GitHub.

Appendix: source

Thrown at sensor/src/settings.rs:272

        let ua_src = build_suspicious_ua_regex(&root);
        let suspicious_ua = match pyre::build(&ua_src) {
            Ok(re) => Some(re),
            Err(e) => {
                crate::ceprintln!("[!] unable to compile SUSPICIOUS_UA_REGEX ({e}); user-agent heuristic disabled");
                None
            }
        };

        let mut suspicious_http_request = Vec::with_capacity(SUSPICIOUS_HTTP_REQUEST_REGEXES.len());
        for (desc, src) in SUSPICIOUS_HTTP_REQUEST_REGEXES {
            // Python: re.search(regex, value, re.I | re.DOTALL)
            suspicious_http_request.push((*desc, pyre::compile(&format!("(?is){src}"))));
        }
        let code_execution = SUSPICIOUS_HTTP_REQUEST_REGEXES
            .iter()
            .find(|(desc, _)| desc.contains("code execution"))
            .map(|(_, src)| pyre::compile(&format!("(?is){src}")))
            .expect("SUSPICIOUS_HTTP_REQUEST_REGEXES must carry a 'code execution' entry");

        let mut suspicious_http_path = Vec::with_capacity(SUSPICIOUS_HTTP_PATH_REGEXES.len());
        for (desc, src) in SUSPICIOUS_HTTP_PATH_REGEXES {
            suspicious_http_path.push((*desc, pyre::compile(&format!("(?i){src}"))));
        }

        Statics {
            f_crlf: memchr::memmem::Finder::new("\r\n").into_owned(),
            f_crlf2: memchr::memmem::Finder::new("\r\n\r\n").into_owned(),
            f_sp_http: memchr::memmem::Finder::new(" HTTP/").into_owned(),
            f_http_slash: memchr::memmem::Finder::new("HTTP/").into_owned(),
            f_host: memchr::memmem::Finder::new("\r\nHost:").into_owned(),
            f_user_agent: memchr::memmem::Finder::new("\r\nUser-Agent:").into_owned(),
            f_content_type: memchr::memmem::Finder::new("\r\nContent-Type:").into_owned(),
            f_intranet: memchr::memmem::Finder::new(".intranet.").into_owned(),

            root,
            valid_dns_name: pyre::compile(VALID_DNS_NAME_REGEX),

View on GitHub (pinned to 77cfb06d76)