前不久刚做的项目挂到阿里服务器上进行测试,遇到了跨站攻击的问题,阿里云反馈攻击日志如下图:

攻击者书写html脚本,通过调用后台接口方法,攻击访问数据库想提取数据。

开始前让我们先熟悉下什么是跨域攻击,以下资料参考的是阿里的技术运维指南(链接:https://help.aliyun.com/knowledge_detail/37444.html)
漏洞描述
跨站脚本攻击(Cross-site scripting,简称XSS攻击),通常发生在客户端,可被用于进行隐私窃取、钓鱼欺骗、密码偷取、恶意代码传播等攻击行为。XSS攻击使用到的技术主要为HTML和Javascript脚本,也包括VBScript和ActionScript脚本等。
恶意攻击者将对客户端有危害的代码放到服务器上作为一个网页内容,用户不经意打开此网页时,这些恶意代码会注入到用户的浏览器中并执行,从而使用户受到攻击。一般而言,利用跨站脚本攻击,攻击者可窃取会话cookie,从而获得用户的隐私信息,甚至包括密码等敏感信息。
鉴于本人是一枚java 程序员,所有定位了解决方案是:Java的xssprotect(Open Source Library),有兴趣的童鞋可以了解下xssproject,这里不说了,因为自己试下了,达不到自己的要求,而且XSS防御的总体思路是:对输入(和URL参数)进行过滤,对输出进行编码。而我需要的是拒绝请求到达等等,这里写下自己对于跨站攻击的处理方案:
1.JAVA FILTER
2.登陆验证
首先说下FILTER,我的目的是将这些异常请求拒绝在门外,而XSS攻击使用到的技术主要为HTML和Javascript脚本,我们的思路可以从这方面下手,即拦截html脚本字符,将request请求中包含这些字符的请求全部杜绝在门外。

2.登陆验证
这个可能和各自的项目有关系,思路是验证当前用户是否登陆,没有登陆,返回404页面

下面贴下第一种FILTER的处理办法的代码
web.xm配置
<filter> <filter-name>XSSFilter</filter-name> <filter-class>xss.XSSCheckFilter</filter-class> <init-param> <param-name>errorPath</param-name> <param-value>/abnormal/404.htm</param-value> </init-param> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>XSSFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
java filter 代码
package xss; import java.io.IOException; import java.util.Enumeration; 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 javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; public class XSSCheckFilter implements Filter { private String encode = "UTF-8";// 默认UTF-8编码 private FilterConfig config; // 出错跳转的目的地 private static String errorPath; // 不进行拦截的url private static String[] excludePaths; // 需要拦截的JS字符关键字 private static String[] safeless = { "<script", "</script", "<iframe", "</iframe", "<frame", "</frame", "set-cookie", "%3cscript", "%3c/script", "%3ciframe", "%3c/iframe", "%3cframe", "%3c/frame", "src=\"javascript:", "<body", "</body", "%3cbody", "%3c/body", "alert", "onmouseover", "onload", "prompt" }; public void doFilter(ServletRequest req, ServletResponse resp,FilterChain filterChain) throws IOException, ServletException { // 设置request编码 req.setCharacterEncoding(encode); // 设置相应信息 //response.setContentType("text/html;charset=" + encode); //response.setCharacterEncoding(encode); Enumeration params = req.getParameterNames(); HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; boolean isSafe = true; String requestUrl = request.getRequestURI(); if (isSafe(requestUrl)) { requestUrl = requestUrl.substring(requestUrl.indexOf("/")); if (!excludeUrl(requestUrl)) { while (params.hasMoreElements()) { String cache = req.getParameter((String) params.nextElement()); if (StringUtils.isNotBlank(cache)) { if (!isSafe(cache)) { isSafe = false; break; } } } } }else { isSafe = false; } if (!isSafe) { request.setAttribute("err", "您输入的参数有非法字符,请输入正确的参数!"); System.out.println("您请求的参数中有非法字符,请输入正确的参数!"); request.getRequestDispatcher(errorPath).forward(request, response); return; } filterChain.doFilter(req, resp); } private static boolean isSafe(String str) { if (StringUtils.isNotBlank(str)) { for (String s : safeless) { if (str.toLowerCase().contains(s)) { return false; } } } return true; } private boolean excludeUrl(String url) { if (excludePaths != null && excludePaths.length > 0) { for (String path : excludePaths) { if (url.toLowerCase().equals(path)) { return true; } } } return false; } public void destroy() { } public void init(FilterConfig config) throws ServletException { this.config = config; errorPath = config.getInitParameter("errorPath"); String excludePath = config.getInitParameter("excludePaths"); if (StringUtils.isNotBlank(excludePath)) { excludePaths = excludePath.split(","); } } }
总结:
当然也有其他方法可以做到防止跨站攻击,这要看我们的需求了,项目中加上了以上两种过滤方式,至今还未再收到攻击,基本是实现了要求。
浙公网安备 33010602011771号