编码电子邮件地址:EncodeForHTML 或 EncodeForURL

Encoding E-Mail Addresses: EncodeForHTML or EncodeForURL

当用户在网站上注册时,我们应该在将值存储到数据库之前使用 EncodeForHTML() 还是 EncodeForURL()

我问这个的原因是,当我向包含 URL 的人发送电子邮件时,其中包含作为 URL 变量的电子邮件地址,我必须使用 EncodeForURL().但是如果这个电子邮件地址已经使用 EncodeForHTML() 编码,这意味着我必须在再次使用 EncodeForURL() 之前对其进行 Canonicalize()。

因此我认为 EncodeForURL() 可能不错,但是将值存储在数据库中时是 'safe' 和 'correct' 吗?

更新:阅读文档后,它说 EncodeForURL 仅用于使用 URL 中的值。因此,我应该将其存储为 EncodedForHTML,然后在 URL 上下文中使用它时规范化并重新编码 URL 似乎是有道理的。我不知道所有这些编码会对我的服务器造成多大的性能影响...??

以纯文本形式存储电子邮件地址,然后在使用时根据上下文对其进行编码。如果它将成为 URL 的一部分,请使用 EncodeForURL()。如果要在 HTML 中显示为文本,请使用 EncodeForHtml().

从我公司的内部文档中复制。不确定图像是否正确上传,因为 imagr 被阻止@work。如果是这样,我稍后会重新上传它们。以后我会将此内容和更多相关内容发布到 Githib 存储库。


您应该将其存储为简单文本,但请确保在使用 AntiSamy 库的过程中清理数据。一旦数据安全,请确保使用适当的编码器对数据进行编码。仅供参考,encodeForHTML()encodeForHTMLAttribute() 的输出之间存在很大差异。

在下面的示例中,用数据库中的数据替换定义电子邮件地址的变量。


PROTIP:不要在 CFFORM 标签中使用这些编码器。这些标签会为您处理编码。 CF 9 及以下使用 HTMLEditFormat(),CF 10 及以上最有可能使用 encodeForHTMLAttribute().


简单实施

基本实现是包含一个电子邮件地址,以便填充新电子邮件 window 的 "To" 字段。

CFML

<cfset email = "someone@example.com" />
<a href="mailto:#email#">E-mail</a>

HTML输出

<a href="mailto:someone@example.com">E-mail</a>

具有适当编码的 CFML

<cfset email = "someone@example.com" />
<a href="mailto:#encodeForURL(email)#">E-mail</a>

编码HTML输出

请注意,“@”符号被正确地编码为“%40”。

<a href="mailto:someone%40example.com">E-mail</a>

点击后的结果

如果您打算在页面上显示电子邮件地址作为 link 的一部分:

<cfset email = "someone@example.com" />
<a href="mailto:#encodeForURL(email)#">#encodeForHTML(email)#</a>

攻击向量

高级实施包括 "To" 和 "CC" 的电子邮件地址。它还可以预填充新电子邮件的 bodysubject

没有编码的CFML

<cfset email = "someone@example.com" />
<cfset email_cc = "someone_else@example.com" />
<cfset subject = "This is the subject" />
<cfset body = "This is the body" />
<a href="mailto:#email#?cc=#email_cc#&subject=#subject#&body=#body#">E-mail</a>

HTML输出

<a href="mailto:someone@example.com?cc=someone_else@example.com&subject=This is the subject&body=This is the body">E-mail</a>

点击后的结果

注意 subjectbody 参数包含 spaces。虽然这个字符串在技术上是可行的,但它仍然容易受到攻击。

假设 body 的值是由数据库查询的结果设置的。此记录已被恶意用户 "infected" 并且默认正文消息附加了 "BCC" 地址,因此某些恶意用户可以获取通过此 link 发送的电子邮件的副本。

被感染的数据

<cfset body = "This is the body&bcc=someone@evil.com" />

HTML输出

<a href="mailto:someone@example.com?cc=someone_else@example.com&subject=This is the subject&body=This is the body&bcc=someone@evil.com">E-mail</a>

点击后的结果

为了阻止这个 MAILTO link 被感染,这个字符串需要被正确编码。

具有 HTML 属性编码的 CFML

由于 "href" 是 标签的一个属性,您可能会考虑使用 HTML 属性编码器。 这是不正确的。

<cfset email = "someone@example.com" />
<cfset email_cc = "someone_else@example.com" />
<cfset subject = "This is the subject" />
<cfset body = "This is the body&bcc=someone@evil.com" />
<a href="mailto:#encodeForHTMLAttribute(email)#?cc=#encodeForHTMLAttribute(email_cc)#&subject=#encodeForHTMLAttribute(subject)#&body=#encodeForHTMLAttribute(body)#">E-mail</a>

HTML输出

<a href="mailto:someone&#x40;example.com?cc=someone_else&#x40;example.com&subject=This&#x20;is&#x20;the&#x20;subject&body=This&#x20;is&#x20;the&#x20;body&amp;bcc&#x3d;someone&#x40;evil.com">E-mail</a>

点击后的结果

具有 URL 编码的 CFML

MAILTO link 的正确编码是使用 URL 编码器完成的。

<cfset email = "someone@example.com" />
<cfset email_cc = "someone_else@example.com" />
<cfset subject = "This is the subject" />
<cfset body = "This is the body&bcc=someone@evil.com" />
<a href="mailto:#encodeForURL(email)#?cc=#encodeForURL(email_cc)#&subject=#encodeForURL(subject)#&body=#encodeForURL(body)#">E-mail</a>

HTML 编码正确的输出

注意关于 URL 编码器的这些事情:

  1. 每个 space (" ") 都转换为加号 ("+") 而不是其预期的百分比值 ("%20")。
  2. 使用百分比 ("%") 值进行编码。
  3. 由于对各个查询参数进行了编码,因此连接每个参数的与号(“&”)未进行编码。
  4. 当"body"参数被编码时,它包含被恶意注入的“&body=”字符串。整个字符串现在是邮件正文的一部分,这可以防止电子邮件的意外 "bcc"。

<a href="mailto:someone%40example.com?cc=someone_else%40example.com&subject=This+is+the+subject&body=This+is+the+body%26bcc%3Dsomeone%40evil.com">E-mail</a>

点击后的结果

加号有什么用? 正确解码这些 URL 编码值取决于各个邮件客户端(例如 Outlook、GMail 等)。