当前位置: 首页 > 知识库问答 >
问题:

用于XSS保护的请求体处的Spring Boot转义字符

怀刚毅
2023-03-14

我正在尝试使用XSSFilter保护我的spring boot应用程序,如下所示:

public class XSSFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    @Override
    public void destroy() { }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
    }

}

包装:

public class XSSRequestWrapper extends HttpServletRequestWrapper {

    public XSSRequestWrapper(HttpServletRequest servletRequest) {
        super(servletRequest);
    }

    @Override
    public String[] getParameterValues(String parameter) {
        String[] values = super.getParameterValues(parameter);

        if (values == null) {
            return null;
        }

        int count = values.length;
        String[] encodedValues = new String[count];
        for (int i = 0; i < count; i++) {
            encodedValues[i] = replaceXSSCharacters((values[i]));
        }

        return encodedValues;
    }

    private String replaceXSSCharacters(String value) {
        if (value == null) {
            return null;
        }

        return value
                .replace("&","&#38;")
                .replace("<", "&#60;")
                .replace(">","&#62;")
                .replace("\"","&#34;")
                .replace("'","&#39;");
    }

    @Override
    public String getParameter(String parameter) {
        return replaceXSSCharacters(super.getParameter(parameter));
    }

    @Override
    public String getHeader(String name) {
        return replaceXSSCharacters(super.getHeader(name));
    }

}

问题是,这只保护请求参数和标头,而不是请求主体,有时我的控制器使用@刚体接收数据。

因此,如果我向控制器提交一个json,如下所示:

{"name":"<script>alert('hello!')</script>"}

name属性的html字符没有像我需要的那样被转义。我怎样才能逃出尸体?

编辑:这与“重复”问题不同。我的问题很具体。如何在请求正文中转义字符。

共有3个答案

戚承业
2023-03-14

要删除XSS字符,您只需覆盖AbstractJackson2HttpMessageConverter—此转换器负责读取请求。请求主体对象的inputStream

@Component
public class XSSRequestBodyConverter extends AbstractJackson2HttpMessageConverter {
    public XSSRequestBodyConverter(ObjectMapper objectMapper) {
        super(objectMapper, MediaType.APPLICATION_JSON, new MediaType("application", "*+json"));
    }

@Override
public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage)
        throws IOException, HttpMessageNotReadableException {

    Object requestBody = super.read(type, contextClass, inputMessage);
    //Remove xss from requestBody here
    String requestInStr = objectMapper.writeValueAsString(requestBody);
    return objectMapper.readValue(replaceXSSCharacters(requestInStr), Object.class);
}


}
颛孙庆
2023-03-14
  1. 在XSSRequestWrapper中有一个本地字符串字段,用于保存已清理的实体(可能不适用于大型实体)

当JSON被反序列化为Java对象时,您可能还对清理JSON感兴趣。

濮阳鸿祯
2023-03-14

我使用自定义类解决了以下问题:

@Configuration
public class AntiXSSConfig  {

    @Autowired()
    public void configeJackson(ObjectMapper mapper) {
        mapper.getFactory().setCharacterEscapes(new HTMLCharacterEscapes());
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    public static class HTMLCharacterEscapes extends JsonpCharacterEscapes {

        @Override
        public int[] getEscapeCodesForAscii() {
            int[] asciiEscapes = CharacterEscapes.standardAsciiEscapesForJSON();
            // and force escaping of a few others:
            asciiEscapes['<'] = CharacterEscapes.ESCAPE_CUSTOM;
            asciiEscapes['>'] = CharacterEscapes.ESCAPE_CUSTOM;
            asciiEscapes['&'] = CharacterEscapes.ESCAPE_CUSTOM;
            asciiEscapes['"'] = CharacterEscapes.ESCAPE_CUSTOM;
            asciiEscapes['\''] = CharacterEscapes.ESCAPE_CUSTOM;
            return asciiEscapes;
        }

        @Override
        public SerializableString getEscapeSequence(int ch) {
            switch (ch) {
                case '&' : return new SerializedString("&#38;");
                case '<' : return new SerializedString("&#60;");
                case '>' : return new SerializedString("&#62;");
                case '\"' : return new SerializedString("&#34;");
                case '\'' : return new SerializedString("&#39;");
                default : return super.getEscapeSequence(ch);
            }
        }
    }
}

它涵盖了所有的案例。

 类似资料:
  • 问题内容: 我有一些用户输入。在我的代码中,我确保对以下符号进行转义: OWASP指出还有更多的字符可以转义。 对于属性,我做了另一种转义: 这样可以确保所有属性都用“括起来。”这样就可以确定自己的html属性,而不是HTML本身。 问题答案: 我也使用OWASP(ESAPI)库,以转义不同显示类型的字符串,请使用: HTML(假设为jsp) 更新 ( 2017 ) 由于ESAPI编码器被认为是旧

  • 问题内容: 我正在使用Golang来构建API Rest。我有一个包含很多字段的结构(超过100个),因此我使用了来自客户端的值来分配给该结构,效果很好。 现在,我要避免用户在任何字符串字段中插入Javascript代码,在结构中我定义了bool,strings,byte []和int值。因此,现在我想知道验证这一点的最佳方法是什么。 我正在考虑仅在字符串字段中对结构进行interate并进行如下

  • CSRF 中间件和模板标签提供对跨站请求伪造简单易用的防护。某些恶意网站上包含链接、表单按钮或者JavaScript ,它们会利用登录过的用户在浏览器中的认证信息试图在你的网站上完成某些操作,这就是跨站攻击。还有另外一种相关的攻击叫做“登录CSRF”,攻击站点触发用户浏览器用其它人的认证信息登录到其它站点。 防护CSRF 攻击的第一道防线是保证GET 请求(以及在9.1.1 Safe Method

  • 我有一个接受JSON的应用程序。它有一个带有@RestController的控制器,然后是一个 这“起作用”是因为它接受根据“MyRequest”对象有效的JSON并对其进行处理。我感兴趣的是捕捉JSON无效的时间。 目前,当有不良数据时会发生什么是Spring似乎会向标准输出写入这样的内容: 这一切都很好,但我想看看请求是什么,这是不好的,这样我就可以在源代码端修复它。 我在玩写“Control

  • 问题内容: 我尝试使用以下方法安装node.js模块: 但我得到这个错误: 可能正在发生这种情况,因为我使用代理服务器,但我通过这种方式设置了代理服务器,以允许从网络外部的ips下载 我希望你能帮帮我 问题答案: 从命令行设置代理。 如果仍然发生错误,请再试一次。 这些为我工作。(请参阅http://sushichop.blogspot.jp/2013/01/npm- install.html )

  • 保安。今天,任何应用程序如果没有适当的安全性编程--无论是由开发人员使用的框架,还是由开发人员自己编程--都无法在internet上生存。我目前正在开发一个使用承载令牌身份验证的RESTful API,但一直在阅读有关XSS和CSRF攻击的内容。 问题1)从我所读到的内容中,我看到使用基于令牌的身份验证的RESTful API的应用程序容易受到XSS而不是CSRF的攻击,如果令牌存储在浏览器的Lo