Xss防护 esapi

1.在resource目录下新增配置文件 ESAPI.properties 和validation.properties

 ESAPI.properties

# 是否要打印配置属性,默认为true

ESAPI.printProperties=true

ESAPI.AccessControl=org.owasp.esapi.reference.DefaultAccessController

ESAPI.Authenticator=org.owasp.esapi.reference.FileBasedAuthenticator

ESAPI.Encoder=org.owasp.esapi.reference.DefaultEncoder

ESAPI.Encryptor=org.owasp.esapi.reference.crypto.JavaEncryptor

ESAPI.Executor=org.owasp.esapi.reference.DefaultExecutor

ESAPI.HTTPUtilities=org.owasp.esapi.reference.DefaultHTTPUtilities

ESAPI.IntrusionDetector=org.owasp.esapi.reference.DefaultIntrusionDetector

ESAPI.Logger=org.owasp.esapi.reference.JavaLogFactory

ESAPI.Randomizer=org.owasp.esapi.reference.DefaultRandomizer

ESAPI.Validator=org.owasp.esapi.reference.DefaultValidator

#===========================================================================

# ESAPI Encoder

Encoder.AllowMultipleEncoding=false

Encoder.AllowMixedEncoding=false

Encoder.DefaultCodecList=HTMLEntityCodec,PercentCodec,JavaScriptCodec

#===========================================================================

# ESAPI 加密模块

Encryptor.PreferredJCEProvider=

Encryptor.EncryptionAlgorithm=AES

Encryptor.CipherTransformation=AES/CBC/PKCS5Padding

Encryptor.cipher_modes.combined_modes=GCM,CCM,IAPM,EAX,OCB,CWC

Encryptor.cipher_modes.additional_allowed=CBC

Encryptor.EncryptionKeyLength=128

Encryptor.ChooseIVMethod=random

Encryptor.fixedIV=0x000102030405060708090a0b0c0d0e0f

Encryptor.CipherText.useMAC=true

Encryptor.PlainText.overwrite=true

Encryptor.HashAlgorithm=SHA-512

Encryptor.HashIterations=1024

Encryptor.DigitalSignatureAlgorithm=SHA1withDSA

Encryptor.DigitalSignatureKeyLength=1024

Encryptor.RandomAlgorithm=SHA1PRNG

Encryptor.CharacterEncoding=UTF-8

Encryptor.KDF.PRF=HmacSHA256

#===========================================================================

# ESAPI Http工具

HttpUtilities.UploadDir=C:\\ESAPI\\testUpload

HttpUtilities.UploadTempDir=C:\\temp

# Force flags on cookies, if you use HttpUtilities to set cookies

HttpUtilities.ForceHttpOnlySession=false

HttpUtilities.ForceSecureSession=false

HttpUtilities.ForceHttpOnlyCookies=true

HttpUtilities.ForceSecureCookies=true

# Maximum size of HTTP headers

HttpUtilities.MaxHeaderSize=4096

# File upload configuration

HttpUtilities.ApprovedUploadExtensions=.zip,.pdf,.doc,.docx,.ppt,.pptx,.tar,.gz,.tgz,.rar,.war,.jar,.ear,.xls,.rtf,.properties,.java,.class,.txt,.xml,.jsp,.jsf,.exe,.dll

HttpUtilities.MaxUploadFileBytes=500000000

# Using UTF-8 throughout your stack is highly recommended. That includes your database driver,

# container, and any other technologies you may be using. Failure to do this may expose you

# to Unicode transcoding injection attacks. Use of UTF-8 does not hinder internationalization.

HttpUtilities.ResponseContentType=text/html; charset=UTF-8

# This is the name of the cookie used to represent the HTTP session

# Typically this will be the default "JSESSIONID"

HttpUtilities.HttpSessionIdName=JSESSIONID

#===========================================================================

# ESAPI Executor

Executor.WorkingDirectory=

Executor.ApprovedExecutables=

#===========================================================================

# ESAPI Logging

# Set the application name if these logs are combined with other applications

Logger.ApplicationName=ExampleApplication

# If you use an HTML log viewer that does not properly HTML escape log data, you can set LogEncodingRequired to true

Logger.LogEncodingRequired=false

# Determines whether ESAPI should log the application name. This might be clutter in some single-server/single-app environments.

Logger.LogApplicationName=true

# Determines whether ESAPI should log the server IP and port. This might be clutter in some single-server environments.

Logger.LogServerIP=true

# LogFileName, the name of the logging file. Provide a full directory path (e.g., C:\\ESAPI\\ESAPI_logging_file) if you

# want to place it in a specific directory.

Logger.LogFileName=ESAPI_logging_file

# MaxLogFileSize, the max size (in bytes) of a single log file before it cuts over to a new one (default is 10,000,000)

Logger.MaxLogFileSize=10000000

#===========================================================================

# ESAPI Intrusion Detection

IntrusionDetector.Disable=false

IntrusionDetector.event.test.count=2

IntrusionDetector.event.test.interval=10

IntrusionDetector.event.test.actions=disable,log

IntrusionDetector.org.owasp.esapi.errors.IntrusionException.count=1

IntrusionDetector.org.owasp.esapi.errors.IntrusionException.interval=1

IntrusionDetector.org.owasp.esapi.errors.IntrusionException.actions=log,disable,logout

IntrusionDetector.org.owasp.esapi.errors.IntegrityException.count=10

IntrusionDetector.org.owasp.esapi.errors.IntegrityException.interval=5

IntrusionDetector.org.owasp.esapi.errors.IntegrityException.actions=log,disable,logout

IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.count=2

IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.interval=10

IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.actions=log,logout

#===========================================================================

# ESAPI 校验器

#校验器的配置文件

Validator.ConfigurationFile=validation.properties

# Validators used by ESAPI

Validator.AccountName=^[a-zA-Z0-9]{3,20}$

Validator.SystemCommand=^[a-zA-Z\\-\\/]{1,64}$

Validator.RoleName=^[a-z]{1,20}$

#the word TEST below should be changed to your application

#name - only relative URL's are supported

Validator.Redirect=^\\/test.*$

# Global HTTP Validation Rules

# Values with Base64 encoded data (e.g. encrypted state) will need at least [a-zA-Z0-9\/+=]

Validator.HTTPScheme=^(http|https)$

Validator.HTTPServerName=^[a-zA-Z0-9_.\\-]*$

Validator.HTTPParameterName=^[a-zA-Z0-9_]{1,32}$

Validator.HTTPParameterValue=^[a-zA-Z0-9.\\-\\/+=@_ ]*$

Validator.HTTPCookieName=^[a-zA-Z0-9\\-_]{1,32}$

Validator.HTTPCookieValue=^[a-zA-Z0-9\\-\\/+=_ ]*$

# Note that max header name capped at 150 in SecurityRequestWrapper!

Validator.HTTPHeaderName=^[a-zA-Z0-9\\-_]{1,50}$

Validator.HTTPHeaderValue=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$

Validator.HTTPContextPath=^\\/?[a-zA-Z0-9.\\-\\/_]*$

Validator.HTTPServletPath=^[a-zA-Z0-9.\\-\\/_]*$

Validator.HTTPPath=^[a-zA-Z0-9.\\-_]*$

Validator.HTTPQueryString=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ %]*$

Validator.HTTPURI=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$

Validator.HTTPURL=^.*$

Validator.HTTPJSESSIONID=^[A-Z0-9]{10,30}$

# Validation of file related input

Validator.FileName=^[a-zA-Z0-9!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$

Validator.DirectoryName=^[a-zA-Z0-9:/\\\\!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$

# Validation of dates. Controls whether or not 'lenient' dates are accepted.

# See DataFormat.setLenient(boolean flag) for further details.

Validator.AcceptLenientDates=false



validation.properties


# 校验某个字段的正则表达式

Validator.SafeString=^[.\\p{Alnum}\\p{Space}]{0,1024}$

Validator.Email=^[A-Za-z0-9._%'-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$

Validator.IPAddress=^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

Validator.URL=^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\:\\'\\/\\\\\\+=&%\\$#_]*)?$

Validator.CreditCard=^(\\d{4}[- ]?){3}\\d{4}$

Validator.SSN=^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$



新增依赖


<!-- 预防XSS攻击工具 -->

<dependency>

<groupId>org.owasp.esapi</groupId>

<artifactId>esapi</artifactId>

<version>2.1.0</version>

</dependency>

<dependency>

<groupId>org.jsoup</groupId>

<artifactId>jsoup</artifactId>

<version>1.9.2</version>

</dependency>


在web-xml中新增配置

<!-- URL请求参数字符过滤或合法性校验 -->

<filter>

<filter-name>XssFilter</filter-name>

<filter-class>com.zl.xssFilter.XssFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>XssFilter</filter-name>

<url-pattern>/*</url-pattern>

<dispatcher>REQUEST</dispatcher>

<dispatcher>FORWARD</dispatcher>

</filter-mapping>


新增xssFilter

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import javax.servlet.*;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

/**

* xss攻击防护过滤器

*

* @author xuanwenhao

* @email 836786010@qq.com

* 时间 :  2019年6月25日

*/

public class XssFilterimplements Filter {

private static Loglog = LogFactory.getLog(XssFilter.class);

FilterConfigfilterConfig =null;

@Override

    public void init(FilterConfig filterConfig)throws ServletException {

this.filterConfig = filterConfig;

}

@Override

    public void doFilter(ServletRequest req,

ServletResponse res, FilterChain chain)

throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) req;

HttpServletResponse response = (HttpServletResponse) res;

log.info("进入XSS过滤器............");

chain.doFilter(new XssHttpServletRequestWrapper(request), response);

log.info("过滤器XSS执行完......................");

}

@Override

    public void destroy() {

this.filterConfig =null;

}

}


新增 XssHttpServletRequestWrapper


import java.util.Map;

import java.util.Set;

import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

/**

* xss攻击防护过滤器

*

* @author xuanwenhao

* @email 836786010@qq.com

* 时间 :  2019年6月25日

*/

public class XssHttpServletRequestWrapperextends HttpServletRequestWrapper {

private static Loglog = LogFactory.getLog(XssHttpServletRequestWrapper.class);

public XssHttpServletRequestWrapper(HttpServletRequest request) {

super(request);

}

/**

    * 对数组参数进行特殊字符过滤

    */

    @Override

    public String[] getParameterValues(String name) {

String[] values =super.getParameterValues(name);

if (values ==null) {

return null;

}

int count = values.length;

String[] encodedValues =new String[count];

for (int i =0; i < count; i++) {

encodedValues[i] = cleanXSS(values[i]);

}

return encodedValues;

}

/**

    * 对参数中特殊字符进行过滤

    */

    @Override

    public String getParameter(String name) {

String value =super.getParameter(name);

if (value ==null) {

return null;

}

return cleanXSS(value);

}

/**

    * 对集合参数进行特殊字符过滤

    */

    @Override

    public Map getParameterMap() {

Map reqMap =super.getParameterMap();

Set set = reqMap.keySet();

for (Object s : set) {

//              Object t =((String[]) reqMap.get(s))[0];

//              Object o = cleanXSS((String) t);

//              t=o;

            String[] arr = (String[]) reqMap.get(s);

for (int i =0; i < arr.length; i++) {

String str = arr[i];

arr[i] = cleanXSS(str);

}

}

return reqMap;

}

private String cleanXSS(String value) {

log.info("过滤前传递参数:" + value);

if (value !=null) {

/**

            //推荐使用ESAPI库来避免脚本攻击,value = ESAPI.encoder().canonicalize(value); // 避免空字符串

            value = value.replaceAll(" ", "");

**/

//value = ESAPI.encoder().canonicalize(value);

            // 避免script 标签

            Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);

value = scriptPattern.matcher(value).replaceAll("");

// 避免src形式的表达式

            scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

value = scriptPattern.matcher(value).replaceAll("");

scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

value = scriptPattern.matcher(value).replaceAll("");

// 删除单个的 </script> 标签

            scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);

value = scriptPattern.matcher(value).replaceAll("");

// 删除单个的<script ...> 标签

            scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

value = scriptPattern.matcher(value).replaceAll("");

// 避免 eval(...) 形式表达式

            scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

value = scriptPattern.matcher(value).replaceAll("");

// 避免 e­xpression(...) 表达式

            scriptPattern = Pattern.compile("e­xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

value = scriptPattern.matcher(value).replaceAll("");

// 避免 javascript: 表达式

            scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);

value = scriptPattern.matcher(value).replaceAll("");

// 避免 vbscript:表达式

            scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);

value = scriptPattern.matcher(value).replaceAll("");

// 避免 onload= 表达式

            scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

value = scriptPattern.matcher(value).replaceAll("");

//移除特殊标签

            value = value.replaceAll("<","&lt;").replaceAll(">","&gt;");

// 避免 onXX= 表达式

            scriptPattern = Pattern.compile("on.*(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

value = scriptPattern.matcher(value).replaceAll("");

}

log.info("过滤后传递参数:" + value);

return value;

}

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容