Java5HTML转义以防止XSS

Java5HTML转义以防止XSS,java,jsp,xss,Java,Jsp,Xss,我正在研究Java应用程序中的一些XSS预防措施 我目前有定制的例程,这些例程将转义存储在数据库中的任何HTML,以便在JSP中安全显示。但是,如果可能的话,我宁愿使用内置/标准方法来实现这一点 我目前没有对发送到数据库的数据进行编码,但我也想开始这样做 有什么内置方法可以帮助我实现这一点吗?不是内置的,但请查看,它应该可以满足您的需要,还有更多。这是一个很棒的开源安全库,由Owasp(“开放Web应用程序安全项目”)的聪明人和女孩编写。您通常在显示期间逃逸XSS,而不是在存储期间逃逸XSS。在

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

我目前有定制的例程,这些例程将转义存储在数据库中的任何HTML,以便在JSP中安全显示。但是,如果可能的话,我宁愿使用内置/标准方法来实现这一点

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


有什么内置方法可以帮助我实现这一点吗?

不是内置的,但请查看,它应该可以满足您的需要,还有更多。这是一个很棒的开源安全库,由Owasp(“开放Web应用程序安全项目”)的聪明人和女孩编写。

您通常在显示期间逃逸XSS,而不是在存储期间逃逸XSS。在JSP中,您可以为此使用(只需插入
/WEB-INF/lib
)标记或函数。例如

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


就这样。如果您在处理输入和/或在数据库中存储时也这样做,那么它将分布在业务代码和/或数据库中。你不应该这样做,这只是维护问题,当你在不同的地方这样做时,你将面临双重或更多的风险(例如,
&
将变成
&;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp

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

  • 这个

我只想警告你:你确实不需要在servlet/filter/javacode/database/whatever中转义它。你只是不必要地过度复杂了一些事情。只需要在显示时转义它。仅此而已。

我不得不说,我不同意公认的答案,即显然是在输出时转义以防止XSS

我认为更好的方法是对输入进行清理,这可以很容易地通过一个方面来实现,这样你就不必把它放得到处都是。清理不同于转义

你不能盲目地逃避:

  • 您可能希望用户输入HTML的子集(又名链接和粗体标记)
  • 转义不会阻止XSS
我建议将OWASP Antisammy库与Aspect或@Futta推荐的过滤器一起使用

下面是我编写的一个方面,它使用SpringMVC注释来清理用户输入(因为我们对所有输入都使用它)

@SuppressWarnings(“未使用”)
@面貌
公共类UserInputSanitizerAdivsor{
@大约(“执行(@RequestMapping**(..)”)
公共对象检查(最终处理连接点jp)抛出可丢弃{
对象[]args=jp.getArgs();
如果(args!=null){
对于(int i=0;i
对于非富文本字段,您仍然必须在输出时转义,但您的数据库中永远不会(我相信也不应该)有恶意数据

如果您不想对某些输入进行清理,则始终可以进行注释,使方面不进行清理

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


清理输入或阻止输入是可以的(我是说大多数人都有文件上传限制吗?)。web应用程序中的大多数字段不需要输入脚本标记,更重要的是,大多数用户可能不需要或不想输入脚本标记(明显的例外是堆栈溢出).

这只不过是逻辑上的。它使数据不可移植。数据绑定到特定视图。数据也不可维护。你不知道什么被转义,什么不被转义。在社交网站中采取社交行为也是不可能的。你无法从数据中判断用户是否有恶意意图。你永远不应该更改用户输入。O仅在数据即将被处理时才对其进行恶意转义。例如,在数据被持久化时转义SQL注入(PreparedStatement)和在数据以HTML显示时转义XSS(fn:escapeXml)-1、对标记执行HTML实体编码不足以防止XSS攻击。您还应该使用一个允许字符的白名单。有关与特定字符相关的漏洞列表,请参阅此处:您给出的建议非常糟糕,您甚至没有意识到。@BalusC我不得不说我同意@Pool的观点。我也不同意e的逻辑是,您永远不应该有任何类型的策略来阻止输入或更改用户输入(从不??真的)。@BalusC escaping仍然不能阻止XSS,而santizing on input将阻止任何用户提交的数据做坏事。不想对输入进行消毒更是一种边缘情况,您可以处理异常(可能有注释)。您不想要恶意数据的另一个原因是,如果您向Internet提供任何排序REST API。您可以在输出上做正确的事情,但您的mashup合作伙伴可能不会。请注意,下面接受的答案是一种不完整和幼稚的方法。
编码“大5”它的设计目的正是:防止在标记和属性值中注入含有非法字符的HTML标记。但是,它不能防止更复杂的注入,也无助于“超出范围的字符=问号”当使用单字节编码将字符串输出给编写器时,当用户切换浏览器编码而不是显示时,也不会阻止字符重新解释
<input name="foo" value="${fn:escapeXml(param.foo)}">
@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);
    }
}