Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

False negative in go/email-injection for password reset links built from Forwarded / X-Forwarded-Host

Open
#21,770 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
go
Domain
security

Research direction

Start at go/email-injection and trace how its source-to-sink flow handles values moved through custom structs, event fields, and notification helpers. Compare this with the described Forwarded/X-Forwarded-Host to password-reset-link path; done means the query covers the indirect flow and avoids the reported false negative.

Written by the indexing model from the issue text.

Description

Hi team,

I think I found a false negative in go/email-injection.

I ran into this while looking at ZITADEL's CVE-2025-64101 / GHSA-mwmh-7px9-4c23. The vulnerable flow is:

  • host data comes from Forwarded / X-Forwarded-Host
  • it is stored in a request/domain context object
  • that value is later carried through an event / notification path
  • and eventually used to build a password reset link that gets emailed to the user

Very roughly, it looks like this:

hostFromHeader = r.Header.Get(header)

if host == "" {
    host = hostFromHeader
}

TriggeredAtOrigin: http.DomainContext(ctx).Origin()

url = login.InitPasswordLink(http_utils.DomainContext(ctx).Origin(), user.ID, code, user.ResourceOwner, authRequestID)

The upstream fix sanitizes the host before storing it in the domain context, so this seems like a real missed case, not just a noisy benchmark result.

My guess is that the source side is already covered well enough, since net/http.Request.Header is modeled as remote input. The gap seems to be later in the flow, once the value moves through custom structs / event fields / notification helpers before it becomes part of email content.

I think this pattern is fairly common in real Go code. Password reset and verification links are often built indirectly through app-specific context and mailer abstractions, not directly inside a modeled mail API call.

For comparison, Semgrep did flag this codebase, but only with a broader rule about request-derived origin/host usage. It was not precise, but the general idea may still be useful here: request-header-derived host/origin values that later become user-facing links in emails probably deserve better coverage.

A reasonable fix might be improving go/email-injection so flow is preserved better through custom carrier objects and “build link first, send email later” patterns.

Dominant language
CodeQL
Stars
10.1k
Forks
2.1k
Avg merge
2d 16h
Merged PRs (30d)
143

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from github/codeql

All issues in github/codeql

Similar issues

More Security issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.