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

オープン
#21,770 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
静か
技術スタック
go
領域
security

調査の方向性

go/email-injection から始め、カスタム Struct、イベントフィールド、通知ヘルパーを通じて渡される値を、その source-to-sink フローがどのように処理するかを追跡します。これを、Forwarded/X-Forwarded-Host から password-reset-link までの説明されたパスと比較します。クエリが間接的なフローをカバーし、報告された False Negative を回避すれば完了です。

索引モデルが issue の本文から書いたものです。

説明

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.

主要言語
CodeQL
スター
10.1k
フォーク
2.1k
平均マージ
2日 10時間
マージ済み PR(30日)
134

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

github/codeql のほかの issue

github/codeql の issue をすべて見る

似ている issue

Security の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。