スプリングブート防御はクロスサイト スクリプティング (XSS) 攻撃です

クロスサイト スクリプティング (XSS) 攻撃に対する保護

XSS 攻撃は通常、Web サイトのシステム ストレージ システムの抜け穴を悪用して Web ページに悪意のある命令を挿入することを指し、ユーザーが Web ページを読み込むと悪意のあるスクリプトが自動的に実行されます。

例えば:

<script>
    alert(xss);
</script>

クライアントがブラウザで JavaScript を実行できる場合、Cookie またはトークンが盗まれる可能性があります。

1. pom.xml による依存関係の追加

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.14</version>
        </dependency>

hutoolのナレッジポイントを閲覧できます

HTML ツール クラス - HtmlUtil Hutool リファレンス ドキュメント

 

 

2. 独自の com.xxx.filter.xss パッケージ内に新しいクラス XssHttpServletRequestWrapper を作成します。

package com.xxxx.filter.xss;


public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    /**
     * 声明子类的构造器
     * @param request
     */
    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name);
        if(!StrUtil.hasEmpty(value)) {
            //把一些带script标签的 过滤掉,变成普通文本 HtmlUtil.filter 过滤HTML文本,防止XSS攻击
            value = HtmlUtil.filter(value);
        }
        //然后可以安全的保存到数据库里面的
        return value;
    }

    /**
     * 把返回的参数也进行转义
     * @param name
     * @return
     */
    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if(values != null){
            for (int i = 0;i < values.length; i++){
                String value = values[i];
                if(!StrUtil.hasEmpty(value)){
                    //把一些带script标签的 过滤掉,变成普通文本 HtmlUtil.filter 过滤HTML文本,防止XSS攻击
                    value = HtmlUtil.filter(value);
                }
                values[i] = value;
            }
        }
        //然后可以安全的保存到数据库里面的
        return values;
    }

    /**
     * 把请求中的数据返回一个map对象,也要做一下转义
     * @return
     */
    @Override
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> parameters = super.getParameterMap();
        LinkedHashMap<String, String[]> map = new LinkedHashMap();
        if(parameters!=null){
            for (String key:parameters.keySet()){
                String[] values=parameters.get(key);
                for (int i = 0; i < values.length; i++) {
                    String value = values[i];
                    if (!StrUtil.hasEmpty(value)) {
                        //HtmlUtil.filter 过滤HTML文本,防止XSS攻击
                        value = HtmlUtil.filter(value);
                    }
                    values[i] = value;
                }
                map.put(key,values);
            }
        }
        return map;
    }

    /**
     * 从请求头获取到数据 也要做一下转义
     * @param name
     * @return
     */
    @Override
    public String getHeader(String name) {
        String value= super.getHeader(name);
        if (!StrUtil.hasEmpty(value)) {
            //HtmlUtil.filter 过滤HTML文本,防止XSS攻击
            value = HtmlUtil.filter(value);
        }
        return value;
    }

    /**
     * 通过io流 读取数据 也要做一下转义
     * @return
     * @throws IOException
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {
        InputStream in= super.getInputStream();
        InputStreamReader reader=new InputStreamReader(in, Charset.forName("UTF-8"));
        BufferedReader buffer=new BufferedReader(reader);
        StringBuffer body=new StringBuffer();
        String line=buffer.readLine();
        while(line!=null){
            body.append(line);
            line=buffer.readLine();
        }
        buffer.close();
        reader.close();
        in.close();
        Map<String,Object> map=JSONUtil.parseObj(body.toString());
        Map<String,Object> result=new LinkedHashMap<>();
        for(String key:map.keySet()){
            Object val=map.get(key);
            if(val instanceof String){
                if(!StrUtil.hasEmpty(val.toString())){
                    //转义
                    result.put(key,HtmlUtil.filter(val.toString()));
                }
            }
            else {
                //不需要转义的数据
                result.put(key,val);
            }
        }
        //又转成json的字符串
        String json=JSONUtil.toJsonStr(result);
        ByteArrayInputStream bain=new ByteArrayInputStream(json.getBytes());
        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return bain.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }
        };
    }
}

 3. 別の XssFilter を構築する

package com.xxxx.filter.xss;

/**
 * urlPatterns = "/*"表示所有请求路由都需要拦截的
 */
@WebFilter(urlPatterns = "/*")
public class XssFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        XssHttpServletRequestWrapper wrapper = new XssHttpServletRequestWrapper(request);
        //通过后 继续往下执行 放行
        filterChain.doFilter(wrapper,servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

4. 最後のステップは、スタートアップ ファイルに追加することです。

@ServletComponentScan

  

5.スタート

6. 最後に、バックエンドは <script> タグをフィルターで除外します。

結果は

alert(xxxxx);

7. ただし、html タグも同時に除外されるため、html タグを除外したくありません。

未完の続報……。

おすすめ

転載: blog.csdn.net/deng_zhihao692817/article/details/130615017