{"record":{"id":"5588d0d14a302c11","repo":"kgretzky/evilginx2","slug":"js-inject-missing-trigger-domains-field","errorCode":null,"errorMessage":"js_inject: missing `trigger_domains` field","messagePattern":"js_inject: missing `trigger_domains` field","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/phishlet.go","lineNumber":469,"sourceCode":"\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 {\n\t\tfor _, js := range *fp.JsInject {\n\t\t\tif js.TriggerDomains == nil {\n\t\t\t\treturn fmt.Errorf(\"js_inject: missing `trigger_domains` field\")\n\t\t\t}\n\t\t\tif js.TriggerPaths == nil {\n\t\t\t\treturn fmt.Errorf(\"js_inject: missing `trigger_paths` field\")\n\t\t\t}\n\t\t\tif js.Script == nil {\n\t\t\t\treturn fmt.Errorf(\"js_inject: missing `script` field\")\n\t\t\t}\n\t\t\tfor n := range *js.TriggerDomains {\n\t\t\t\t(*js.TriggerDomains)[n] = p.paramVal((*js.TriggerDomains)[n])\n\t\t\t}\n\t\t\tfor n := range *js.TriggerPaths {\n\t\t\t\t(*js.TriggerPaths)[n] = p.paramVal((*js.TriggerPaths)[n])\n\t\t\t}\n\t\t\terr := p.addJsInject(*js.TriggerDomains, *js.TriggerPaths, js.TriggerParams, p.paramVal(*js.Script))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}","sourceCodeStart":451,"sourceCodeEnd":487,"githubUrl":"https://github.com/kgretzky/evilginx2/blob/4c0988a1d9db4d172a185e979a38bfd0efdb5830/core/phishlet.go#L451-L487","documentation":"Each entry in the `js_inject` list must define `trigger_domains`, the hosts on which the injected script runs. The parsed entry's `trigger_domains` field was nil, so phishlet validation fails before p.addJsInject would be reached. This ensures every script injection has at least one target host.","triggerScenarios":"A `js_inject:` entry in the phishlet YAML omits `trigger_domains:`; core/phishlet.go's `if js.TriggerDomains == nil` check fires while iterating fp.JsInject.","commonSituations":"Adding a js_inject block with only `script:`; copying a sub_filters-style entry whose field names differ; typo like `trigger_domain:` (singular).","solutions":["Add `trigger_domains: ['<hostname>']` (e.g. `trigger_domains: ['auth.example.com']`) to the js_inject entry","Use the YAML list syntax since the code ranges over the slice later","Reload and continue with the next reported field (trigger_paths, script)"],"exampleFix":"// before\njs_inject:\n  - trigger_paths: ['/login']\n    script: 'alert(1)'\n// after\njs_inject:\n  - trigger_domains: ['auth.example.com']\n    trigger_paths: ['/login']\n    script: 'alert(1)'","handlingStrategy":"validation","validationCode":"for i, js in enumerate(cfg.get('js_inject') or []):\n    td = js.get('trigger_domains')\n    if not isinstance(td, list) or len(td) == 0:\n        raise ValueError(f\"js_inject[{i}]: missing `trigger_domains` field\")","typeGuard":"func validJsInject(js JsInject) bool { return js.TriggerDomains != nil }","tryCatchPattern":null,"preventionTips":["Never write a js_inject entry without trigger_domains — there is no 'all domains' default","Use plural `trigger_domains` (distinct from sub_filters' `triggers_on`)","Validate the whole phishlet before a live session"],"tags":["phishlet","config-validation","js-inject","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-14T00:17:10.932Z"}