常见web攻击总结( 三 )


Hash加密cookie中csrf_token值
这可能是最简单的解决方案了,因为攻击者不能获得第三方的Cookie(理论上),所以表单中的数据也就构造失败了 。
我采用的hash加密方法是JS实现Java的HashCode方法,得到hash值,这个比较简单 。也可以采用其他的hash算法 。
前端向后台传递hash之后的csrf_token值和cookie中的csrf_token值,后台拿到cookie中的csrf_token值后得到hashCode值然后与前端传过来的值进行比较,一样则通过 。
你有权限删除3号帖子
http://localhost:8081/deletePost.html

常见web攻击总结

文章插图
 
 
B网站的他已经没有权限了
我们通过UserFilter.java给攻击者返回的是403错误,表示服务器理解用户客户端的请求但拒绝处理 。
http://localhost:8082/deletePost.html
常见web攻击总结

文章插图
 
攻击者不能删除4号帖子 。
前端代码:
deletePost.html
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>deletePost</title> <script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript"> function deletePost() { var url = '/post/' + document.getElementById("postId").value; var csrf_token = document.cookie.replace(/(?:(?:^|.*;s*)csrf_tokens*=s*([^;]*).*$)|^.*$/, "$1"); console.log('csrf_token=' + csrf_token); $.ajax({ type: "post",//请求方式 url: url, //发送请求地址 timeout: 30000,//超时时间:30秒 data: { "_method": "delete", "csrf_token": hash(csrf_token) // 对csrf_token进行hash加密 }, dataType: "json",//设置返回数据的格式 success: function (result) { if (result.message == "success") { $("#result").text("删除成功"); } else { $("#result").text("删除失败"); } }, error: function () { //请求出错的处理 $("#result").text("请求出错"); } }); } // javascript的String到int(32位)的hash算法 function hash(str) { var hash = 0; if (str.length == 0) return hash; for (i = 0; i < str.length; i++) { char = str.charCodeAt(i); hash = ((hash << 5) - hash) + char; hash = hash & hash; // Convert to 32bit integer } return hash; } </script></head><body><h3>删除帖子</h3>帖子编号 : <input type="text" id="postId"/><button onclick="deletePost();">deletePost</button><br/><br/><br/><div> <p id="result"></p></div></body></html>后台代码:
UserInterceptor.java
package cn.morethink.interceptor;import cn.morethink.util.JsonUtil;import cn.morethink.util.Result;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.PrintWriter;/** * @author 李文浩 * @date 2018/1/4 */public class UserInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String method = request.getMethod(); System.out.println(method); if (method.equalsIgnoreCase("POST") || method.equalsIgnoreCase("DELETE") || method.equalsIgnoreCase("PUT")) { String csrf_token = request.getParameter("csrf_token"); Cookie[] cookies = request.getCookies(); if (cookies != null && cookies.length > 0 && csrf_token != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals("csrf_token")) { if (Integer.valueOf(csrf_token) == cookie.getValue().hashCode()) { return true; } } } } } Result result = new Result("403", "你还想攻击我??????????", ""); PrintWriter out = response.getWriter(); out.write(JsonUtil.toJson(result)); out.close(); 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 { }}注意:
  1. cookie必须要设置PATH才可以生效,否则在下一次请求的时候无法带给服务器 。
  2. Spring Boot 出现启动找不到主类的问题时可以mvn clean一下 。
  3. Filter设置response.sendError(403)在Spring Boot没有效果 。
总结上面一共提到了4种攻击方式,分别是XSS攻击(关键是脚本,利用恶意脚本发起攻击),SQL注入(关键是通过用SQL语句伪造参数发出攻击),DDOS攻击(关键是发出大量请求,最后令服务器崩溃),CSRF攻击(关键是借助本地cookie进行认证,伪造发送请求) 。


推荐阅读