xss和csrf 防御
CSRF攻击原理及防御:https://www.cnblogs.com/shytong/p/5308667.html
CSRF 攻击的应对之道:https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/
拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
XSS
一个目标资源可以指定多个过滤器,过滤器的执行顺序是在web.xml文件中的部署顺序:
1.web.xml配置filter
1.1配置要拦截的url的格式
1.2配置拦截后的处理类
<filter>
<filter-name>XSSFilter</filter-name>
<filter-class>com.jd.ihotel.pc.webapp.filters.NewXssFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XSSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
一个filter可被多个mapping使用:
<filter>
<filter-name>authority</filter-name>
<filter-class>com.util.AuthorityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>authority</filter-name>
<url-pattern>/pages/genbill/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>authority</filter-name>
<url-pattern>/pages/cmm/*</url-pattern>
</filter-mapping>
2.配置依赖:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
新建:实现Filter类是初始化,过滤,销毁三个方法必须都实现(初始化和销毁可以是空方法,过滤方法中chain.doFilter的参数是装饰者模式的http请求对象和普通的http响应对象)
NewXssFilter类
过滤方法中新建一个request过滤对象(装饰者模式),以便可以对request的参数进行更改(过滤)
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class NewXssFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(new NewXssHttpServletRequestWraper(
(HttpServletRequest)request), response);//对request和response进行过滤
}
@Override
public void destroy() {
}
}
新建NewXssHttpServletRequestWraper类
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class NewXssHttpServletRequestWraper extends HttpServletRequestWrapper {
public NewXssHttpServletRequestWraper(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
return clearXss(super.getParameter(name));
}
@Override
public String getHeader(String name) {
return clearXss(super.getHeader(name));
}
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values == null) {
return null;
}
String[] newValues = new String[values.length];
for (int i = 0; i < values.length; i++) {
newValues[i] = clearXss(values[i]);
}
return newValues;
}
/**
* 处理字符转义
*
* @param value
* @return
*/
private String clearXss(String value) {
if (value == null || "".equals(value)) {
return value;
}
value = value
.replaceAll("'","")
.replaceAll("\'","")
.replaceAll("`","")
//.replaceAll("\"","“")
.replaceAll("<","")
.replaceAll(">","")
.replaceAll("\\(","(")
.replaceAll("\\)",")")
//.replaceAll("&","&")
.replaceAll("eval","")
.replaceAll("java","")
.replaceAll("script","")
.replaceAll("alert","")
.replaceAll("prompt","");
value = value.replaceAll("eval\\((.*)\\)", "");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']",
"\"\"");
return value;
}
}
下面的代码配置的过滤器必须有吗?作用是?
<filter>
<filter-name>XssEscape</filter-name>
<filter-class>com.jd.ihotel.pc.webapp.filters.XssFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XssEscape</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
也可以简答粗暴不用过滤器这么写:
private String stripXSS(String value) {
if (value != null) {
value = value.replaceAll("<", "<").replaceAll(">", ">");
value = value.replaceAll("\\(", "(").replaceAll("\\)", ")");
value = value.replaceAll("'", "'");
value = value.replaceAll("eval\\((.*)\\)", "");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
value = value.replaceAll("script", "");
value = value.replaceAll("%", "");
value = value.replaceAll(";", "");
}
return value;
}
如果项目中使用了Spring框架,那么,很多过滤器都不用自己来写了,Spring为我们写好了一些常用的过滤器。下面我们就以字符编码的
过滤器CharacterEncodingFilter为例,来看一下Spring框架下,如果配置过滤器。
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
CSRF:访问受信网站A并在本地产生cookie,不登出A的情况访问不受信网站B(即使浏览器关闭,A的cookie不一定立即过期或会话结束)
http://www.cnblogs.com/shanyou/p/5038794.html
1.web.xml中配置springMVC:
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-web-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
2.springMVC配置中配置拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/submitOrder.html" />
<mvc:mapping path="/ihtrade/unpaidCancel.html"/>
<mvc:mapping path="/ihtrade/cancel.html"/>
<bean class="com.jd.ihtrade.core.intercepter.CheckRefferIntercepter" />
</mvc:interceptor>
</mvc:interceptors>
</beans>
3.新建拦截器里配置的类:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URI;
public class CheckRefferIntercepter implements HandlerInterceptor{
private Logger logger = LoggerFactory.getLogger(CheckRefferIntercepter.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws
Exception {
String referer = request.getHeader("referer");
StringBuffer requestURL = request.getRequestURL();
if(referer == null || referer.isEmpty()) {
return false ;
}
try{
if (referer.contains("?")){
referer = referer.substring(0, referer.indexOf("?"));
}
URI referUri = new URI(referer);
String domain = referUri.getHost();
logger.info("请求目的地URL:{}来源URL:{}验证:{}",requestURL,referer,domain);
if(domain != null){
if(
domain.endsWith("360buy.com")
|| domain.endsWith("jd.com")
|| domain.endsWith("jd.net")
|| domain.endsWith("jd.hk")
) {
return true;
}
}
} catch (Exception e){
logger.error("--invalid uri--" + referer, e);
return false ;
}
return false ;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
可使用拦截器验证token来避免攻击:
http://www.360doc.com/content/18/0223/11/31784658_731672172.shtml
token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 token 给前端。前端可以在每次请求的时候带上 token 证明自己的合法地位。
zz:https://blog.csdn.net/u010287873/article/details/80769762