【问题标题】:Encoding E-Mail Addresses: EncodeForHTML or EncodeForURL编码电子邮件地址:EncodeForHTML 或 EncodeForURL
【发布时间】:2015-04-07 20:49:52
【问题描述】:

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

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

因此,我认为EncodeForURL() 可能很好,但是在将值存储在数据库中时它是否“安全”和“正确”?

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

【问题讨论】:

  • 我想不出一个不将电子邮件地址存储为简单文本的理由。但话又说回来,我想不出任何情况下我会向某人发送一封电子邮件,其中包含一个包含电子邮件地址作为 URL 变量的 URL。
  • 假设您正在向用户发送验证电子邮件以确认他们的注册。在电子邮件中放置的返回 URL 将是用户的电子邮件地址(URL 编码)和验证键值。不将其存储为简单文本的原因是为了防止 XSS 攻击
  • 我想我会选择散列或加密的东西,而不是电子邮件地址。我只是想避免通过电子邮件和类似的链接传递个人信息。

标签: coldfusion coldfusion-10 coldfusion-11


【解决方案1】:

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


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

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


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


简单实现

一个基本的实现是包含一个电子邮件地址,以便填充新电子邮件窗口的“收件人”字段。

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>

点击结果

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

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

攻击向量

高级实现包括“收件人”和“抄送”的电子邮件地址。它还可以预先填充新电子邮件的正文主题

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 输出

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

点击结果

请注意,subjectbody 参数包含空格。虽然这个字符串在技术上可以工作,但它仍然容易受到攻击。

想象 body 的值是由数据库查询的结果设置的。此记录已被恶意用户“感染”,并且默认正文消息附加了“密件抄送”地址,因此某些恶意用户可以获取通过此链接发送的电子邮件的副本。

受感染的数据

&lt;cfset body = "This is the body&amp;bcc=someone@evil.com" /&gt;

HTML 输出

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

点击结果

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

带有 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 输出

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

点击结果

带有 URL 编码的 CFML

MAILTO 链接的正确编码是通过 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. 每个空格 (" ") 都转换为加号 ("+"),而不是其预期的百分比值 ("%20")。
  2. 否则使用百分比 ("%") 值进行编码。
  3. 由于对各个查询参数进行了编码,因此连接每个参数的与号 ("&") 未编码。
  4. “body”参数编码时,包含恶意注入的“&body=”字符串。这整个字符串现在是邮件正文的一部分,可防止电子邮件的意外“密件抄送”。
&lt;a href="mailto:someone%40example.com?cc=someone_else%40example.com&amp;subject=This+is+the+subject&amp;body=This+is+the+body%26bcc%3Dsomeone%40evil.com"&gt;E-mail&lt;/a&gt;

点击结果

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

【讨论】:

  • 是的。您应该使用各个查询字符串参数。
  • 将值作为编码文本存储在数据库中没有意义吗?我一直以 html 编码格式存储其他所有内容,例如产品描述
  • 这样做的问题是您最终可能会在输出中出现双编码文本。您应该清理输入的数据并在输出时对其进行编码。
  • 有时用户会想要重置他们的密码。他们需要输入他们的电子邮件地址,我需要检查数据库,然后如果匹配,我将向他们发送新的密码重置表格。因此,当我进行此匹配时,我必须对存储的数据库电子邮件地址及其表单输入电子邮件地址进行编码,对吗?
  • 如果您要对存储的电子邮件进行编码,那么可以。但如果可能,请将其保存为纯文本。然后您只需清理表单数据(电子邮件)并进行比较。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2012-12-14
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    • 2017-07-23
    • 2011-01-31
    相关资源
    最近更新 更多