CodeQL 文档

电子邮件内容注入

ID: go/email-injection
Kind: path-problem
Security severity: 9.8
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-640
Query suites:
   - go-code-scanning.qls
   - go-security-extended.qls
   - go-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

使用不受信任的输入来构建电子邮件可能会导致多个安全漏洞。例如,在电子邮件正文中包含不受信任的输入可能会允许攻击者进行跨站脚本 (XSS) 攻击,而包含 HTTP 标头可能会导致完全的帐户泄露,如下面的示例所示。

建议

传递给电子邮件主题或正文的任何数据在使用前都必须进行清理。

示例

在下面的代码段示例中,host 字段是由用户控制的。

恶意用户可以向目标网站发送 HTTP 请求,但使用的 Host 标头指的是他们自己的网站。这意味着电子邮件将从受害者信任的服务器发送给潜在受害者,但链接会指向恶意网站。

如果电子邮件包含密码重置链接,并且受害者点击了该链接,则秘密重置令牌将泄露给攻击者。使用泄露的令牌,攻击者就可以构建真实的重置链接,并使用它来更改受害者的密码。

package main

import (
	"net/http"
	"net/smtp"
)

func mail(w http.ResponseWriter, r *http.Request) {
	host := r.Header.Get("Host")
	token := backend.getUserSecretResetToken(email)
	body := "Click to reset password: " + host + "/" + token
	smtp.SendMail("test.test", nil, "from@from.com", nil, []byte(body))
}

防止这种情况的一种方法是从受信任的配置文件加载主机名。

package main

import (
	"net/http"
	"net/smtp"
)

func mailGood(w http.ResponseWriter, r *http.Request) {
	host := config.Get("Host")
	token := backend.getUserSecretResetToken(email)
	body := "Click to reset password: " + host + "/" + token
	smtp.SendMail("test.test", nil, "from@from.com", nil, []byte(body))
}

参考

  • ©GitHub 公司
  • 条款
  • 隐私