{"record":{"id":"0da2e463e0a203e5","repo":"kgretzky/evilginx2","slug":"credentials-missing-username-search-field","errorCode":null,"errorMessage":"credentials: missing username `search` field","messagePattern":"credentials: missing username `search` field","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/phishlet.go","lineNumber":595,"sourceCode":"\t\t\terr := p.addHttpAuthToken(p.paramVal(*at.Domain), p.paramVal(*at.Path), p.paramVal(*at.Name), p.paramVal(*at.Header))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\tfor _, au := range fp.AuthUrls {\n\t\tre, err := regexp.Compile(p.paramVal(au))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tp.authUrls = append(p.authUrls, re)\n\t}\n\n\tif fp.Credentials.Username.Key == nil {\n\t\treturn fmt.Errorf(\"credentials: missing username `key` field\")\n\t}\n\tif fp.Credentials.Username.Search == nil {\n\t\treturn fmt.Errorf(\"credentials: missing username `search` field\")\n\t}\n\tif fp.Credentials.Password.Key == nil {\n\t\treturn fmt.Errorf(\"credentials: missing password `key` field\")\n\t}\n\tif fp.Credentials.Password.Search == nil {\n\t\treturn fmt.Errorf(\"credentials: missing password `search` field\")\n\t}\n\n\tp.username.key, err = regexp.Compile(p.paramVal(*fp.Credentials.Username.Key))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"credentials: %v\", err)\n\t}\n\n\tp.username.search, err = regexp.Compile(p.paramVal(*fp.Credentials.Username.Search))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"credentials: %v\", err)\n\t}\n","sourceCodeStart":577,"sourceCodeEnd":613,"githubUrl":"https://github.com/kgretzky/evilginx2/blob/4c0988a1d9db4d172a185e979a38bfd0efdb5830/core/phishlet.go#L577-L613","documentation":"Thrown when the phishlet's credentials.username block is missing the 'search' field. 'search' is the regex used to extract the submitted username value from the login POST body; without it credentials cannot be captured, so the phishlet is rejected.","triggerScenarios":"A phishlet YAML defines credentials.username.key but omits 'search', or 'search' is misplaced by indentation.","commonSituations":"Adding key but forgetting search when writing a new phishlet; copy-paste dropping the search line; renamed field mismatch after editing.","solutions":["Add a 'search:' regex under credentials.username that captures the username value","Keep 'key' and 'search' as siblings under credentials.username","Re-run phishlet validation after editing"],"exampleFix":"// before\ncredentials:\n  username:\n    key: 'username'\n// after\ncredentials:\n  username:\n    key: 'username'\n    search: 'username=([^&]*)'","handlingStrategy":"validation","validationCode":"if cfg.Credentials.Username.Search == nil || *cfg.Credentials.Username.Search == \"\" {\n  return errors.New(\"credentials: missing username search\")\n}","typeGuard":"func hasUsernameSearch(fp FakePost) bool { return fp.Credentials.Username.Search != nil && *fp.Credentials.Username.Search != \"\" }","tryCatchPattern":null,"preventionTips":["Pair every key with a matching search capture regex","Test that the search regex matches the real login POST body","Validate the phishlet after edits"],"tags":["phishlet","config","credentials","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"}