1、存储型xss漏洞
系统由于未对参数过滤,导致可以存储html特殊标签,且返回的数据未经处理显示在web页面中导致存在存储型xss,攻击者可利用xss对用户发起鱼叉攻击获取cookie进入系统。为解决该问题,创建全局过滤器,涉及的类及步骤如下:
1)XssFilter.java

package com.chinacreator.c2.filter.xss;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;/*** xss过滤*/
@WebFilter(filterName = "XSSFilter", urlPatterns = "/*")
@Order(2)
public class XSSFilter implements Filter {//不拦截的地址private List<String> excludedList = new ArrayList<String>();public static Logger log = LoggerFactory.getLogger(XSSFilter.class);@Overridepublic void init(FilterConfig config) throws ServletException {/** 这里只处理了不拦截的url地址,如果想不拦截某个字段,比如富文本字段,* 需要自己在XssHttpServletRequestWrapper类中去添加逻辑*/excludedList.add("/proxy/aip/v1/currentappmenus");excludedList.add("/proxy/aip/v1/permissions/verify");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);HttpServletRequest req = (HttpServletRequest) request;if ("POST".equals(req.getMethod().toUpperCase())) {String url = xssRequest.getServletPath();if(isExcluded(url)){chain.doFilter(request, response);}else{//使用XSS过滤log.info("使用XSS过滤");chain.doFilter(xssRequest, response);}} else {chain.doFilter(request, response);}}@Overridepublic void destroy() {}/*** 是否不拦截* @param url 请求地址* @return   true不拦截,false拦截*/private boolean isExcluded(String url){if(StringUtils.isBlank(url)){return false;}for (String excluded : excludedList) {if(url.indexOf(excluded) > -1){return true;}}return false;}}

2)XssHttpServletRequestWrapper.java

package com.chinacreator.c2.filter.xss;import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.LinkedHashMap;
import java.util.Map;import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;public class XssHttpServletRequestWrapper  extends HttpServletRequestWrapper {// 没被包装过的HttpServletRequest(特殊场景,需求自己过滤)HttpServletRequest orgRequest;// html过滤private final static HTMLFilter htmlFilter = new HTMLFilter();public XssHttpServletRequestWrapper(HttpServletRequest request) {super(request);orgRequest = request;}/*** 过滤json参数*/@Overridepublic ServletInputStream getInputStream() throws IOException {String contentType = super.getHeader(HttpHeaders.CONTENT_TYPE);//非json类型,直接返回if(!(MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(contentType) || MediaType.APPLICATION_JSON_UTF8_VALUE.equalsIgnoreCase(contentType))){return super.getInputStream();}//为空,直接返回String json = IOUtils.toString(super.getInputStream(), "utf-8");if (StringUtils.isBlank(json)) {return super.getInputStream();}//xss过滤json =xssEncode(json);json = StringEscapeUtils.unescapeHtml4(json);final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("utf-8"));return new ServletInputStream() {@Overridepublic boolean isFinished() {return true;}@Overridepublic boolean isReady() {return true;}@Overridepublic void setReadListener(ReadListener readListener) {}@Overridepublic int read() throws IOException {return bis.read();}};}@Overridepublic String getParameter(String name) {String value = super.getParameter(xssEncode(name));if (StringUtils.isNotBlank(value)) {value =xssEncode(value);}return StringEscapeUtils.unescapeHtml4(value);}@Overridepublic String[] getParameterValues(String name) {String[] parameters = super.getParameterValues(name);if (parameters == null || parameters.length == 0) {return null;}for (int i = 0; i < parameters.length; i++) {parameters[i] = xssEncode(parameters[i]);parameters[i] = StringEscapeUtils.unescapeHtml4(parameters[i]);}return parameters;}@Overridepublic Map<String, String[]> getParameterMap() {Map<String, String[]> map = new LinkedHashMap<>();Map<String, String[]> parameters = super.getParameterMap();for (String key : parameters.keySet()) {String[] values = parameters.get(key);for (int i = 0; i < values.length; i++) {values[i] = xssEncode(values[i]);values[i] = StringEscapeUtils.unescapeHtml4(values[i]);}map.put(key, values);}return map;}@Overridepublic String getHeader(String name) {String value = super.getHeader(xssEncode(name));if (StringUtils.isNotBlank(value)) {value = xssEncode(value);}return StringEscapeUtils.unescapeHtml4(value);}private String xssEncode(String input) {return htmlFilter.filter(input);}/*** 获取最原始的request*/public HttpServletRequest getOrgRequest() {return orgRequest;}/*** 获取最原始的request*/public static HttpServletRequest getOrgRequest(HttpServletRequest request) {if (request instanceof XssHttpServletRequestWrapper) {return ((XssHttpServletRequestWrapper) request).getOrgRequest();}return request;}}

3)HTMLFilter.java

package com.chinacreator.c2.filter.xss;import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* HTML filtering utility for protecting against XSS (Cross Site Scripting).
*
* This code is licensed LGPLv3
*
* This code is a Java port of the original work in PHP by Cal Hendersen.
* http://code.iamcal.com/php/lib_filter/
*
* The trickiest part of the translation was handling the differences in regex handling
* between PHP and Java.  These resources were helpful in the process:
*
* http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html
* http://us2.php.net/manual/en/reference.pcre.pattern.modifiers.php
* http://www.regular-expressions.info/modifiers.html
*
* A note on naming conventions: instance variables are prefixed with a "v"; global
* constants are in all caps.
*
* Sample use:
* String input = ...
* String clean = new HTMLFilter().filter( input );
*
* The class is not thread safe. Create a new instance if in doubt.
*
* If you find bugs or have suggestions on improvement (especially regarding
* performance), please contact us.  The latest version of this
* source, and our contact details, can be found at http://xss-html-filter.sf.net
*
* @author Joseph O'Connell
* @author Cal Hendersen
* @author Michael Semb Wever
*/
public class HTMLFilter {/** regex flag union representing /si modifiers in php **/private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL;private static final Pattern P_COMMENTS = Pattern.compile("<!--(.*?)-->", Pattern.DOTALL);private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI);private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL);private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI);private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI);private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI);private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI);private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI);private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?");private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?");private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?");private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))");private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL);private static final Pattern P_END_ARROW = Pattern.compile("^>");private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)");private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)");private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)");private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)");private static final Pattern P_AMP = Pattern.compile("&");private static final Pattern P_QUOTE = Pattern.compile("\"");private static final Pattern P_LEFT_ARROW = Pattern.compile("<");private static final Pattern P_RIGHT_ARROW = Pattern.compile(">");private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>");private static final Pattern P_DOUBLE_QUOT = Pattern.compile("&quot;");// @xxx could grow large... maybe use sesat's ReferenceMapprivate static final ConcurrentMap<String,Pattern> P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<String, Pattern>();private static final ConcurrentMap<String,Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<String, Pattern>();/** set of allowed html elements, along with allowed attributes for each element **/private final Map<String, List<String>> vAllowed;/** counts of open tags for each (allowable) html element **/private final Map<String, Integer> vTagCounts = new HashMap<String, Integer>();/** html elements which must always be self-closing (e.g. "<img />") **/private final String[] vSelfClosingTags;/** html elements which must always have separate opening and closing tags (e.g. "<b></b>") **/private final String[] vNeedClosingTags;/** set of disallowed html elements **/private final String[] vDisallowed;/** attributes which should be checked for valid protocols **/private final String[] vProtocolAtts;/** allowed protocols **/private final String[] vAllowedProtocols;/** tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />") **/private final String[] vRemoveBlanks;/** entities allowed within html markup **/private final String[] vAllowedEntities;/** flag determining whether comments are allowed in input String. */private final boolean stripComment;private final boolean encodeQuotes;private boolean vDebug = false;/*** flag determining whether to try to make tags when presented with "unbalanced"* angle brackets (e.g. "<b text </b>" becomes "<b> text </b>").  If set to false,* unbalanced angle brackets will be html escaped.*/private final boolean alwaysMakeTags;/** Default constructor.**/public HTMLFilter() {vAllowed = new HashMap<>();final ArrayList<String> a_atts = new ArrayList<String>();a_atts.add("href");a_atts.add("target");vAllowed.put("a", a_atts);final ArrayList<String> img_atts = new ArrayList<String>();img_atts.add("src");img_atts.add("width");img_atts.add("height");img_atts.add("alt");vAllowed.put("img", img_atts);final ArrayList<String> no_atts = new ArrayList<String>();vAllowed.put("b", no_atts);vAllowed.put("strong", no_atts);vAllowed.put("i", no_atts);vAllowed.put("em", no_atts);vSelfClosingTags = new String[]{"img"};vNeedClosingTags = new String[]{"a", "b", "strong", "i", "em"};vDisallowed = new String[]{};vAllowedProtocols = new String[]{"http", "mailto", "https"}; // no ftp.vProtocolAtts = new String[]{"src", "href"};vRemoveBlanks = new String[]{"a", "b", "strong", "i", "em"};vAllowedEntities = new String[]{"amp", "gt", "lt", "quot"};stripComment = true;encodeQuotes = true;alwaysMakeTags = true;}/** Set debug flag to true. Otherwise use default settings. See the default constructor.** @param debug turn debug on with a true argument*/public HTMLFilter(final boolean debug) {this();vDebug = debug;}/** Map-parameter configurable constructor.** @param conf map containing configuration. keys match field names.*/public HTMLFilter(final Map<String,Object> conf) {assert conf.containsKey("vAllowed") : "configuration requires vAllowed";assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags";assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags";assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed";assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols";assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts";assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks";assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities";vAllowed = Collections.unmodifiableMap((HashMap<String, List<String>>) conf.get("vAllowed"));vSelfClosingTags = (String[]) conf.get("vSelfClosingTags");vNeedClosingTags = (String[]) conf.get("vNeedClosingTags");vDisallowed = (String[]) conf.get("vDisallowed");vAllowedProtocols = (String[]) conf.get("vAllowedProtocols");vProtocolAtts = (String[]) conf.get("vProtocolAtts");vRemoveBlanks = (String[]) conf.get("vRemoveBlanks");vAllowedEntities = (String[]) conf.get("vAllowedEntities");stripComment =  conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true;encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true;alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true;}private void reset() {vTagCounts.clear();}private void debug(final String msg) {if (vDebug) {Logger.getAnonymousLogger().info(msg);}}//---------------------------------------------------------------// my versions of some PHP library functionspublic static String chr(final int decimal) {return String.valueOf((char) decimal);}public static String htmlSpecialChars(final String s) {String result = s;result = regexReplace(P_AMP, "&amp;", result);result = regexReplace(P_QUOTE, "&quot;", result);result = regexReplace(P_LEFT_ARROW, "&lt;", result);result = regexReplace(P_RIGHT_ARROW, "&gt;", result);return result;}//---------------------------------------------------------------/*** given a user submitted input String, filter out any invalid or restricted* html.** @param input text (i.e. submitted by a user) than may contain html* @return "clean" version of input, with only valid, whitelisted html elements allowed*/public String filter(final String input) {reset();String s = input;debug("************************************************");debug("              INPUT: " + input);s = escapeComments(s);debug("     escapeComments: " + s);s = balanceHTML(s);debug("        balanceHTML: " + s);s = checkTags(s);debug("          checkTags: " + s);s = processRemoveBlanks(s);debug("processRemoveBlanks: " + s);s = validateEntities(s);debug("    validateEntites: " + s);debug("************************************************\n\n");return s;}public boolean isAlwaysMakeTags(){return alwaysMakeTags;}public boolean isStripComments(){return stripComment;}private String escapeComments(final String s) {final Matcher m = P_COMMENTS.matcher(s);final StringBuffer buf = new StringBuffer();if (m.find()) {final String match = m.group(1); //(.*?)m.appendReplacement(buf, Matcher.quoteReplacement("<!--" + htmlSpecialChars(match) + "-->"));}m.appendTail(buf);return buf.toString();}private String balanceHTML(String s) {if (alwaysMakeTags) {//// try and form html//s = regexReplace(P_END_ARROW, "", s);s = regexReplace(P_BODY_TO_END, "<$1>", s);s = regexReplace(P_XML_CONTENT, "$1<$2", s);} else {//// escape stray brackets//s = regexReplace(P_STRAY_LEFT_ARROW, "&lt;$1", s);s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2&gt;<", s);//// the last regexp causes '<>' entities to appear// (we need to do a lookahead assertion so that the last bracket can// be used in the next pass of the regexp)//s = regexReplace(P_BOTH_ARROWS, "", s);}return s;}private String checkTags(String s) {Matcher m = P_TAGS.matcher(s);final StringBuffer buf = new StringBuffer();while (m.find()) {String replaceStr = m.group(1);replaceStr = processTag(replaceStr);m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr));}m.appendTail(buf);s = buf.toString();// these get tallied in processTag// (remember to reset before subsequent calls to filter method)for (String key : vTagCounts.keySet()) {for (int ii = 0; ii < vTagCounts.get(key); ii++) {s += "</" + key + ">";}}return s;}private String processRemoveBlanks(final String s) {String result = s;for (String tag : vRemoveBlanks) {if(!P_REMOVE_PAIR_BLANKS.containsKey(tag)){P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?></" + tag + ">"));}result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result);if(!P_REMOVE_SELF_BLANKS.containsKey(tag)){P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>"));}result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result);}return result;}private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) {Matcher m = regex_pattern.matcher(s);return m.replaceAll(replacement);}private String processTag(final String s) {// ending tagsMatcher m = P_END_TAG.matcher(s);if (m.find()) {final String name = m.group(1).toLowerCase();if (allowed(name)) {if (!inArray(name, vSelfClosingTags)) {if (vTagCounts.containsKey(name)) {vTagCounts.put(name, vTagCounts.get(name) - 1);return "</" + name + ">";}}}}// starting tagsm = P_START_TAG.matcher(s);if (m.find()) {final String name = m.group(1).toLowerCase();final String body = m.group(2);String ending = m.group(3);//debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" );if (allowed(name)) {String params = "";final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body);final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body);final List<String> paramNames = new ArrayList<String>();final List<String> paramValues = new ArrayList<String>();while (m2.find()) {paramNames.add(m2.group(1)); //([a-z0-9]+)paramValues.add(m2.group(3)); //(.*?)}while (m3.find()) {paramNames.add(m3.group(1)); //([a-z0-9]+)paramValues.add(m3.group(3)); //([^\"\\s']+)}String paramName, paramValue;for (int ii = 0; ii < paramNames.size(); ii++) {paramName = paramNames.get(ii).toLowerCase();paramValue = paramValues.get(ii);//          debug( "paramName='" + paramName + "'" );
//          debug( "paramValue='" + paramValue + "'" );
//          debug( "allowed? " + vAllowed.get( name ).contains( paramName ) );if (allowedAttribute(name, paramName)) {if (inArray(paramName, vProtocolAtts)) {paramValue = processParamProtocol(paramValue);}params += " " + paramName + "=\"" + paramValue + "\"";}}if (inArray(name, vSelfClosingTags)) {ending = " /";}if (inArray(name, vNeedClosingTags)) {ending = "";}if (ending == null || ending.length() < 1) {if (vTagCounts.containsKey(name)) {vTagCounts.put(name, vTagCounts.get(name) + 1);} else {vTagCounts.put(name, 1);}} else {ending = " /";}return "<" + name + params + ending + ">";} else {return "";}}// commentsm = P_COMMENT.matcher(s);if (!stripComment && m.find()) {return  "<" + m.group() + ">";}return "";}private String processParamProtocol(String s) {s = decodeEntities(s);final Matcher m = P_PROTOCOL.matcher(s);if (m.find()) {final String protocol = m.group(1);if (!inArray(protocol, vAllowedProtocols)) {// bad protocol, turn into local anchor link insteads = "#" + s.substring(protocol.length() + 1, s.length());if (s.startsWith("#//")) {s = "#" + s.substring(3, s.length());}}}return s;}private String decodeEntities(String s) {StringBuffer buf = new StringBuffer();Matcher m = P_ENTITY.matcher(s);while (m.find()) {final String match = m.group(1);final int decimal = Integer.decode(match).intValue();m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));}m.appendTail(buf);s = buf.toString();buf = new StringBuffer();m = P_ENTITY_UNICODE.matcher(s);while (m.find()) {final String match = m.group(1);final int decimal = Integer.valueOf(match, 16).intValue();m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));}m.appendTail(buf);s = buf.toString();buf = new StringBuffer();m = P_ENCODE.matcher(s);while (m.find()) {final String match = m.group(1);final int decimal = Integer.valueOf(match, 16).intValue();m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));}m.appendTail(buf);s = buf.toString();s = validateEntities(s);return s;}private String validateEntities(final String s) {StringBuffer buf = new StringBuffer();// validate entities throughout the stringMatcher m = P_VALID_ENTITIES.matcher(s);while (m.find()) {final String one = m.group(1); //([^&;]*)final String two = m.group(2); //(?=(;|&|$))m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two)));}m.appendTail(buf);return encodeQuotes(buf.toString());}private String encodeQuotes(final String s){if(encodeQuotes){StringBuffer buf = new StringBuffer();Matcher m = P_VALID_QUOTES.matcher(s);while (m.find()) {final String one = m.group(1); //(>|^)final String two = m.group(2); //([^<]+?)final String three = m.group(3); //(<|$)m.appendReplacement(buf, Matcher.quoteReplacement(one + regexReplace(P_QUOTE, "&quot;", two) + three));}m.appendTail(buf);return buf.toString();}else{return s;}}private String checkEntity(final String preamble, final String term) {return ";".equals(term) && isValidEntity(preamble)? '&' + preamble: "&amp;" + preamble;}private boolean isValidEntity(final String entity) {return inArray(entity, vAllowedEntities);}private static boolean inArray(final String s, final String[] array) {for (String item : array) {if (item != null && item.equals(s)) {return true;}}return false;}private boolean allowed(final String name) {return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed);}private boolean allowedAttribute(final String name, final String paramName) {return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName));}
}

4)启动类注册过滤器

@ServletComponentScan(basePackages = {"com.chinacreator.c2.filter"})

2、解决sql注入漏洞

package com.chinacreator.c2.filter.sql;import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;import com.alibaba.fastjson.JSON;@WebFilter(filterName = "SQLFilter", urlPatterns = "/*")
@Order(1)
public class SQLFilter implements Filter {public static Logger log = LoggerFactory.getLogger(SQLFilter.class);private static final String SQL_REG_EXP = ".*(\\b(select|insert|into|update|delete|from|where|and|or|trancate" +"|drop|execute|like|grant|use|union|order|by)\\b).*";@Overridepublic void destroy() {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest request, ServletResponse res, FilterChain chain)throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;Map<String, Object> parameterMap = new HashMap<>();parameterMap =getParameterMap(parameterMap, req);// 正则校验是否有SQL关键字for (Entry<String, Object> entry : parameterMap.entrySet()) {Object value = entry.getValue();if (value != null) {boolean isValid = isSqlInject(value.toString(), res);if (!isValid) {return;}}}chain.doFilter(req, res);}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// TODO Auto-generated method stub}private Map<String, Object> getParameterMap(Map<String, Object> paramMap, HttpServletRequest request) {// 1.POST请求获取参数if ("POST".equals(request.getMethod().toUpperCase())) {} else {Enumeration<?> params = request.getParameterNames();String paramN = null;while (params.hasMoreElements()) {paramN = (String) params.nextElement();String paramValue = request.getParameter(paramN);paramMap.put(paramN, paramValue);}}return paramMap;}private boolean isSqlInject(String value, ServletResponse servletResponse) throws IOException {if (null != value) {if(value.toLowerCase().matches(SQL_REG_EXP) || checkSQLInject(value)) {log.info("入参中有非法字符: " + value);HttpServletResponse response = (HttpServletResponse) servletResponse;Map<String, String> responseMap = new HashMap<>();// 匹配到非法字符,立即返回responseMap.put("code", "999");responseMap.put("message","入参中有非法字符");response.setContentType("application/json;charset=UTF-8");response.setStatus(HttpStatus.OK.value());response.getWriter().write(JSON.toJSONString(responseMap));response.getWriter().flush();response.getWriter().close();return false;}}return true;}/*** * 检查是否存在非法字符,防止js脚本注入* * @param str*            被检查的字符串* @return ture-字符串中存在非法字符,false-不存在非法字符*/public boolean checkSQLInject(String str) {if (StringUtils.isEmpty(str)) {return false;// 如果传入空串则认为不存在非法字符}List<String> blackNameList=new ArrayList<String>();blackNameList.add("script");blackNameList.add("mid");blackNameList.add("master");blackNameList.add("truncate");/*blackNameList.add("insert");blackNameList.add("select");blackNameList.add("delete");blackNameList.add("update");*/blackNameList.add("iframe");blackNameList.add("referer");blackNameList.add("onreadystatechange");blackNameList.add("alert");blackNameList.add("atestu");blackNameList.add("xss");blackNameList.add("svg");blackNameList.add("confirm");blackNameList.add("prompt");blackNameList.add("onload");blackNameList.add("onmouseover");blackNameList.add("sleep");blackNameList.add("remove");blackNameList.add("onfocus");blackNameList.add("onerror");blackNameList.add("<");blackNameList.add(">");blackNameList.add("(");blackNameList.add(")");blackNameList.add("'");blackNameList.add(";");/*blackNameList.add(",");*/blackNameList.add("\\(");blackNameList.add("eval\\\\((.*)\\\\)");blackNameList.add("%3C");blackNameList.add("%3");blackNameList.add("%3C/");blackNameList.add("%3E");blackNameList.add("%22%3E%3C");blackNameList.add("%2e%2e");blackNameList.add("win.ini");blackNameList.add("boot.ini");blackNameList.add("[\\\\\\\"\\\\\\'][\\\\s]*javascript:(.*)[\\\\\\\"\\\\\\']");// 判断黑名单str = str.toLowerCase(); // sql不区分大小写
if(str.contains("{") && str.contains("}")) {return false;}for(String blackString: blackNameList) {if(str.indexOf(blackString) > -1) {log.info("参数中含有黑名单的字符:" + blackString);return true;}}/*if (blackNameList.contains(str)) {log.info("sql不区分大小写:" + str);return true;}*/return false;}}

为解决存储型xss和sql注入漏洞,创建对应的全局过滤器相关推荐

  1. 网络渗透测试实验三——XSS和SQL注入

    网络渗透测试实验三--XSS和SQL注入 实验目的 了解什么是XSS:了解XSS攻击实施,理解防御XSS攻击的方法:了解SQL注入的基本原理:掌握PHP脚本访问MySQL数据库的基本方法:掌握程序设计 ...

  2. 二次注入 php,dedecms20140606 二次注入+存储型xss

    红色目录有exp,注入比较鸡肋 目录 dede/soft_edit.php, 存储型XSS漏洞        2 include /memberlogin.class.php 会员笔名二次注入    ...

  3. XSS注入(1)-两个简单测试理解反射型xss注入和存储型xss注入

    XSS注入(1)-两个例子理解反射型xss注入和存储型xss注入 XSS全称 Cross Site Script,为使与css语言重名,所以我们将其称为xss跨站脚本攻击.它指的是恶意攻击者往Web页 ...

  4. WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案

    对web安全方面的知识非常薄弱,这篇文章把Xss跨站攻击和sql注入的相关知识整理了下,希望大家多多提意见. 对于防止sql注入发生,我只用过简单拼接字符串的注入及参数化查询,可以说没什么好经验,为避 ...

  5. (超详细)XSS和SQL注入-网络渗透测试实验三

    文章目录 前言 实验目的 系统环境 网络环境 实验工具 XSS部分:利用Beef劫持被攻击者客户端浏览器. 实验环境搭建. 环境搭建参考网站 搭建IIS时踩的坑: 1.利用AWVS扫描留言簿网站,发现 ...

  6. 从php角度分析预防xss和Sql注入

    引言 从php角度分析预防xss和Sql注入,是因为php对这方面做了很好的支持. XSS 概念: Xss即跨站脚本攻击,指攻击者在网页中嵌入恶意脚本程序(一般由html,css,js组成),当用户打 ...

  7. DVWA通关--存储型XSS(XSS (Stored))

    目录 LOW 通关步骤 源码分析 MEDIUM 通关步骤 源码分析 HIGH 通关步骤 源码分析 IMPOSSIBLE 源码分析 存储型XSS也叫持久型XSS,从名字就知道特征是攻击代码会被存储在数据 ...

  8. DVWA系列之21 存储型XSS分析与利用

    存储型跨站可以将XSS语句直接写入到数据库中,因而相比反射型跨站的利用价值要更大. 在DVWA中选择XSS stored,这里提供了一个类型留言本的页面. 我们首先查看low级别的代码,这里提供了$m ...

  9. Web攻防之XSS,CSRF,SQL注入

    摘要:对Web服务器的攻击也可以说是形形色色.种类繁多,常见的有挂马.SQL注入.缓冲区溢出.嗅探.利用IIS等针对Webserver漏洞进行攻击.本文结合WEB TOP10漏洞中常见的SQL注入,跨 ...

最新文章

  1. 写给Java程序员的Java虚拟机学习指南
  2. PcGAN:一种用于一次学习的噪声鲁棒条件生成对抗网络∗
  3. MyBatis简介——半自动的持久化层框架(SQL映射框架)|| 支持定制化sql
  4. MDCC 2016:网易云信直击移动IM之痛
  5. Centos7.5常用firewall-cmd命令集
  6. 关于windows server 2016 更新CVE-2020-1472漏洞补丁的问题
  7. java中的缓冲流BufferedWriter和BufferedReader
  8. php基础之常量(系统常量,自定义常量)
  9. 利用python爬虫进行彼岸网图库图片的抓取(bs4)
  10. 【Racket】安装与入门
  11. vue3 组件naiveui报错: Extraneous non-props attributes (class) were passed to component but could not be
  12. 2021年安全生产模拟考试(全国特种作业操作证高处作业-高处安装维护拆除模拟考试题库二)安考星
  13. 关于Ubuntu下浏览器不能上网但是能ping通网络的问题
  14. 玩转基因组浏览器之查看gwas结果
  15. 以下对linux中线程描述错误的是,2008年9月全国计算机等级三级PC技术真题
  16. 运动世界校园【夜神模拟器——步频脚本一键导入】
  17. 一阶线性电路暂态分析的三要素法
  18. c语言:判断字符串是否符合手机号码格式
  19. android 开源项目
  20. 【20保研】兰州大学信息科学与工程学院2019年优秀大学生暑期夏令营活动通知...

热门文章

  1. IntelliJ IDEA修改系统缓存目录解决开发Java项目C盘爆满的坑
  2. 基于yolov7开发实践实例分割模型超详细教程
  3. [未]DRN: A Deep Reinforcement Learning Framework for News Recommendation
  4. python里range什么意思_python里range的意思是什么
  5. 游戏测试员—游戏即人生
  6. 20165223 学习基础和C语言基础调查
  7. 国有公房公租房管理系统源代码(vs2015+sql2008)
  8. 使用apache的FTPClient下载特别慢的问题
  9. Python3 解决 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
  10. python_报数游戏_经典考题_四级