Xss防護(hù) esapi

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

?ESAPI.properties

# 是否要打印配置屬性,默認(rèn)為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 校驗(yàn)器

#校驗(yàn)器的配置文件

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


# 校驗(yàn)?zāi)硞€(gè)字段的正則表達(dá)式

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}$



新增依賴


<!-- 預(yù)防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請(qǐng)求參數(shù)字符過濾或合法性校驗(yàn) -->

<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攻擊防護(hù)過濾器

*

* @author xuanwenhao

* @email 836786010@qq.com

* 時(shí)間 :? 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("進(jìn)入XSS過濾器............");

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

log.info("過濾器XSS執(zhí)行完......................");

}

@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攻擊防護(hù)過濾器

*

* @author xuanwenhao

* @email 836786010@qq.com

* 時(shí)間 :? 2019年6月25日

*/

public class XssHttpServletRequestWrapperextends HttpServletRequestWrapper {

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

public XssHttpServletRequestWrapper(HttpServletRequest request) {

super(request);

}

/**

? ? * 對(duì)數(shù)組參數(shù)進(jìn)行特殊字符過濾

? ? */

? ? @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;

}

/**

? ? * 對(duì)參數(shù)中特殊字符進(jìn)行過濾

? ? */

? ? @Override

? ? public String getParameter(String name) {

String value =super.getParameter(name);

if (value ==null) {

return null;

}

return cleanXSS(value);

}

/**

? ? * 對(duì)集合參數(shù)進(jìn)行特殊字符過濾

? ? */

? ? @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("過濾前傳遞參數(shù):" + value);

if (value !=null) {

/**

? ? ? ? ? ? //推薦使用ESAPI庫來避免腳本攻擊,value = ESAPI.encoder().canonicalize(value); // 避免空字符串

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

**/

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

? ? ? ? ? ? // 避免script 標(biāo)簽

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

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

// 避免src形式的表達(dá)式

? ? ? ? ? ? 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("");

// 刪除單個(gè)的 </script> 標(biāo)簽

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

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

// 刪除單個(gè)的<script ...> 標(biāo)簽

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

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

// 避免 eval(...) 形式表達(dá)式

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

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

// 避免 e-xpression(...) 表達(dá)式

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

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

// 避免 javascript: 表達(dá)式

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

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

// 避免 vbscript:表達(dá)式

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

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

// 避免 onload= 表達(dá)式

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

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

//移除特殊標(biāo)簽

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

// 避免 onXX= 表達(dá)式

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

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

}

log.info("過濾后傳遞參數(shù):" + value);

return value;

}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末挺益,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子缕贡,更是在濱河造成了極大的恐慌匣掸,老刑警劉巖逢慌,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稀颁,死亡現(xiàn)場離奇詭異崩瓤,居然都是意外死亡恕齐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門剃斧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來轨香,“玉大人,你說我怎么就攤上這事幼东”廴荩” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵根蟹,是天一觀的道長策橘。 經(jīng)常有香客問我,道長娜亿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任蚌堵,我火速辦了婚禮买决,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吼畏。我一直安慰自己督赤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布泻蚊。 她就那樣靜靜地躺著躲舌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪性雄。 梳的紋絲不亂的頭發(fā)上没卸,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音秒旋,去河邊找鬼约计。 笑死,一個(gè)胖子當(dāng)著我的面吹牛迁筛,可吹牛的內(nèi)容都是我干的煤蚌。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼尉桩!你這毒婦竟也來了筒占?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤蜘犁,失蹤者是張志新(化名)和其女友劉穎翰苫,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沽瘦,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡革骨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了析恋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片良哲。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖助隧,靈堂內(nèi)的尸體忽然破棺而出筑凫,到底是詐尸還是另有隱情,我是刑警寧澤并村,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布巍实,位于F島的核電站,受9級(jí)特大地震影響哩牍,放射性物質(zhì)發(fā)生泄漏棚潦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一膝昆、第九天 我趴在偏房一處隱蔽的房頂上張望丸边。 院中可真熱鬧,春花似錦荚孵、人聲如沸妹窖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽骄呼。三九已至,卻和暖如春判没,著一層夾襖步出監(jiān)牢的瞬間蜓萄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工澄峰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留绕德,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓摊阀,卻偏偏與公主長得像耻蛇,于是被迫代替她去往敵國和親踪蹬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容