【问题标题】:Java 5 HTML escaping To Prevent XSSJava 5 HTML 转义以防止 XSS
【发布时间】:2010-02-25 11:28:16
【问题描述】:

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

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

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

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

【问题讨论】:

  • 请注意,下面接受的答案是一种不完整且幼稚的方法。 Encoding the "big 5" serves exactly the purpose it was designed for: prevents injecting HTML markup with illegal characters inside tags and attribute values. However it does not prevent more elaborate injections, does not help with "out of range characters = question marks" when outputting Strings to Writers with single byte encodings, nor prevents character reinterpretation when user switches browser encoding over displayed pageowasp.org/index.php/How_to_perform_HTML_entity_encoding_in_Java
  • 您不会说接受的答案通常是正确的,只是在转义 HTML 时需要考虑更大范围的字符?
  • 锁好门很好,但最好不要让窗户大开。这是危险的建议。
  • 转义不是解决方案,特别是如果您希望用户通过 tiny mc 等富文本编辑器输入 HTML 子集。

标签: java jsp xss


【解决方案1】:

您通常在 display 期间逃避 XSS,而不是在 store 期间。在 JSP 中,您可以为此使用 JSTL(只需将 jstl-1.2.jar 放入 /WEB-INF/lib<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;amp; 而不是 &amp;amp; 以便最终用户会真正看到 @987654337 @ 而不是 &amp;amp; 在视图中。代码和数据库对 XSS 不敏感。只有视图是。然后你应该只在 就在那儿转义它。

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

我只会警告你:你确实不需要需要在 servlet/filter/javacode/database/whatever 中转义它。你只是不必要地把事情复杂化了。只是在显示期间逃脱它。就是这样。

【讨论】:

  • 这不过是合乎逻辑的。它使数据不可移植。数据与特定视图相关联。数据也是不可维护的。你不知道什么被逃脱了,什么没有。在社交网站上采取社交行动也是不可能的。您无法从数据中判断用户是否有恶意。您应该永远更改用户输入。仅在即将处理数据的那一刻将其从恶意中逃脱。例如。在要持久化数据时逃避 SQL 注入(PreparedStatement)并在要以 HTML 形式显示数据时逃避 XSS(fn:escapeXml)
  • -1,对标签执行 HTML 实体编码不足以防止 XSS 攻击。您还应该使用允许字符的白名单。
  • 在此处查看与特定字符相关的漏洞列表:ha.ckers.org/charsets.html 您提供的建议非常糟糕,您甚至都没有意识到这一点。
  • @BalusC 我不得不说我同意@Pool 对此的看法。我也不同意你永远不应该有任何类型的策略来阻止输入或更改用户输入的逻辑(永远不??真的)。
  • @BalusC 转义仍然不能阻止 XSS,并且输入的消毒将阻止 任何用户提交的数据 做坏事。不想对输入进行清理更多的是边缘情况,您可以处理异常(可能使用注释)。您不想要恶意数据的另一个原因是您是否向 Internet 提供了任何排序的 REST API。您可能会在输出上做正确的事情,但您的混搭伙伴可能不会。
【解决方案2】:

不是内置的,但请查看owasp esapi filter,它应该可以满足您的需求以及更多功能。这是一个很棒的开源安全库,由 Owasp(“开放 Web 应用程序安全项目”)的聪明人编写。

【讨论】:

    【解决方案3】:

    我不得不说我不同意显然在输出上转义以防止 XSS 的公认答案。

    我相信更好的方法是对输入进行清理,这可以通过方面轻松实现,这样您就不必把它放在所有地方。 消毒不同于转义

    你不能只是盲目地逃避:

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

    我建议使用带有 Aspect 或 @futtta 推荐的过滤器的 OWASP Antisammy 库。

    以下是我编写的一个方面,用于使用 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);
        }
    }
    

    您仍然需要对非富文本字段的输出进行转义,但您永远不会(而且我相信永远不会)在您的数据库中包含恶意数据。

    如果您不想对某些输入进行清理,您可以随时进行注释以使方面无法清理。

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

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

    【讨论】:

    • 这完全违背了 OWASP 的一般建议。清理输入是有问题的,因为在许多情况下它会错误地清理完全合法的数据,因为某些字符可能在未转义显示时是有害的。
    • 现实情况是你需要同时做这两件事,特别是如果你允许 HTML 输入。仅仅因为您进行了消毒并不意味着您也必须将其存储起来。您可以失败并告诉用户原因。
    • 你能举一个字符串被转义后执行的例子吗?转义后,我在我的 JSP 中尝试了一堆但没有一个执行。
    猜你喜欢
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-02
    • 1970-01-01
    • 2020-08-09
    • 2017-08-25
    • 2014-10-21
    相关资源
    最近更新 更多