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 之前就了解过这方面的知识,但是没有系统地总结.今天在这总结一下,也让 ...
随机推荐
- Filter 起航 编程式配置 压缩响应 日志过滤器
[编程式配置]可以用web.xml配置替换 @WebListenerpublic class FilterListenerConfigurator implements ServletContextL ...
- SSR搭建服务器
SSR搭建服务器一站式教程:https://ssr.tools/252
- 【网络爬虫入门03】爬虫解析利器beautifulSoup模块的基本应用
[网络爬虫入门03]爬虫解析利器beautifulSoup模块的基本应用 1.引言 网络爬虫最终的目的就是过滤选取网络信息,因此最重要的就是解析器了,其性能的优劣直接决定这网络爬虫的速度和效率.B ...
- vue-CLI踩坑记
vue init webpack vue-demo 使用 windows 7 DOS命令行和gitbash都有选择和实际选择结果不一致的问题, DOS命令行只在 Vue build有问题, gitba ...
- Linux常用命令(二)查找当前ip地址
查询当地ip地址(没错就是这么短): /sbin/ifconfig
- Create C++ Class
创建“目标物体”,是世界场景中的一个物体,当玩家经过时,可以将它拾起,并带至某处 选择Actor为父类,创建FPSObjectiveActor类 注:点击公有按钮就会把头文件放入Public文件夹 ...
- Spark架构与作业执行流程简介
https://www.cnblogs.com/shenh062326/p/3658543.html
- Hibernate Transformers之三种结果转换说明
在hibernate使用的过程中,我们通常需要对结果进行解释.Hibernate为我们提供了以下3种查询结果解释方法: Transformers.ALIAS_TO_ENTITY_MAP //把输出结果 ...
- 线程变量---ThreadLocal类
用处:保存线程的独立变量.对一个线程类(继承自Thread) 思想:如果一个资源会引起线程竞争,那就为每一个线程配置一个资源.相比于synchronized是一种空间换时间的策略 当使用ThreadL ...
- oracle-----视图/物化视图
什么是视图 视图(view),也称虚表, 不占用物理空间,这个也是相对概念,因为视图本身的定义语句还是要存储在数据字典里的. 视图只有逻辑定义.每次使用的时候,只是重新执行SQL. 视图是从一个或多个 ...