12

我正在使用 OWASP Html Sanitizer 来防止对我的 Web 应用程序的 XSS 攻击。对于许多应该是纯文本的字段,Sanitizer 的作用超出了我的预期。

例如:

HtmlPolicyBuilder htmlPolicyBuilder = new HtmlPolicyBuilder();
stripAllTagsPolicy = htmlPolicyBuilder.toFactory();
stripAllTagsPolicy.sanitize('a+b'); // return a+b
stripAllTagsPolicy.sanitize('foo@example.com'); // return foo@example.com

当我有诸如电子邮件地址之类的字段+时,例如foo+bar@gmail.com我最终在数据库中得到了错误的数据。所以两个问题:

  1. 诸如+ - @危险的字符本身是否真的需要编码?
  2. 如何配置 OWASP html sanitizer 以允许特定字符,例如 + - @?

问题 2 对我来说是更重要的一个答案。

4

4 回答 4

3

您可能希望使用 ESAPI API 来过滤特定字符。虽然如果你喜欢允许特定的 HTML 元素或属性,你可以使用下面的 allowElements 和 allowAttributes。

// 定义策略。

Function<HtmlStreamEventReceiver, HtmlSanitizer.Policy> policy
     = new HtmlPolicyBuilder()
         .allowElements("a", "p")
         .allowAttributes("href").onElements("a")
         .toFactory();

 // Sanitize your output.
 HtmlSanitizer.sanitize(myHtml, policy.apply(myHtmlStreamRenderer));
于 2014-11-17T03:02:26.433 回答
3

我知道我在 7 年后回答问题,但也许它对某人有用。所以,基本上我同意你们的观点,出于安全原因,我们不应该允许使用特定字符(您涵盖了这个主题,谢谢)。但是,我正在处理遗留的内部项目,该项目要求转义 html 字符但“@”,原因我不知道(但这没关系)。我的解决方法很简单:

private static final PolicyFactory PLAIN_TEXT_SANITIZER_POLICY = new HtmlPolicyBuilder().toFactory();


public static String toString(Object stringValue) {
    if (stringValue != null && stringValue.getClass() == String.class) {
        return HTMLSanitizerUtils.PLAIN_TEXT_SANITIZER_POLICY.sanitize((String) stringValue).replace("&#64;", "@");
    } else {
        return null;
    }
}

我知道它不干净,创建了额外的字符串,但我们非常需要这个。因此,如果您需要允许特定字符,您可以使用此解决方法。但是,如果您需要这样做,您的应用程序可能设计不正确。

于 2019-03-19T05:18:59.193 回答
1

XSS 的危险在于,一个用户可能会在他的输入数据中插入 html 代码,然后您将这些代码插入发送给另一个用户的网页中。

如果您想防止这种情况发生,原则上您可以遵循两种策略。您可以在用户进入系统时从用户输入中删除所有危险字符,也可以在稍后将危险字符写回浏览器时对其进行 html 编码。

第一种策略的示例:

用户输入数据(带有html代码)

  1. 服务器删除所有危险字符
  2. 修改后的数据存储在数据库中
  3. 一段时间后,服务器从数据库中读取修改后的数据
  4. 服务器将网页中的修改数据插入到另一个用户

第二种策略的例子:

  1. 用户输入数据(带有html代码)
  2. 未修改的数据,带有危险字符,存储在数据库中
  3. 一段时间后,服务器从数据库中读取未修改的数据
  4. 服务器对危险数据进行 html 编码,并将其插入到网页中以供其他用户使用

第一种策略更简单,因为您通常读取数据的频率低于使用它们的频率。但是,它也更加困难,因为它可能会破坏数据。如果您需要数据而不是稍后将它们发送回浏览器(例如使用电子邮件地址实际发送电子邮件),则特别困难。它使得在数据库中进行搜索、在 pdf 报告中包含数据、在电子邮件中插入数据等变得更加困难。

另一种策略的优点是不破坏输入数据,因此您可以在以后如何使用数据方面拥有更大的自由。但是,实际检查您是否对发送到浏览器的所有用户提交的数据进行了 html 编码可能会更加困难。解决您的特定问题的方法是在(或如果)您曾经将该电子邮件地址放在网页上时对该电子邮件地址进行 html 编码。

XSS 问题是当您混合用户提交的数据和控制代码时出现的更普遍问题的一个示例。SQL 注入是同一问题的另一个例子。问题是用户提交的数据被解释为指令而不是数据。第三个鲜为人知的例子是,如果您在电子邮件中混合用户提交的数据。用户提交的数据可能包含电子邮件服务器解释为指令的字符串。这种情况下的“危险字符”是一个换行符,后跟“From:”。

不可能针对所有可能的控制字符或字符序列验证所有输入数据,这些控制字符或字符序列可能以某种方式在未来的某些潜在应用中被解释为指令。唯一永久的解决方案是在您实际使用这些数据时实际清理所有可能不安全的数据。

于 2012-09-26T21:31:16.007 回答
1

老实说,你真的应该对所有用户提供的输入做一个白名单。如果它是一个电子邮件地址,只需使用 OWASP ESAPI 或其他东西来根据他们的验证器和电子邮件正则表达式验证输入。

如果输入通过白名单,您应该继续并将其存储在数据库中。在向用户显示文本时,您应该始终对其进行 HTML 编码。

OWASP 不推荐您的黑名单方法,并且可能会被致力于攻击您的用户的人绕过。

于 2012-09-27T12:19:12.867 回答