Java 5 HTML转义To Prevent XSS

AJM*_*AJM 6 java xss jsp

我正在研究Java应用程序中的一些XSS预防.

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

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

有没有内置的方法可以帮助我实现这一目标?

Bal*_*usC 9

您通常在显示期间逃避XSS ,而不是在商店期间.在JSP中可以使用JSTL(刚落,JSTL-1.2.jar/WEB-INF/lib)<c:out>标签或fn:escapeXml功能这一点.例如

<input name="foo" value="<c:out value="${param.foo}" />">
Run Code Online (Sandbox Code Playgroud)

要么

<input name="foo" value="${fn:escapeXml(param.foo)}">
Run Code Online (Sandbox Code Playgroud)

而已.如果您在处理输入和/或存储在DB中时也这样做,那么它全部分布在业务代码和/或数据库中.你不应该这样做,它只是维护麻烦,当你在不同的地方做这件事时你会冒险双重逃避或更多(例如&,&amp;amp;而不是&amp;让最终用户真正看到&amp;而不是&在视野中.代码和数据库不是对XSS很敏感.只有视图才是.你应该只在那里逃避它.

更新:您发布了4个关于同一主题的主题:

我只提醒你:你不是需要逃离它的servlet /过滤/ javacode /数据库/不管.你只是不必要地使事情过于复杂.在显示期间逃脱它.就这样.

  • 这只不过是合乎逻辑的.它使数据不可移植.数据与特定视图相关联.数据也不可维护.你不知道什么是逃逸的,什么不是.在社交网站中采取社交行动也是不可能的.您无法从数据中判断用户是否具有恶意意图.你应该**永远不会改变用户输入.只有在数据即将被处理时才能摆脱恶意.例如,在数据要保留(PreparedStatement)时转义SQL注入,并在数据以HTML格式显示时转义XSS(fn:escapeXml) (2认同)
  • -1,在标签上执行HTML实体编码不足以阻止XSS攻击.您还应该使用允许字符的白名单. (2认同)
  • 请参阅此处查看与特定字符相关的漏洞列表:http://ha.ckers.org/charsets.html您提供的建议非常糟糕,您甚至都不知道. (2认同)
  • @BalusC 我不得不说我同意 @Pool 的观点。我也不同意你永远不应该有任何策略来阻止输入或更改用户输入的逻辑(永远??真的)。 (2认同)
  • @BalusC 转义仍然不能阻止 XSS,并且对输入进行清理将阻止*任何用户提交的数据* 做坏事。不想对输入进行消毒更多的是边缘情况,您可以处理异常(也许使用注释)。您不想要恶意数据的另一个原因是您是否向 Internet 提供了任何类型的 REST API。您可能会在输出方面做正确的事情,但您的混搭合作伙伴可能不会。 (2认同)
  • @BalusC 我认为这归结为一种意见。我认为我的方式可以更好地扩展,我可以更确定地保证即使我错过了 ac:out,我也永远不会遇到 XSS。看起来你宁愿用安全而不是原则和纯洁来交换。我不会。我的意思是,由于 XSS,最终用户提取他们不应该输入的数据或完全损坏的站点更令人尴尬。 (2认同)

fut*_*tta 5

不是内置的,但检查owasp esapi过滤器,它应该做你正在寻找的和更多.它是由Owasp("开放式Web应用程序安全项目")的聪明人和女孩编写的一个很棒的开源安全库.


Ada*_*ent 5

我不得不说我非常不同意接受的答案显然是为了防止XSS逃避输出.

我认为更好的方法是对输入进行消毒,这可以通过一个方面轻松实现,这样您就不必将它全部放在一起.消毒不同于逃避.

你不能盲目逃避:

  • 您可能希望用户输入HTML的子集(也称为链接和粗体标记).
  • 转义不会阻止XSS

我建议使用OWASP Antisammy库以及过滤器的Aspect或@ 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

您仍然必须在非富文本字段的输出上转义,但您永远不会(我相信永远不会)在您的数据库中包含恶意数据.

如果您不想对某些输入进行消毒,则可以始终进行注释,使该方面不会消毒.

如果您向Internet提供任何排序​​REST API,则您不希望数据库中存在恶意数据的另一个原因.您可以在输出上做正确的事情,但您的mashup合作伙伴可能不会.

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