JAVA覆写Request过滤XSS跨站脚本攻击
注:本文非本人原著。
demo的地址:链接:http://pan.baidu.com/s/1miEmHMo 密码:k5ca
如何过滤Xss跨站脚本攻击,我想,Xss跨站脚本攻击令人为之头疼。为什么呢。
尤其是有富文本编辑器的产品。xss可能出现在http的head,不说别的,新浪多次出现。
xss可以出现在post数据的正文。图片的url。
于是各种Xss横行,如今Xss跨站脚本漏洞的流行程度甚至超过了当年的sql。
那么对于JAVA语言,如何防御呢。
笔者分享一个思路:所有的web项目,所有的参数都是request获得。
不管是json合适xml又或者post表单数据。甚至图片、文件等等都是如此。
那么,如果对request做个手脚。是不是就可以过滤xss了呢。
正是如此。
如下分享代码。网络上也有类似的过滤器,但不如笔者这份强悍。
package com.blog.web.base.wrapper; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern; import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper; /**
* 覆写Request方法,过滤XSS恶意脚本
*
* @author WebSOS
* @time 2015-06-09
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { HttpServletRequest orgRequest = null; public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
orgRequest = request;
} /**
* 覆盖getParameter方法,将参数名和参数值都做xss过滤。
*/
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value != null) {
value = xssEncode(value);
}
return value;
} /**
* 覆盖getHeader方法,将参数名和参数值都做xss过滤。 避免部分head操作引发的xss
*/
@Override
public String getHeader(String name) { String value = super.getHeader(name);
if (value != null) {
value = xssEncode(value);
}
return value;
} /**
* 覆盖getHeaderNames方法,避免穷举head参数名引发的xss
*/
@Override
public Enumeration<String> getHeaderNames() { Enumeration<String> headNames = super.getHeaderNames();
String value = null;
List<String> values = new ArrayList<String>();
while (headNames.hasMoreElements()) {
try {
value = (String) headNames.nextElement();
if (value == null) {
continue;
}
value = xssEncode(value);
values.add(value);
} catch (Exception e) {
e.printStackTrace();
}
}
if (values.isEmpty()) {
return null;
}
headNames = new XssEnumerator(0, values.size(), values);
return headNames;
} /**
* 覆盖getParameterNames方法,避免穷举参数名引发的xss
*/
@Override
public Enumeration<String> getParameterNames() {
Enumeration<String> paraNames = super.getParameterNames();
if (paraNames == null) {
return null;
}
String value = null;
List<String> values = new ArrayList<String>();
while (paraNames.hasMoreElements()) {
try {
value = (String) paraNames.nextElement();
if (value == null) {
continue;
}
value = xssEncode(value);
values.add(value);
} catch (Exception e) {
e.printStackTrace();
}
}
if (values.isEmpty()) {
return null;
}
paraNames = new XssEnumerator(0, values.size(), values);
return paraNames;
} /**
* 覆盖getParameterMap方法,避免穷举参数名或值引发的xss
*/
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> map = super.getParameterMap();
Map<String, String[]> paraMap = new HashMap<String, String[]>();
if (map == null) {
return null;
}
String[] values = null;
for (String key : map.keySet()) {
try {
values = map.get(key);
if (values != null) {
for (int i = 0; i < values.length; i++) {
try {
values[i] = xssEncode(values[i]);
} catch (Exception e) {
e.printStackTrace();
}
}
}
paraMap.put(xssEncode(key), values);
} catch (Exception e) {
e.printStackTrace();
}
}
return paraMap;
} /**
* 覆盖getInputStream方法,避免上传文件出现的xss或脚本代码
*/
@Override
public ServletInputStream getInputStream() throws IOException {
XSSServletInputStream xssServletInputStream = new XSSServletInputStream();
ServletInputStream inputStream = orgRequest.getInputStream(); ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
try {
int ch;
while ((ch = inputStream.read()) != -1) {
byteStream.write(ch);
}
} finally {
inputStream.close();
}
xssServletInputStream.stream = new ByteArrayInputStream(xssEncode(
new String(byteStream.toByteArray(), "iso-8859-1")).getBytes(
"iso-8859-1"));
return xssServletInputStream;
} /**
* 将容易引起xss漏洞的字符清理掉
*
* @param s
* @return
*/
private static String xssEncode(String value) {
if (value != null) {
/*
* value = value.replace("<", "<"); value = value.replace(">",
* ">");
*/
// 如需开启富文本请撤销以下注释 Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>",
Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("</script>",
Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<img.*?on.*?=.*?>",
Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<script(.*?)>",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
| Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("eval\\((.*?)\\)",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
| Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("expression\\((.*?)\\)",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
| Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("expression\\((.*?)\\)",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
| Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("javascript:",
Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("vbscript:",
Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("onload(.*?)=",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
| Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<%.*?java.*?%>", Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<jsp:.*?>.*?</jsp:.*?>",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
| Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<meta.*?>",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
| Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll(""); }
return value;
} /**
* 获取最原始的request
*
* @return
*/
public HttpServletRequest getOrgRequest() { return orgRequest;
} /**
* 获取最原始的request的静态方法
*
* @return
*/
public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
if (req instanceof XssHttpServletRequestWrapper) {
return ((XssHttpServletRequestWrapper) req).getOrgRequest();
} return req;
} private class XSSServletInputStream extends ServletInputStream {
private InputStream stream; @Override
public int read() throws IOException {
return stream.read();
}
} private class XssEnumerator implements Enumeration<String> {
int count; // 计数器
int length; // 存储的数组的长度
List<String> dataArray; // 存储数据数组的引用 XssEnumerator(int count, int length, List<String> dataArray) {
this.count = count;
this.length = length;
this.dataArray = dataArray; } public boolean hasMoreElements() {
return (count < length);
} public String nextElement() {
return dataArray.get(count++);
}
} public static void main(String[] args) {
Enumeration<String> paraNames = (Enumeration<String>) new ArrayList();
}
}
JAVA覆写Request过滤XSS跨站脚本攻击的更多相关文章
- PHP进行安全字段和防止XSS跨站脚本攻击过滤(通用版)
废话不多说,直接贴使用方法和代码: 使用方式:1)写在公共方法里面,随时调用即可.2)写入类文件,使用是include_once 即可 代码: /* 进行安全字段和xss跨站脚本攻击过滤(通用版) - ...
- 个人网站对xss跨站脚本攻击(重点是富文本编辑器情况)和sql注入攻击的防范
昨天本博客受到了xss跨站脚本注入攻击,3分钟攻陷--其实攻击者进攻的手法很简单,没啥技术含量.只能感叹自己之前竟然完全没防范. 这是数据库里留下的一些记录.最后那人弄了一个无限循环弹出框的脚本,估计 ...
- xss(跨站脚本攻击),crsf(跨站请求伪造),xssf
我们常说的网络安全其实应该包括以下三方面的安全: 1.机密性,比如用户的隐私被窃取,帐号被盗,常见的方式是木马. 2.完整性,比如数据的完整,举个例子,康熙传位十四子,被当时四阿哥篡改遗诏:传位于四子 ...
- 初窥XSS跨站脚本攻击
XSS跨站脚本攻击的分类 一. 反射型XSS跨站脚本攻击 二. 存储型XSS跨站脚本攻击 三. 基于DOM的XSS跨站脚本攻击 1.反射性XSS 经过后端,不经过数据库 2.储存型XSS 经过后端,经 ...
- web应用程序安全攻防---sql注入和xss跨站脚本攻击
kali视频学习请看 http://www.cnblogs.com/lidong20179210/p/8909569.html 博文主要内容包括两种常见的web攻击 sql注入 XSS跨站脚本攻击 代 ...
- spring-boot-plus XSS跨站脚本攻击处理
XSS跨站脚本攻击处理 XSS:Cross Site Scripting 跨站脚本攻击(XSS),是目前最普遍的Web应用安全漏洞.这类漏洞能够使得攻击者嵌入恶意脚本代码到正常用户会访问到的页面中,当 ...
- 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 之前就了解过这方面的知识,但是没有系统地总结.今天在这总结一下,也让 ...
随机推荐
- springboot使用jpa+mongodb时,xxxRepository不能Autowired的问题
springboot启动类: @SpringBootApplication public class MainApp { public static void main(String[] args) ...
- Java Map在遍历过程中删除元素
Java中的Map如果在遍历过程中要删除元素,除非通过迭代器自己的remove()方法,否则就会导致抛出ConcurrentModificationException异常.JDK文档中是这么描述的: ...
- JDK1.8HashMap源码解读
package java.util; import sun.misc.SharedSecrets; import java.io.IOException; import java.io.Invalid ...
- nodejs设置允许跨域
//设置服务器跨域权限app.use(function (req, res, next) { res.header("Access-Control-Allow-Origin" ...
- JAVA进阶2
间歇性混吃等死,持续性踌躇满志系列-------------第2天 1.父类子类继承(注:一个JAVA源文件中只能有一个public类,public 类的名字必须和这个编译单元的文件名完全相同,包括大 ...
- Python笔记(二)查找重复元素
一.查找数列重复元素---count() >>> list = [,,,,,,,,,,,] >>> set = set(list) >>> for ...
- CrackME 2011 # 2 逆向练习解题思路
CrackME 2011 # 2 逆向练习解题思路 做题背景: 从朋友那里得到一道逆向题名字叫package,作为小菜的我当然要看一看啦,这名字辨识度太低我就按照运行的名字改成CrackME 2011 ...
- Javascript - ExtJs - 常用方法和属性
常用方法和属性(Common methods and attributes) ExtJs中的对象 Ext.Component Ext组件对象,表示一个可渲染的组件. Ext.dom.Element E ...
- 解决Ubuntu 18.04中文输入法的问题,安装搜狗拼音
首先安装fcitx一.检测是否安装fcitx首先检测是否有fcitx,因为搜狗拼音依赖fcitx> fcitx提示:程序“fcitx”尚未安装. 您可以使用以下命令安装:> sudo ap ...
- 获取异步API数据
异步操作应该是以前学习 ajax 时才被明确提及,就目前的理解,同步就是同一时间只能做一件事,如果使用 ajax同步模式,则代码会卡在 xhr.send() 这里,只有请求响应的过程全部完成了才会执行 ...