繁体   English   中英

如何使用OWASP HTML Sanitizer允许特定字符?

[英]How to allow specific characters with OWASP HTML Sanitizer?

我正在使用OWASP Html Sanitizer来防止对我的网络应用程序进行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清理程序以允许特定字符,如+ - @?

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

您可能希望使用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));

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

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

第一个策略示例:

用户输入数据(使用html代码)

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

第二个策略示例:

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

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

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

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

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

说实话,你应该真正针对所有用户提供的输入进行白名单。 如果它是一个电子邮件地址,只需使用OWASP ESAPI或其他东西验证输入与其Validator和电子邮件正则表达式。

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

OWASP不建议您使用黑名单方法,并且可能会被承诺攻击用户的人绕过。

我知道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;
    }
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM