概念
xss攻击:全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。
xss攻击测试
//web环境
//表单输入框输入以下攻击脚本,提交表单,可测试简单脚本攻击:
"/> <script>alert(document.cookie);</script><!--
"/><script>window.open("http://ncna2.com:9050/bwp/login.do?theAction=login¶m=")</script><!--
xss攻击解决方案
1.使用拦截器,拦截携带敏感字符请求
2.使用过滤器实现,过滤敏感字符,这里只介绍filter
2.1web.xml配置
<filter>
<filter-name>xssAndSQLFilter</filter-name>
<filter-class>*.XSSFilter</filter-class>
<init-param>
<param-name>excludeCSSandSQLs</param-name>
<param-value>para_value;theAction;password;userNosStr;userNos.user_no;url;icon;tlist;jobdirt;remark;REMARK;ename;packagename;filepath;urlpath;role.name;email;warning_email_content;ids</param-value>
</init-param>
<init-param>
<param-name>rejectCSSandSQLs</param-name>
<param-value>script;truncate;insert;select;delete;update;';";=;{;}; or ;(;);alert;confirm;cookie;|;$;+;/;,</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>xssAndSQLFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
2.2filter内部实现
public class XSSFilter implements Filter {
private static final Logger log=LoggerFactory.getLogger(XSSFilter.class);
/**
* 排除部分参数key不做过滤
*/
private static List<String> excludeCSSandSQLs = new ArrayList<String>();
/**
* 预防xss和sql注入黑名单参数值value
*/
private static List<String> rejectCSSandSQLs = new ArrayList<String>();
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//不过滤的请求参数key
String[] excludeCSSandSQLs = filterConfig.getInitParameter("excludeCSSandSQLs").trim().split(";");
Collections.addAll(this.excludeCSSandSQLs, excludeCSSandSQLs);
//过滤的参数value
String str = filterConfig.getInitParameter("rejectCSSandSQLs") + ";<;>;%;&";
String[] rejectCSSandSQLs = str.split(";");
Collections.addAll(this.rejectCSSandSQLs, rejectCSSandSQLs);
this.rejectCSSandSQLs.add(";");
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest) arg0;
HttpServletResponse response = (HttpServletResponse) arg1;
//HttpSession session = request.getSession();
String pathInfo = request.getPathInfo() == null ? "" : request.getPathInfo();
String url = request.getServletPath() + pathInfo;
//String uri = request.getRequestURI();
//boolean isNoticeUrl = false;
//1.获取请求所有参数,校验防止SQL注入,防止XSS漏洞
Enumeration<?> params = request.getParameterNames();
String paramN = null;
while (params.hasMoreElements()) {
paramN = (String) params.nextElement();
String paramVale = request.getParameter(paramN);
if (!paramN.toLowerCase().contains("password")) {
log.info(paramN + "==" + paramVale);
}
//排除部分不做过滤的参数key 同时 校验xss或者sql攻击敏感关键词
if(!excludeCSSandSQLs.contains(paramN) && checkSQLInject(paramVale, url)){
//返回错误信息页面
request.setAttribute("errMsg", "xss或sql攻击拦截,包含敏感字符" + paramVale);
request.getRequestDispatcher("/WEB-INF/xsserrorInfo.jsp").forward(request, response);
break;
}
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
/**
* 检查是否存在非法字符,防止SQL注入
* @param str 被检查的字符串
* @param url 请求url
* @return ture-字符串中存在非法字符,false-不存在非法字符
*/
public static boolean checkSQLInject(String str, String url) {
if (StringTool.isNullOrEmpty(str)) {
// 如果传入空串则认为不存在非法字符
return false;
}
for (String field : rejectCSSandSQLs) {
if (str.indexOf(field) >= 0) {
if (!field.toLowerCase().contains("password")) {
log.info("xss或者sql注入防攻击拦截url:" + url + ",原因:特殊字符,传入str=" + str + ",包含特殊字符:" + field);
}
return true;
}
}
return false;
}
}