给springboot增加XSS跨站脚本攻击防护功能
XSS原理
xss攻击的原理是利用前后端校验不严格,用户将攻击代码植入到数据中提交到了后台,当这些数据在网页上被其他用户查看的时候触发攻击
举例:用户提交表单时把地址写成:山东省济南市<script>for(var i=0;i<9999;i++){alert(i)}</script>
上面的数据如果没有在后台做处理,当数据被展示到网页上的时候,会在网页上弹出N个alert框,当然实际攻击肯定是比这个要复杂的多的
SpringBoot防护
给SpringBoot增加这种防护的原理是用户提交数据之后后台在获取数据内容时做一层过滤。过滤方式有两种
第一种
第一种方式是对特殊字符进行转义操作,例如将 < > /等特殊字符转换成html支持的 < >等,这样显示到页面的时候还是那些内容但是不会当成脚本执行了
这种方式我们用到了SpringFramework自带的HtmlUtils.htmlEscape方法进行替换
```org.springframework.web.util.HtmlUtils.htmlEscape```
第二种
第二种是直接把数据过滤一遍彻底去掉不安全的因素,包括隐藏在标签当中的 onXX=“js代码” 属性。
这一种方式用到了一个jar包 jsoup,Maven的依赖如下:
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
无论以上那种方式都需要对参数进行过滤处理,具体处理方式如下:
1.添加jsoup包的依赖
2.增加一个Filter类
import com.aliyuncs.utils.StringUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class XssFilter implements Filter {
private List<String> excludes = new ArrayList<>();
private boolean enabled = false;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String strExcludes = filterConfig.getInitParameter("excludes");
String strEnabled = filterConfig.getInitParameter("enabled");
//将不需要xss过滤的接口添加到列表中
if(StringUtils.isNotEmpty(strExcludes)){
String[] urls = strExcludes.split(",");
for(String url:urls){
excludes.add(url);
}
}
if(StringUtils.isNotEmpty(strEnabled)){
enabled = Boolean.valueOf(strEnabled);
}
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
//如果该访问接口在排除列表里面则不拦截
if(isExcludeUrl(request.getServletPath())){
filterChain.doFilter(servletRequest,servletResponse);
return;
}
//拦截该url并进行xss过滤
XssHttpServletRequestWrapper xssHttpServletRequestWrapper = new XssHttpServletRequestWrapper(request);
filterChain.doFilter(xssHttpServletRequestWrapper,servletResponse);
}
@Override
public void destroy() {
}
private boolean isExcludeUrl(String urlPath){
if(!enabled){
//如果xss开关关闭了,则所有url都不拦截
return true;
}
if(excludes==null||excludes.isEmpty()){
return false;
}
String url = urlPath;
for(String pattern:excludes){
Pattern p = Pattern.compile("^"+pattern);
Matcher m = p.matcher(url);
if(m.find()){
return true;
}
}
return false;
}
}
3.增加一个xssHttpServletRequestWrapper类,这个类重写了获取参数的方法,在获取参数时做了xss替换处理
import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* xss过滤包装类
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private static final Logger logger = LoggerFactory.getLogger(XssHttpServletRequestWrapper.class);
/**
* Constructs a request object wrapping the given request.
*
* @param request The request to wrap
* @throws IllegalArgumentException if the request is null
*/
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getHeader(String name) {
String strHeader = super.getHeader(name);
if(StringUtils.isEmpty(strHeader)){
return strHeader;
}
return Jsoup.clean(super.getHeader(name),Whitelist.relaxed());
}
@Override
public String getParameter(String name) {
String strParameter = super.getParameter(name);
if(StringUtils.isEmpty(strParameter)){
return strParameter;
}
return Jsoup.clean(super.getParameter(name),Whitelist.relaxed());
}
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if(values==null){
return values;
}
int length = values.length;
String[] escapseValues = new String[length];
for(int i = 0;i<length;i++){
//过滤一切可能的xss攻击字符串
escapseValues[i] = Jsoup.clean(values[i], Whitelist.relaxed()).trim();
if(!StringUtils.equals(escapseValues[i],values[i])){
logger.debug("xss字符串过滤前:"+values[i]+"\r\n"+"过滤后:"+escapseValues[i]);
}
}
return escapseValues;
}
}
4.SpringBoot里面增加一个configuration配置,把Filter类配置上去
import cn.gov.zibo.scsupport.xss.XssFilter;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.DispatcherType;
import java.util.HashMap;
import java.util.Map;
/**
* 设置跨站脚本过滤
*/
@Configuration
public class FilterConfig {
@Value("${xss.enabled}")
private String enabled;
@Value("${xss.excludes}")
private String excludes;
@Value("${xss.urlPatterns}")
private String urlPatterns;
@Bean
public FilterRegistrationBean xssFilterRegistration(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setDispatcherTypes(DispatcherType.REQUEST);
registrationBean.setFilter(new XssFilter());
registrationBean.addUrlPatterns(StringUtils.split(urlPatterns,","));
registrationBean.setName("XssFilter");
registrationBean.setOrder(9999);
Map<String,String> initParameters = new HashMap<>();
initParameters.put("excludes",excludes);
initParameters.put("enabled",enabled);
registrationBean.setInitParameters(initParameters);
return registrationBean;
}
}
5.最后在application.properties或者application.yml里面增加一些开关配置,可以忽略某些接口提交的数据或者关闭xss过滤
#xss攻击拦截
xss.enabled=true
xss.excludes=
xss.urlPatterns=/*
6.上面使用的是第二种处理方式,如果想使用第一种处理方式 只需要把XssHttpServletRequestWrapper类里面的Jsoup.clean方法替换成HtmlUtils.htmlEscape(xxx,"UTF-8")即可
给springboot增加XSS跨站脚本攻击防护功能的更多相关文章
- xss(跨站脚本攻击),crsf(跨站请求伪造),xssf
我们常说的网络安全其实应该包括以下三方面的安全: 1.机密性,比如用户的隐私被窃取,帐号被盗,常见的方式是木马. 2.完整性,比如数据的完整,举个例子,康熙传位十四子,被当时四阿哥篡改遗诏:传位于四子 ...
- 个人网站对xss跨站脚本攻击(重点是富文本编辑器情况)和sql注入攻击的防范
昨天本博客受到了xss跨站脚本注入攻击,3分钟攻陷--其实攻击者进攻的手法很简单,没啥技术含量.只能感叹自己之前竟然完全没防范. 这是数据库里留下的一些记录.最后那人弄了一个无限循环弹出框的脚本,估计 ...
- XSS跨站脚本攻击实例讲解,新浪微博XSS漏洞过程分析
2011年6月28日晚,新浪微博遭遇到XSS蠕虫攻击侵袭,在不到一个小时的时间,超过3万微博用户受到该XSS蠕虫的攻击.此事件给严重依赖社交网络的网友们敲响了警钟.在此之前,国内多家著名的SNS网站和 ...
- web应用程序安全攻防---sql注入和xss跨站脚本攻击
kali视频学习请看 http://www.cnblogs.com/lidong20179210/p/8909569.html 博文主要内容包括两种常见的web攻击 sql注入 XSS跨站脚本攻击 代 ...
- Fortify漏洞之Cross-Site Scripting(XSS 跨站脚本攻击)
书接上文,继续对Fortify漏洞进行总结,本篇主要针对XSS跨站脚步攻击漏洞进行总结,如下: 1.Cross-Site Scripting(XSS 跨站脚本攻击) 1.1.产生原因: 1. 数据通过 ...
- 解析如何防止XSS跨站脚本攻击
2012-11-20 09:03 (分类:网络安全) 这些规则适用于所有不同类别的XSS跨站脚本攻击,可以通过在服务端执行适当的解码来定位映射的XSS以及存储的XSS,由于XSS也存在很多特殊情况,因 ...
- XSS跨站脚本攻击与CSRF跨站请求伪造攻击的学习总结(转载)
转载自 https://blog.csdn.net/baidu_24024601/article/details/51957270 之前就了解过这方面的知识,但是没有系统地总结.今天在这总结一下,也让 ...
- PHP漏洞全解(四)-xss跨站脚本攻击
本文主要介绍针对PHP网站的xss跨站脚本攻击.跨站脚本攻击是通过在网页中加入恶意代码,当访问者浏览网页时恶意代码会被执行或者通过给管理员发信息 的方式诱使管理员浏览,从而获得管理员权限,控制整个网站 ...
- JAVA覆写Request过滤XSS跨站脚本攻击
注:本文非本人原著. demo的地址:链接:http://pan.baidu.com/s/1miEmHMo 密码:k5ca 如何过滤Xss跨站脚本攻击,我想,Xss跨站脚本攻击令人为之头疼.为什么呢. ...
随机推荐
- 28.4 Calendar 日历
/* * Calendar:日历,提供了一些操作年月日时的方法 * 获取 * 修改 * 添加 */ public class CalendarDemo { public static void mai ...
- "多行文本"组件:<multi> —— 快应用组件库H-UI
 <import name="multi" src="../Common/ui/h-ui/text/c_text_multi"></impo ...
- virtual box设置网络,使用nat网络和仅主机(Host Only)网络进行连接
virtual box设置网络,使用nat网络和仅主机(Host Only)网络进行连接 前言 作为程序员难免要在本机电脑安装虚拟机,最近在用virtual box安装虚拟机的时候遇到了点问题. 对于 ...
- alg-查找只出现一次的数
//只有2个数出现1次,其余的数都出现2次 class Solution { public: vector<int> singleNumber(const vector<int> ...
- 利用浏览器的console篡改cookie
背景: 最近公司有个客户问题,是由于浏览器的cookie中多记录过期的session id导致重复登录,普通操作无法复现,因此尝试进行cookie篡改复现问题. 方法: 首先,要知道软件定义的sess ...
- 重启mysql服务
重启mysql 启动mysql: 方式一:sudo /etc/init.d/mysql start 方式二:sudo service mysql start 停止mysql: 方式一:sudo /et ...
- 20200107——记spring的DataSource
spring项目中总要跟数据库打交道,其中怎么连接数据库的方法都有很多,大概分为3类: 1) 通过JNDI获取应用服务器(如JBOSS, Tomcat) 的数据源 2) Spring容器中直接配置数 ...
- Java 多线程 -- 理解锁:手动实现可重入锁和不可重入锁
JDK提供的大多数内置锁都是可重入的,也就是 说,如果某个线程试图获取一个已经由它自己持有的锁时,那么这个请求会立 刻成功,并且会将这个锁的计数值加1,而当线程退出同步代码块时,计数器 将会递减,当计 ...
- 获取某个时间开始 之后的 N次[周几,周几]
废话不多说,直接上菜! 调用函数代码举例 //PS :这里需要注意的是 周日 是 0 !!!!! console.log(getBeforeDate(-10000)) //一万天之后的日期 conso ...
- VirtualBox 原始镜像转换成 vdi 镜像
VBoxManage convertdd [-static] <filename> <outputfile> 将raw硬盘转换成vdi虚拟硬盘