SpringBoot +esapi 实现防止xss攻击
maven 集成:
<!-- 预防XSS攻击工具 --><dependency><groupId>org.owasp.esapi</groupId><artifactId>esapi</artifactId><version>2.2.0.0</version></dependency><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.13.1</version></dependency>
过滤器
/*** 描述 : 跨站请求防范** @author**/@WebFilter(filterName = "xssFilter", urlPatterns = "/*", asyncSupported = true)public class XssFilter implements Filter {/*** 描述 : 日志*/private static final Logger LOGGER = LoggerFactory.getLogger(XssFilter.class);@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);System.out.println("进入XSS过滤器............");chain.doFilter(xssRequest, response);System.out.println("过滤器XSS执行完......................");}@Overridepublic void destroy() {}}
/*** @author xk* @create -11-25 9:14* @desc* esapi 防止xss攻击过滤器配置类**/@Configurationpublic class XSSFilterConfig {@Beanpublic FilterRegistrationBean filterRegistrationBean() {FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(xssFilter());registration.addUrlPatterns("/*");registration.addInitParameter("paramName", "paramValue");registration.setName("xssFilter");return registration;}/*** 创建一个bean* @return*/@Bean(name = "xssFilter")public Filter xssFilter() {return new XssFilter();}
/*** 描述 : 针对请求参数采用具体规则正则匹配* @author**/public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {super(servletRequest);}@Overridepublic String[] getParameterValues(String parameter) {String[] values = super.getParameterValues(parameter);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;}@Overridepublic String getParameter(String parameter) {String value = super.getParameter(parameter);if (value == null) {return null;}return cleanXSS(value);}@Overridepublic String getHeader(String name) {String value = super.getHeader(name);if (value == null) {return null;}return value;}// private String cleanXSS(String value) {//// //You'll need to remove the spaces from the html entities below//// value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");//// value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");//// value = value.replaceAll("'", "& #39;");//// value = value.replaceAll("eval\\((.*)\\)", "");//// value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");//// value = value.replaceAll("script", "");//// return value;//// }private String cleanXSS(String value) {if (value != null) {// 推荐使用ESAPI库来避免脚本攻击value = ESAPI.encoder().canonicalize(value);// 避免空字符串value = value.replaceAll("", "");// 避免script 标签Pattern scriptPattern = compile("<script>(.*?)</script>", CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");//避免src形式的表达式//scriptPattern = compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", CASE_INSENSITIVE | MULTILINE | DOTALL);//value = scriptPattern.matcher(value).replaceAll("");scriptPattern = compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", CASE_INSENSITIVE | MULTILINE | DOTALL);value = scriptPattern.matcher(value).replaceAll("");// 删除单个的 </script> 标签scriptPattern = compile("</script>", CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// 删除单个的<script ...> 标签scriptPattern = compile("<script(.*?)>", CASE_INSENSITIVE | MULTILINE | DOTALL);value = scriptPattern.matcher(value).replaceAll("");// 避免 eval(...) 形式表达式scriptPattern = compile("eval\\((.*?)\\)", CASE_INSENSITIVE | MULTILINE | DOTALL);value = scriptPattern.matcher(value).replaceAll("");// 避免 expression(...) 表达式scriptPattern = compile("expression\\((.*?)\\)", CASE_INSENSITIVE | MULTILINE | DOTALL);value = scriptPattern.matcher(value).replaceAll("");// 避免 javascript: 表达式scriptPattern = compile("javascript:", CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// 避免 vbscript: 表达式scriptPattern = compile("vbscript:", CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// 避免 onload= 表达式scriptPattern = compile("onload(.*?)=", CASE_INSENSITIVE | MULTILINE | DOTALL);value = scriptPattern.matcher(value).replaceAll("");// 避免 onXX= 表达式scriptPattern = compile("on.*(.*?)=", CASE_INSENSITIVE | MULTILINE | DOTALL);value = scriptPattern.matcher(value).replaceAll("");}return value;}
配置文件 ESAPI.properties
# 是否要打印配置属性,默认为trueESAPI.printProperties=trueESAPI.AccessControl=org.owasp.esapi.reference.DefaultAccessControllerESAPI.Authenticator=org.owasp.esapi.reference.FileBasedAuthenticatorESAPI.Encoder=org.owasp.esapi.reference.DefaultEncoderESAPI.Encryptor=org.owasp.esapi.reference.crypto.JavaEncryptorESAPI.Executor=org.owasp.esapi.reference.DefaultExecutorESAPI.HTTPUtilities=org.owasp.esapi.reference.DefaultHTTPUtilitiesESAPI.IntrusionDetector=org.owasp.esapi.reference.DefaultIntrusionDetectorESAPI.Logger=org.owasp.esapi.reference.JavaLogFactoryESAPI.Randomizer=org.owasp.esapi.reference.DefaultRandomizerESAPI.Validator=org.owasp.esapi.reference.DefaultValidator#===========================================================================# ESAPI EncoderEncoder.AllowMultipleEncoding=falseEncoder.AllowMixedEncoding=falseEncoder.DefaultCodecList=HTMLEntityCodec,PercentCodec,JavaScriptCodec#===========================================================================# ESAPI 加密模块Encryptor.PreferredJCEProvider=Encryptor.EncryptionAlgorithm=AESEncryptor.CipherTransformation=AES/CBC/bined_modes=GCM,CCM,IAPM,EAX,OCB,CWCEncryptor.cipher_modes.additional_allowed=CBCEncryptor.EncryptionKeyLength=128Encryptor.ChooseIVMethod=randomEncryptor.fixedIV=0x000102030405060708090a0b0c0d0e0fEncryptor.CipherText.useMAC=trueEncryptor.PlainText.overwrite=trueEncryptor.HashAlgorithm=SHA-512Encryptor.HashIterations=1024Encryptor.DigitalSignatureAlgorithm=SHA1withDSAEncryptor.DigitalSignatureKeyLength=1024Encryptor.RandomAlgorithm=SHA1PRNGEncryptor.CharacterEncoding=UTF-8Encryptor.KDF.PRF=HmacSHA256#===========================================================================# ESAPI Http工具HttpUtilities.UploadDir=C:\\ESAPI\\testUploadHttpUtilities.UploadTempDir=C:\\temp# Force flags on cookies, if you use HttpUtilities to set cookiesHttpUtilities.ForceHttpOnlySession=falseHttpUtilities.ForceSecureSession=falseHttpUtilities.ForceHttpOnlyCookies=trueHttpUtilities.ForceSecureCookies=true# Maximum size of HTTP headersHttpUtilities.MaxHeaderSize=4096# File upload configurationHttpUtilities.ApprovedUploadExtensions=.zip,.pdf,.doc,.docx,.ppt,.pptx,.tar,.gz,.tgz,.rar,.war,.jar,.ear,.xls,.rtf,.properties,.java,.class,.txt,.xml,.jsp,.jsf,.exe,.dllHttpUtilities.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 ExecutorExecutor.WorkingDirectory=Executor.ApprovedExecutables=#===========================================================================# ESAPI Logging# Set the application name if these logs are combined with other applicationsLogger.ApplicationName=ExampleApplication# If you use an HTML log viewer that does not properly HTML escape log data, you can set LogEncodingRequired to trueLogger.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 DetectionIntrusionDetector.Disable=falseIntrusionDetector.event.test.count=2IntrusionDetector.event.test.interval=10IntrusionDetector.event.test.actions=disable,.owasp.esapi.errors.IntrusionException.count=.owasp.esapi.errors.IntrusionException.interval=.owasp.esapi.errors.IntrusionException.actions=log,disable,.owasp.esapi.errors.IntegrityException.count=.owasp.esapi.errors.IntegrityException.interval=.owasp.esapi.errors.IntegrityException.actions=log,disable,.owasp.esapi.errors.AuthenticationHostException.count=.owasp.esapi.errors.AuthenticationHostException.interval=.owasp.esapi.errors.AuthenticationHostException.actions=log,logout#===========================================================================# ESAPI 校验器#校验器的配置文件Validator.ConfigurationFile=validation.properties# Validators used by ESAPIValidator.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 supportedValidator.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 inputValidator.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}$validation.properties
源码链接:
链接: 源码链接.请戳!!!!!!!