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.
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)
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
- missing `credentials` section
- credentials: missing `username` section
- credentials: missing `password` section
- proxy_hosts: missing `phish_sub` field
- proxy_hosts: missing `orig_sub` field
AI-assisted analysis of kgretzky/evilginx2@4c0988a1d9 (2026-09-05).
Data as JSON: /api/errors/abd28d0da23578c8.
Report an issue: GitHub.