Springboot抵御即跨站脚本(XSS)攻击2

本文涉及的产品
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: Springboot抵御即跨站脚本(XSS)攻击2

三、定义请求包装类
我们平时写 Web 项目遇到的 HttpServletRequest ,它其实是个接口。如果我们想要重新定义请
求类,扩展这个接口是最不应该的。因为 HttpServletRequest 接口中抽象方法太多了,我们逐
一实现起来太耗费时间。所以我们应该挑选一个简单一点的自定义请求类的方式。那就是继承
HttpServletRequestWrapper 父类。

  JavaEE 只是一个标准,具体的实现由各家应用服务器厂商来完成。比如说 Tomcat 在实现

Servlet 规范的时候,就自定义了 HttpServletRequest 接口的实现类。同时 JavaEE 规范还定义
了 HttpServletRequestWrapper ,这个类是请求类的包装类,用上了装饰器模式。不得不说这里
用到的设计模式真的非常棒,无论各家应用服务器厂商怎么去实现 HttpServletRequest 接口,
用户想要自定义请求,只需要继承 HttpServletRequestWrapper ,对应覆盖某个方法即可,然后
把请求传入请求包装类,装饰器模式就会替代请求对象中对应的某个方法。用户的代码和服务器
厂商的代码完全解耦,我们不用关心 HttpServletRequest 接口是怎么实现的,借助于包装类我
们可以随意修改请求中的方法。同学们,如此优雅的代码设计,有时间你真该认真学习设计模
————————————————
```package com.example.emos.wx.config.xss;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import cn.hutool.json.JSONUtil;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.LinkedHashMap;
import java.util.Map;

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}

@Override
public String getParameter(String name) {
    String value= super.getParameter(name);
    if(!StrUtil.hasEmpty(value)){
        value=HtmlUtil.filter(value);
    }
    return value;
}

@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)){
                value=HtmlUtil.filter(value);
            }
            values[i]=value;
        }
    }
    return values;
}

@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)) {
                    value = HtmlUtil.filter(value);
                }
                values[i] = value;
            }
            map.put(key,values);
        }
    }
    return map;
}

@Override
public String getHeader(String name) {
    String value= super.getHeader(name);
    if (!StrUtil.hasEmpty(value)) {
        value = HtmlUtil.filter(value);
    }
    return value;
}

@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);
        }
    }
    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) {

        }
    };
}

}

四、创建过滤器,把所有请求对象传入包装类
        为了让刚刚定义的包装类生效,我们还要在 com.example.emos.wx.config.xss 中创建

XssFilter 过滤器。过滤器拦截所有请求,然后把请求传入包装类,这样包装类就能覆盖所有请
求的参数方法,用户从请求中获得数据,全都经过转义。
————————————————
```package com.example.emos.wx.config.xss;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class XssFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @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() {

    }
}

五、给主类添加注解
给SpringBoot主类添加 @ServletComponentScan 注解。

相关文章
|
4月前
|
SQL 安全 Java
揭秘Spring Boot安全防线:如何巧妙抵御XSS与SQL注入的双重威胁?
【8月更文挑战第29天】随着互联网技术的发展,Web应用已成为社会不可或缺的一部分。Spring Boot作为高效构建Web应用的框架备受青睐,但同时也面临安全挑战,如XSS攻击和SQL注入。本文介绍如何在Spring Boot应用中防范这两种常见安全漏洞。针对XSS攻击,可通过输入验证、输出编码及使用安全API来加强防护;对于SQL注入,则应利用预编译语句、参数化查询及最小权限原则来确保数据库安全。示例代码展示了具体实现方法,帮助开发者提升应用安全性。
319 2
|
4月前
|
前端开发 JavaScript Java
【实操】SpringBoot监听Iphone15邮件提醒,Selenium+Python自动化抢购脚本
本文介绍了一个结合SpringBoot和Python的实用功能,旨在监控iPhone 15的库存状态并通过邮件提醒用户。系统采用SpringBoot监听苹果官网API,解析JSON数据判断是否有货,并展示最近的库存记录。此外,还能自动触发Selenium+Python脚本实现自动化购买。文中详细介绍了技术栈、接口分析、邮件配置及自动化脚本的设置方法。该项目不仅适用于熟悉后端开发的人员,也适合回顾Layui和Jquery等前端技术。
59 0
【实操】SpringBoot监听Iphone15邮件提醒,Selenium+Python自动化抢购脚本
|
1月前
|
JavaScript 安全 前端开发
同源策略如何防止 XSS 攻击?
【10月更文挑战第31天】同源策略通过对 DOM 访问、Cookie 访问、脚本执行环境和跨源网络请求等多方面的严格限制,构建了一道坚实的安全防线,有效地防止了 XSS 攻击,保护了用户在网络浏览过程中的数据安全和隐私。
101 49
|
1月前
|
安全 前端开发 Java
Web安全进阶:XSS与CSRF攻击防御策略深度解析
【10月更文挑战第26天】Web安全是现代软件开发的重要领域,本文深入探讨了XSS和CSRF两种常见攻击的原理及防御策略。针对XSS,介绍了输入验证与转义、使用CSP、WAF、HTTP-only Cookie和代码审查等方法。对于CSRF,提出了启用CSRF保护、设置CSRF Token、使用HTTPS、二次验证和用户教育等措施。通过这些策略,开发者可以构建更安全的Web应用。
96 4
|
1月前
|
安全 Go PHP
Web安全进阶:XSS与CSRF攻击防御策略深度解析
【10月更文挑战第27天】本文深入解析了Web安全中的XSS和CSRF攻击防御策略。针对XSS,介绍了输入验证与净化、内容安全策略(CSP)和HTTP头部安全配置;针对CSRF,提出了使用CSRF令牌、验证HTTP请求头、限制同源策略和双重提交Cookie等方法,帮助开发者有效保护网站和用户数据安全。
76 2
|
1月前
|
存储 安全 Go
Web安全基础:防范XSS与CSRF攻击的方法
【10月更文挑战第25天】Web安全是互联网应用开发中的重要环节。本文通过具体案例分析了跨站脚本攻击(XSS)和跨站请求伪造(CSRF)的原理及防范方法,包括服务器端数据过滤、使用Content Security Policy (CSP)、添加CSRF令牌等措施,帮助开发者构建更安全的Web应用。
101 3
|
1月前
|
SQL 存储 安全
什么是XSS攻击?什么是SQL注入攻击?什么是CSRF攻击?
理解并防范XSS、SQL注入和CSRF攻击是Web应用安全的基础。通过采用严格的输入验证、使用安全编码实践以及实现适当的身份验证和授权机制,可以有效防止这些常见的Web攻击,保障应用程序和用户的数据安全。
42 0
|
3月前
|
存储 安全 JavaScript
XSS跨站脚本攻击详解(包括攻击方式和防御方式)
这篇文章详细解释了XSS跨站脚本攻击的概念、原理、特点、类型,并提供了攻击方式和防御方法。
588 1
|
3月前
|
SQL 安全 JavaScript
告别Web安全小白!Python实战指南:抵御SQL注入、XSS、CSRF的秘密武器!
【9月更文挑战第12天】在Web开发中,安全漏洞如同暗礁,尤其对初学者而言,SQL注入、跨站脚本(XSS)和跨站请求伪造(CSRF)是常见挑战。本文通过实战案例,展示如何利用Python应对这些威胁。首先,通过参数化查询防止SQL注入;其次,借助Jinja2模板引擎自动转义机制抵御XSS攻击;最后,使用Flask-WTF库生成和验证CSRF令牌,确保转账功能安全。掌握这些技巧,助你构建更安全的Web应用。
68 5
|
2月前
|
存储 JavaScript 安全