{"record":{"id":"1aaf13fd955e7a14","repo":"kgretzky/evilginx2","slug":"sub-filters-missing-mimes-field","errorCode":null,"errorMessage":"sub_filters: missing `mimes` field","messagePattern":"sub_filters: missing `mimes` field","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/phishlet.go","lineNumber":448,"sourceCode":"\t\t}\n\t}\n\tif !landing_set {\n\t\tp.proxyHosts[0].is_landing = true\n\t}\n\n\tif fp.SubFilters != nil {\n\t\tfor _, sf := range *fp.SubFilters {\n\t\t\tif sf.Hostname == nil {\n\t\t\t\treturn fmt.Errorf(\"sub_filters: missing `triggers_on` field\")\n\t\t\t}\n\t\t\tif sf.Sub == nil {\n\t\t\t\treturn fmt.Errorf(\"sub_filters: missing `orig_sub` field\")\n\t\t\t}\n\t\t\tif sf.Domain == nil {\n\t\t\t\treturn fmt.Errorf(\"sub_filters: missing `domain` field\")\n\t\t\t}\n\t\t\tif sf.Mimes == nil {\n\t\t\t\treturn fmt.Errorf(\"sub_filters: missing `mimes` field\")\n\t\t\t}\n\t\t\tif sf.Search == nil {\n\t\t\t\treturn fmt.Errorf(\"sub_filters: missing `search` field\")\n\t\t\t}\n\t\t\tif sf.Replace == nil {\n\t\t\t\treturn fmt.Errorf(\"sub_filters: missing `replace` field\")\n\t\t\t}\n\t\t\tif sf.WithParams == nil {\n\t\t\t\tsf.WithParams = &[]string{}\n\t\t\t}\n\n\t\t\tfor n := range *sf.Mimes {\n\t\t\t\t(*sf.Mimes)[n] = p.paramVal((*sf.Mimes)[n])\n\t\t\t}\n\t\t\tp.addSubFilter(p.paramVal(*sf.Hostname), p.paramVal(*sf.Sub), p.paramVal(*sf.Domain), *sf.Mimes, p.paramVal(*sf.Search), p.paramVal(*sf.Replace), sf.RedirectOnly, *sf.WithParams)\n\t\t}\n\t}\n\tif fp.JsInject != nil {","sourceCodeStart":430,"sourceCodeEnd":466,"githubUrl":"https://github.com/kgretzky/evilginx2/blob/4c0988a1d9db4d172a185e979a38bfd0efdb5830/core/phishlet.go#L430-L466","documentation":"Every `sub_filters` entry must list `mimes`, the response MIME types the substitution applies to. The entry's `mimes` field was nil, so validation fails. Later code dereferences `*sf.Mimes` in a range loop, so a missing list would also cause a nil dereference.","triggerScenarios":"A `sub_filters:` entry lacks the `mimes:` key; core/phishlet.go's `if sf.Mimes == nil` check rejects the phishlet before the `for n := range *sf.Mimes` loop runs.","commonSituations":"Omitting mimes when writing a quick filter (many filters only need text/html); misspelling as `mime:`; a filter copied from js_inject style where the field names differ.","solutions":["Add `mimes: ['text/html']` (or the relevant list, e.g. text/html, application/javascript) to the entry","Ensure the value is a YAML list with correct indentation, since the code ranges over the slice","Reload the phishlet and address any next missing field reported"],"exampleFix":"// before\nsub_filters:\n  - triggers_on: 'auth.example.com'\n    orig_sub: 'accounts'\n    domain: 'example.com'\n    search: 'accounts\\\\.example\\\\.com'\n    replace: 'accounts.{domain}'\n// after\nsub_filters:\n  - triggers_on: 'auth.example.com'\n    orig_sub: 'accounts'\n    domain: 'example.com'\n    mimes: ['text/html']\n    search: 'accounts\\\\.example\\\\.com'\n    replace: 'accounts.{domain}'","handlingStrategy":"validation","validationCode":"for i, sf in enumerate(cfg.get('sub_filters') or []):\n    mimes = sf.get('mimes')\n    if not isinstance(mimes, list) or len(mimes) == 0:\n        raise ValueError(f\"sub_filters[{i}]: missing `mimes` field\")","typeGuard":"func validSubFilter(sf SubFilter) bool { return sf.Mimes != nil }","tryCatchPattern":null,"preventionTips":["Default to `mimes: ['text/html']` when unsure","Key must be plural `mimes` as a YAML list","Remember the code ranges over the list — nil here would crash, so the loader blocks it early"],"tags":["phishlet","config-validation","sub-filters","missing-field"],"backgroundTag":"missing-required-config-field","analyzedSha":"4c0988a1d9db4d172a185e979a38bfd0efdb5830","analyzedAt":"2026-09-05T19:23:07.238Z","contentChangedAt":"2026-09-05T19:23:07.238Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}