防止XSS Attack攻击的解决方案

2024-08-20 17:18

本文主要是介绍防止XSS Attack攻击的解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

需求:

1.防止用户RequestBody里面数据包含XSS Attack代码

2.防止用户RequestURL地址中包含XSS Attack代码

解决方案及思路:

1.写个拦截器拦截用户请求,之后正则表达式去过滤RequestBody和RequestURL部分包含恶意攻击的代码。

2.具体代码如下


/*** Project Name: * File Name:SecurityFilter.java* Description: TODO* Copyright: Copyright (c) 2017 * Company:* * @author * @date Mar 19, 2019 4:01:44 PM* @version * @see* @since */import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.regex.Pattern;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ReadListener;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;import org.apache.commons.io.IOUtils;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.stereotype.Component;/*** ClassName: SecurityFilter Description: filter all request* * @author * @version* @see* @since*/
@Component
@ServletComponentScan
public class SecurityFilter implements Filter
{/*** Title: init Description:* * @param filterConfig* @throws ServletException*             (describe the param)* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)*/@Overridepublic void init(FilterConfig filterConfig) throws ServletException{}/*** Title: doFilter Description:* * @param request* @param response* @param chain* @throws IOException* @throws ServletException*             (describe the param)* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,*      javax.servlet.FilterChain)*/@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException{HttpServletRequest req = new XSSRequestWrapper((HttpServletRequest) request);HttpServletResponse resp = (HttpServletResponse) response;//clean xss attack code in reqeuest bodycleanRequestBody(req, resp);//clean xss attack code in request urlcleanRequsetUrl(req, resp, chain);}/*** Title: destroy Description:(describe the param)* * @see javax.servlet.Filter#destroy()*/@Overridepublic void destroy(){}public class XSSRequestWrapper extends HttpServletRequestWrapper{private final byte[] body;public XSSRequestWrapper(HttpServletRequest request) throws IOException{super(request);body = IOUtils.toString(request.getReader()).getBytes(Charset.forName("UTF-8"));}@Overridepublic BufferedReader getReader() throws IOException{return new BufferedReader(new InputStreamReader(getInputStream()));}@Overridepublic ServletInputStream getInputStream() throws IOException{final ByteArrayInputStream bais = new ByteArrayInputStream(body);return new ServletInputStream(){@Overridepublic int read() throws IOException{return bais.read();}@Overridepublic boolean isFinished(){return false;}@Overridepublic boolean isReady(){return false;}@Overridepublic void setReadListener(ReadListener listener){}};}}/*** * Title: stripXSS Description: replace potential xss attack code with ""* * @exception @see* @since {@inheritDoc}* @param value* @return*/private String stripXSS(String value){if (null != value && !value.isEmpty()){// Avoid anything between script tagsPattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);value = scriptPattern.matcher(value).replaceAll("");scriptPattern = Pattern.compile("src=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");// Remove any lonesome </script> tagscriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");scriptPattern = Pattern.compile("alert\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);value = scriptPattern.matcher(value).replaceAll("");// Remove any lonesome <script ...> tagscriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");// Avoid eval(...) expressionsscriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");// Avoid expression(...) expressions/** scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE |* Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll("");*/// Avoid javascript:... expressionsscriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// Avoid vbscript:... expressionsscriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// Avoid onload= expressionsscriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");}return value;}/*** * Title: cleanRequsetUrl Description: clean xss attack code of request url.* * @exception @see* @since {@inheritDoc}* @param req* @param resp* @param chain* @throws IOException* @throws ServletException*/private void cleanRequsetUrl(HttpServletRequest req, HttpServletResponse resp, FilterChain chain)throws IOException, ServletException{StringBuffer sb = new StringBuffer();String uri = req.getRequestURI();String queryString = req.getQueryString();String url = uri;if (null != queryString && !queryString.isEmpty()){url = sb.append(uri).append(SecurityConstants.QUESTION_MARK).append(queryString).toString();}String cleanUrl = stripXSS(url);if (null != cleanUrl && !cleanUrl.equals(url)){req.getRequestDispatcher(cleanUrl).forward(req, resp);}else{chain.doFilter(req, resp);}}/*** * Title: cleanRequestBody Description: clean XSS Attack code of request body* * @exception @see* @since {@inheritDoc}* @param req* @param resp* @throws IOException*/private String cleanRequestBody(HttpServletRequest req, HttpServletResponse resp) throws IOException{Reader reader = req.getReader();String payload = IOUtils.toString(reader);String body = stripXSS(payload);System.out.println("body is\n" + body);resp.getWriter().write(body);return body;}
}

遇到的问题:

1.The request was rejected because the URL was not normalized

原因:

1.1 是因为请求地址里面包含"//"

解决方案:

1.2 使用该方法获取请求地址:String uri = req.getRequestURI();而不用req.getRequestURL()。之后我们使用相对路径重新发一个请求即可:req.getRequestDispatcher(cleanUrl).forward(req, resp);

2.为什么不适用resp.sendRedirect(cleanUrl);

原因:

2.1 该方法一般情况下只能重新发一个GET请求,不能发POST或者PUT. 想用该方法发POST请求出去可以自己用JSP实现一个表格,较为麻烦。

解决方案:

用req.getRequestDispatcher(cleanUrl).forward(req, resp); 替换它。

PS:除了过滤用户输入的数据处理XSS以外,还可以 只要遇到XSS Code直接抛错出去,具体怎么处理需要根据需求来。

这篇关于防止XSS Attack攻击的解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1090687

相关文章

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

C#文件复制异常:"未能找到文件"的解决方案与预防措施

《C#文件复制异常:未能找到文件的解决方案与预防措施》在C#开发中,文件操作是基础中的基础,但有时最基础的File.Copy()方法也会抛出令人困惑的异常,当targetFilePath设置为D:2... 目录一个看似简单的文件操作问题问题重现与错误分析错误代码示例错误信息根本原因分析全面解决方案1. 确保

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

SpringBoot3匹配Mybatis3的错误与解决方案

《SpringBoot3匹配Mybatis3的错误与解决方案》文章指出SpringBoot3与MyBatis3兼容性问题,因未更新MyBatis-Plus依赖至SpringBoot3专用坐标,导致类冲... 目录SpringBoot3匹配MyBATis3的错误与解决mybatis在SpringBoot3如果

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

Python 字符串裁切与提取全面且实用的解决方案

《Python字符串裁切与提取全面且实用的解决方案》本文梳理了Python字符串处理方法,涵盖基础切片、split/partition分割、正则匹配及结构化数据解析(如BeautifulSoup、j... 目录python 字符串裁切与提取的完整指南 基础切片方法1. 使用切片操作符[start:end]2

Linux部署中的文件大小写问题的解决方案

《Linux部署中的文件大小写问题的解决方案》在本地开发环境(Windows/macOS)一切正常,但部署到Linux服务器后出现模块加载错误,核心原因是Linux文件系统严格区分大小写,所以本文给大... 目录问题背景解决方案配置要求问题背景在本地开发环境(Windows/MACOS)一切正常,但部署到

Java中InputStream重复使用问题的几种解决方案

《Java中InputStream重复使用问题的几种解决方案》在Java开发中,InputStream是用于读取字节流的类,在许多场景下,我们可能需要重复读取InputStream中的数据,这篇文章主... 目录前言1. 使用mark()和reset()方法(适用于支持标记的流)2. 将流内容缓存到字节数组

MybatisPlus中removeById删除数据库未变解决方案

《MybatisPlus中removeById删除数据库未变解决方案》MyBatisPlus中,removeById需实体类标注@TableId注解以识别数据库主键,若字段名不一致,应通过value属... 目录MyBATisPlus中removeBypythonId删除数据库未变removeById(Se

创建springBoot模块没有目录结构的解决方案

《创建springBoot模块没有目录结构的解决方案》2023版IntelliJIDEA创建模块时可能出现目录结构识别错误,导致文件显示异常,解决方法为选择模块后点击确认,重新校准项目结构设置,确保源... 目录创建spChina编程ringBoot模块没有目录结构解决方案总结创建springBoot模块没有目录