2010-02-25 166 views
6

我正在研究Java应用程序中的一些XSS预防。Java 5 HTML转义防止XSS

我目前有自定义构建的例程,将转义任何HTML存储在数据库中安全显示在我的jsps。但是,如果可能的话,我宁愿使用内置/标准方法来执行此操作。

我目前没有编码发送到数据库的数据,但也想开始这样做。

是否有任何内置的方法可以帮助我实现这个目标?

+5

请注意,下面接受的答案是一个不完整和天真的方法。 '编码“5大”的目的正是为了设计它的目的:防止在标签和属性值中使用非法字符注入HTML标记。但是,它不会阻止更详细的注入,当使用单字节编码将字符串输出到作者时,不会帮助“超出范围的字符=问号”,也不会阻止用户在显示的页面上切换浏览器编码时的字符重新解释。 .owasp.org/index.php/How_to_perform_HTML_entity_encoding_in_Java – Pool 2010-03-05 01:47:50

+0

您是否会说接受的答案通常是正确的,只是在HTML转义时需要考虑更大范围的字符? – AJM 2010-03-08 12:04:45

+0

保持门锁是很好的,但最好不要让窗户敞开。这是危险的建议。 – Pool 2010-03-22 19:18:01

回答

9

您通常会在显示期间转义XSS,而不是在存储。在JSP中,您可以使用JSTL(只需在/WEB-INF/lib中删除jstl-1.2.jar<c:out>标记或fn:escapeXml函数。例如。

<input name="foo" value="<c:out value="${param.foo}" />"> 

<input name="foo" value="${fn:escapeXml(param.foo)}"> 

就是这样。如果您在处理输入和/或存储在数据库期间执行此操作,则它将全部遍布业务代码和/或数据库中。你不应该这样做,这只是维修的麻烦,当你在不同的地方做这件事时,你将冒险双重逃脱或更多(例如&将变为&amp;amp;而不是&amp;,以便最终用户在字面上看&amp;而不是&。 。代码和DB不是为XSS敏感只有观点是你应该然后逃逸只那里

更新:你已经发布4个主题关于同一主题:

我只提醒你:你不需要逃脱它的servlet /过滤/ javacode /数据库/不管。你只是不必要的过分复杂的事情。在显示过程中逃避它。就这样。

+0

是的,也许我应该停止发布问题了......就处理输出而言,这是一个我期盼得到的结论,但我注意到有些网站建议您至少输出结果,然后在存储上进行编码那。 – AJM 2010-02-25 13:13:43

+0

你有好的网站,你有坏的网站。 – BalusC 2010-02-25 13:18:02

+0

是的,但你知道一个相当明确的来源,我可以指出一个人爱上了坚持编码的HTML的想法,以改变他们的想法! – AJM 2010-02-25 13:23:20

5

不是内置的,但看看owasp esapi filter,它应该做你正在寻找和更多。这是一个伟大的开源安全库,由Owasp的聪明人&女孩编写(“Open Web Application Security Project”)。

5

我不得不说,我不同意接受的答案显然逃避输出,以防止XSS。

我认为更好的方法是对输入进行消毒处理,这可以通过一个方面很容易地实现,这样您就不必将它放在所有位置。 消毒不同于逃脱

你不能只是一味地逃避:

  • 您可能需要用户输入HTML的一个子集(又名链接和粗体标记)。
  • 逃逸并不能防止XSS

我建议使用OWASP Antisammy库过滤器的一个方面或@ futtta的建议。

下面是我写的一个方面,用Spring MVC注释清理用户输入(因为我们使用它来处理所有的输入)。

@SuppressWarnings("unused") 
@Aspect 
public class UserInputSanitizerAdivsor { 

    @Around("execution(@RequestMapping * * (..))") 
    public Object check(final ProceedingJoinPoint jp) throws Throwable { 
     Object[] args = jp.getArgs(); 
     if (args != null) { 
      for (int i = 0; i < args.length; i++) { 
       Object o = args[i]; 
       if (o != null && o instanceof String) { 
        String s = (String) o; 
        args[i] = UserInputSanitizer.sanitize(s); 
       } 
      } 
     } 
     return jp.proceed(args); 
    } 
} 

你仍然有逃避对非富文本域输出,但你永远不会(我相信应该永远)在你的数据库恶意数据。

如果您不想对特定输入进行消毒,您可以始终进行注释,以使该方面不会消毒。

您不希望数据库中存在恶意数据的另一个原因是您将任何排序REST API提供给Internet。您可能会在输出上做正确的事情,但混搭合作伙伴可能不会。

消毒输入或阻止输入是好的(我的意思是大多数人有文件上传限制权?)。 Web应用程序中的大多数字段不需要输入脚本标记,更重要的是,大多数用户可能不需要或不想输入脚本标记(显然,例外是堆栈溢出应答)。

+0

这完全违背了OWASP的一般建议。消毒输入是有问题的,因为它在很多情况下错误地清理了完全合法的数据,因为某些字符*在未显示未转义时可能会有害。 – 2016-01-20 12:00:00

+0

现实是,如果你允许HTML输入,你需要做到这两点。仅仅因为你消毒并不意味着你必须保存它。你可能会失败并告诉用户原因。 – 2016-02-04 09:38:01