kgretzky/evilginx2 · error
missing `login` section
Error message
missing `login` section
What it means
Thrown when the phishlet defines credentials but lacks the required top-level `login` section (fp.LoginItem is nil). The `login` section specifies the login URL path and domain on the target site, which Evilginx uses to redirect victims to the real login page and detect successful authentication.
Solutions
- Add a top-level `login:` section to the phishlet YAML
- Include `domain:` and `path:` fields pointing at the site's real login endpoint
- Reload the phishlet after the edit
Example fix
// before
credentials:
username:
key: username
password:
key: password
// after
credentials:
username:
key: username
password:
key: password
login:
domain: accounts.example.com
path: /login Defensive patterns
Strategy: validation
Validate before calling
var fp struct {
LoginItem *struct {
Domain *string `yaml:"domain"`
Path *string `yaml:"path"`
} `yaml:"login"`
}
yaml.Unmarshal(data, &fp)
if fp.LoginItem == nil {
return errors.New("phishlet must define a top-level `login:` section with domain and path")
} Type guard
func hasLogin(fp *PhishletConfig) bool {
return fp != nil && fp.LoginItem != nil
} Try / catch
err := cfg.AddPhishlet("local", name)
if err != nil {
if strings.Contains(err.Error(), "missing `login` section") {
log.Fatalf("phishlet %s: add a login block with domain and path", name)
}
return err
} Prevention
- Include login.domain and login.path in every phishlet from the start
- Point login at the real site's login endpoint, not the phishing domain
- Keep `login:` at top-level indentation, not nested under another key
- Re-load the phishlet after each structural edit
When it happens
Trigger: Loading a phishlet YAML that includes proxy_hosts and credentials but omits the `login:` block, or has it mis-indented so it does not bind to the struct.
Common situations: Trimming a phishlet down and removing the login block by mistake; renaming `login` to something like `signin`; YAML anchor/tag errors that leave the field nil.
Related errors
- credentials: missing `password` section
- credentials: missing `username` section
- force_post: missing force `key` field
- force_post: missing force `value` field
- force_post: missing or empty `force` field
AI-assisted analysis of kgretzky/evilginx2@4c0988a1d9 (2026-09-05).
Data as JSON: /api/errors/abd28d0da23578c8.
Report an issue: GitHub.
Appendix: source
Thrown at core/phishlet.go:393
}
if fp.ProxyHosts == nil {
return fmt.Errorf("missing `proxy_hosts` section")
}
if fp.AuthTokens == nil {
return fmt.Errorf("missing `auth_tokens` section")
}
if fp.Credentials == nil {
return fmt.Errorf("missing `credentials` section")
}
if fp.Credentials.Username == nil {
return fmt.Errorf("credentials: missing `username` section")
}
if fp.Credentials.Password == nil {
return fmt.Errorf("credentials: missing `password` section")
}
if fp.LoginItem == nil {
return fmt.Errorf("missing `login` section")
}
for _, ph := range *fp.ProxyHosts {
if ph.PhishSub == nil {
return fmt.Errorf("proxy_hosts: missing `phish_sub` field")
}
if ph.OrigSub == nil {
return fmt.Errorf("proxy_hosts: missing `orig_sub` field")
}
if ph.Domain == nil {
return fmt.Errorf("proxy_hosts: missing `domain` field")
}
auto_filter := true
if ph.AutoFilter != nil {
auto_filter = *ph.AutoFilter
}
p.addProxyHost(p.paramVal(*ph.PhishSub), p.paramVal(*ph.OrigSub), p.paramVal(*ph.Domain), ph.Session, ph.IsLanding, auto_filter)
}View on GitHub (pinned to 4c0988a1d9)