{"record":{"id":"8395c596f690f9f7","repo":"kgretzky/evilginx2","slug":"proxy-hosts-missing-phish-sub-field","errorCode":null,"errorMessage":"proxy_hosts: missing `phish_sub` field","messagePattern":"proxy_hosts: missing `phish_sub` field","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/phishlet.go","lineNumber":398,"sourceCode":"\tif fp.AuthTokens == nil {\n\t\treturn fmt.Errorf(\"missing `auth_tokens` section\")\n\t}\n\tif fp.Credentials == nil {\n\t\treturn fmt.Errorf(\"missing `credentials` section\")\n\t}\n\tif fp.Credentials.Username == nil {\n\t\treturn fmt.Errorf(\"credentials: missing `username` section\")\n\t}\n\tif fp.Credentials.Password == nil {\n\t\treturn fmt.Errorf(\"credentials: missing `password` section\")\n\t}\n\tif fp.LoginItem == nil {\n\t\treturn fmt.Errorf(\"missing `login` section\")\n\t}\n\n\tfor _, ph := range *fp.ProxyHosts {\n\t\tif ph.PhishSub == nil {\n\t\t\treturn fmt.Errorf(\"proxy_hosts: missing `phish_sub` field\")\n\t\t}\n\t\tif ph.OrigSub == nil {\n\t\t\treturn fmt.Errorf(\"proxy_hosts: missing `orig_sub` field\")\n\t\t}\n\t\tif ph.Domain == nil {\n\t\t\treturn fmt.Errorf(\"proxy_hosts: missing `domain` field\")\n\t\t}\n\t\tauto_filter := true\n\t\tif ph.AutoFilter != nil {\n\t\t\tauto_filter = *ph.AutoFilter\n\t\t}\n\t\tp.addProxyHost(p.paramVal(*ph.PhishSub), p.paramVal(*ph.OrigSub), p.paramVal(*ph.Domain), ph.Session, ph.IsLanding, auto_filter)\n\t}\n\tif len(p.proxyHosts) == 0 {\n\t\treturn fmt.Errorf(\"proxy_hosts: list cannot be empty\")\n\t}\n\tsession_set := false\n\tfor _, ph := range p.proxyHosts {","sourceCodeStart":380,"sourceCodeEnd":416,"githubUrl":"https://github.com/kgretzky/evilginx2/blob/4c0988a1d9db4d172a185e979a38bfd0efdb5830/core/phishlet.go#L380-L416","documentation":"Thrown while iterating over the `proxy_hosts` list during validation when an entry is missing the `phish_sub` field. `phish_sub` defines the subdomain shown to the victim on the attacker's phishing domain (e.g. `login` in login.example.phishing). Every proxy_host entry must contain it so the proxy can route requests.","triggerScenarios":"A `proxy_hosts:` entry in the phishlet YAML defines `orig_sub` and/or `domain` but omits `phish_sub`, or the key is misspelled/mis-indented so the struct field stays nil.","commonSituations":"Hand-editing entries and deleting a line; typos like `phish-sub` or `phishsub`; copying an entry where phish_sub was removed intentionally but the entry left in place.","solutions":["Add `phish_sub:` to every entry under `proxy_hosts:`","Set it to the subdomain of the original host that entry proxies (e.g. `login`, `www`, `mail`)","Use `''` if the host has no subdomain (empty value still counts as present)"],"exampleFix":"// before\nproxy_hosts:\n  - orig_sub: login\n    domain: example.com\n// after\nproxy_hosts:\n  - phish_sub: login\n    orig_sub: login\n    domain: example.com","handlingStrategy":"validation","validationCode":"type proxyHost struct {\n\tPhishSub *string `yaml:\"phish_sub\"`\n\tOrigSub  *string `yaml:\"orig_sub\"`\n\tDomain   *string `yaml:\"domain\"`\n}\nvar fp struct { ProxyHosts *[]proxyHost `yaml:\"proxy_hosts\"` }\nyaml.Unmarshal(data, &fp)\nfor i, ph := range *fp.ProxyHosts {\n\tif ph.PhishSub == nil {\n\t\treturn fmt.Errorf(\"proxy_hosts[%d]: missing phish_sub\", i)\n\t}\n}","typeGuard":"func validProxyHosts(phs []ProxyHost) bool {\n\tfor _, ph := range phs {\n\t\tif ph.PhishSub == nil || ph.OrigSub == nil || ph.Domain == nil {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn len(phs) > 0\n}","tryCatchPattern":"err := cfg.AddPhishlet(\"local\", name)\nif err != nil {\n\tif strings.Contains(err.Error(), \"missing `phish_sub` field\") {\n\t\tlog.Fatalf(\"phishlet %s: each proxy_hosts entry needs phish_sub/orig_sub/domain\", name)\n\t}\n\treturn err\n}","preventionTips":["Give every proxy_hosts entry all three keys: phish_sub, orig_sub, domain","Use '' explicitly for entries with no subdomain","Keep keys hyphenated exactly: phish_sub not phish-sub","Lint the YAML before loading"],"tags":["phishlet","proxy-hosts","config-validation"],"backgroundTag":"phishlet-schema-validation","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"}