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 之前就了解过这方面的知识,但是没有系统地总结.今天在这总结一下,也让 ...
随机推荐
- Servlet 起航 文件上传 中文文件名下载
@WebServlet(name = "ticketServlet",urlPatterns = {"/tickets"},loadOnStartup = 1) ...
- Microsoft Windows .Reg File Dialog Box Message Spoofing 0day
Microsoft Windows .Reg文件对话框消息欺骗 0day 概述 扩展名为.reg的文件是Windows注册表中使用的注册文件.这些文件可以包含hives.密钥和值..reg文件可以在文 ...
- visual studio属性管理器
位于 视图->其它窗口 项目配置属性,这个项目的属性别的项目也需要的时候可以把属性页复制到新项目. 以及配置单个项目的不同构建方案
- call apply bind 区别?
call apply bind 区别? 例:定义一个计算器,没绑定bind的为公共计算器,call可以调用,绑定bind的为私人计算器,别人调用不了, //ps:用bind绑定的call强制作借用不好 ...
- Java基础03-12_对象比较
对象比较 如果说现在有两个数字要判断是否相等,可以使用"=="完成 如果是字符串要判断是否相等使用"equals()" 但是如果说现在有一个自定义的类,要想判断 ...
- webwork框架
以前都没有用过WebWork这个框架,只是听说过.没想到现在要用,所以就自学了一下.做了个小例子给大家分享下中间遇到的苦难和经验. 准备工作:首先要去下载WebWork框架的开发包.我用的2.2.6版 ...
- jq的stop
jQuery stop() 方法用于停止动画或效果,在它们完成之前. stop() 方法适用于所有 jQuery 效果函数,包括滑动.淡入淡出和自定义动画. $(selector).stop(stop ...
- 【blog】谷歌浏览器如何设置编码
解释 55.0.2883.75 版本之后的chrome的更多工具菜单项里就没有编码设置了,理由据说是使用率比较低,促进网页编码规范.google 真是脑抽了,普通用户也许很少遇到默认编码错误显示出现乱 ...
- mysql 案例 ~ mysql字符集详解
一 谈谈mysql常见的字符集问题 二 字符集统一 1 character_set_server 2 character_set_client 3 java/php等连接字符集 4 chara ...
- python3编码(encode,decode)
python3默认编码为unicode,由str类型进行表示.二进制数据使用byte类型表示. 字符串通过编码转换成字节码,字节码通过解码成为字符串 encode:str --> bytes d ...