CSRF是什么?

CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。

CSRF可以做什么?

你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。

CSRF的原理

下图简单阐述了CSRF攻击的思

从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤:

登录受信任网站A,并在本地生成Cookie。

在不登出A的情况下,访问危险网站B。

看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:

你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。

你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了......)

上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。

下面讲一讲java解决CSRF攻击的方式。

模拟CSRF攻击

登录A网站

用户名和密码都是admin。

http://localhost:8081/login.html:

你有权限删除1号帖子

http://localhost:8081/deletePost.html:

登录有CSRF攻击A网站的B网站

http://localhost:8082/deletePost.html:

明显看到B网站是8082端口,A网站是8081端口,但是B网站的删除2号帖子功能依然实现。

预防CSRF攻击

简单来说,CSRF 就是网站 A 对用户建立信任关系后,在网站 B 上利用这种信任关系,跨站点向网站 A 发起一些伪造的用户操作请求,以达到攻击的目的。

而之所以可以完成攻击是因为B向A发起攻击的时候会把A网站的cookie带给A网站,也就是说cookie已经不安全了。

通过Synchronizer Tokens

Synchronizer Tokens: 在表单里隐藏一个随机变化的 csrf_token csrf_token 提交到后台进行验证,如果验证通过则可以继续执行操作。这种情况有效的主要原因是网站 B 拿不到网站 A 表单里的 csrf_token

这种方式的使用条件是PHP和JSP等。因为cookie已经不安全了,因此把csrf_token值存储在session中,然后每次表单提交时都从session取出来放到form表单的隐藏域中,这样B网站不可以得到这个存储到session中的值。

下面是JSP的:

>

但是我现在的情况是html,不是JSP,并不能动态的从session中取出csrf_token值。只能采用加密的方式了。

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

B网站的他已经没有权限了

我们通过UserFilter.java给攻击者返回的是403错误,表示服务器理解用户客户端的请求但拒绝处理。

http://localhost:8082/deletePost.html:

攻击者不能删除4号帖子。

前端代码:

deletePost.html

deletePost

function deletePost() {

var url = '/post/' + document.getElementById("postId").value;

var csrf_token = document.cookie.replace(/(?:(?:^|.*;\s*)csrf_token\s*\=\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") {

// window.location.href = "index.html";

$("#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;

}

删除帖子

帖子编号 :

deletePost

后台代码:

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");

System.out.println(csrf_token + "1222222222222222222222222222222222222222222222");

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 {

}

}

注意:

cookie必须要设置PATH才可以生效,否则在下一次请求的时候无法带给服务器。

Spring Boot 出现启动找不到主类的问题时可以mvn clean一下。

Filter设置response.sendError(403)在Spring Boot没有效果。

参考文档:

java csrf_Java解决CSRF问题相关推荐

  1. 《Java实战开发》利用spring-security解决CSRF问题,通过重写CsrfFilter 过滤掉指定方法

    最近项目渗透测试检测出一些安全问题其中一项为csrf攻击隐患,然后开始修复 csrf简介 CSRF(Cross-site request forgery)跨站请求伪造,也被称为"One Cl ...

  2. java多线程解决应用挂死的问题

    java多线程解决应用挂死的问题 参考文章: (1)java多线程解决应用挂死的问题 (2)https://www.cnblogs.com/hushaojun/p/4323808.html (3)ht ...

  3. Java 递归解决 quot;仅仅能两数相乘的计算器计算x^yquot; 问题

    Java 递归解决 "仅仅能两数相乘的计算器计算x^y" 问题 /*** 求一个数的乘方* 求x^y,y是一个正整数. 设计算器仅仅能计算两数相乘,不能一次计算n个数相乘. * 知 ...

  4. java面试解决项目难题_Java转换难题者,不适合工作(或面试)

    java面试解决项目难题 一个非常艰苦的面试问题可能是这样的: int i = Integer.MAX_VALUE; i += 0.0f; int j = i; System.out.println( ...

  5. java 死锁 解决_Java死锁故障排除和解决

    java 死锁 解决 JavaOne年度会议的一大优点是主题专家介绍了几个技术和故障排除实验室. 这些实验室之一尤其引起了我的关注:Java冠军Heinz Kabutz提出的" HOL650 ...

  6. java中解决组件重叠的问题(例如鼠标移动组件时)

    java中解决组件覆盖的问题!      有时候在移动组件的时候会出现两个组件覆盖的情况,但是你想让被覆盖的组件显示出来或者不被覆盖! 在设计GUI时已经可以定义组件的叠放次序了(按摆放组件的先后顺序 ...

  7. java雪崩_【并发编程】java 如何解决redis缓存穿透、缓存雪崩(高性能示例代码)...

    [并发编程]java 如何解决redis缓存穿透.缓存雪崩(高性能示例代码) 发布时间:2018-11-22 16:48, 浏览次数:872 , 标签: java redis <>缓存穿透 ...

  8. java数据存在ie中_[Java教程]解决在IE中获取数据的缓存问题,运行环境为node.js

    [Java教程]解决在IE中获取数据的缓存问题,运行环境为node.js 0 2015-11-30 20:00:06 IE下默认会开启缓存策略,不管是页面还是通过ajax请求的数据都会议一个url,u ...

  9. JAVA中解决Filter过滤掉css,js,图片文件等问题

    JAVA中解决Filter过滤掉css,js,图片文件等问题 参考文章: (1)JAVA中解决Filter过滤掉css,js,图片文件等问题 (2)https://www.cnblogs.com/er ...

最新文章

  1. BDTC 2017丨大数据在金融、交通、医疗、工业领域落地实践与应用
  2. TCP/IP详解学习笔记(12)-TCP的超时与重传
  3. Redis入门到精通只需要三篇博客
  4. 【移动端 Web】怎么循序渐进地开发一个移动端页面
  5. 用计算机对话的小品,爆笑小品剧本台词《作弊记》
  6. 推荐系统在滴滴司机调度系统中的应用实践
  7. C++primer 6.7节练习
  8. 中国生产力促进中心”十四五”规划与发展规模分析报告2022~2028年
  9. R 和 rgl 绘制 3D 结
  10. Joiner.on和stream().map联合使用技巧
  11. 二元二次拟合 matlab函数
  12. wps插入尾注(罗马数字变阿拉伯数字,即i变1)的操作方法
  13. 【毕业设计】基于树莓派的指纹识别考勤系统 - 单片机 嵌入式 物联网
  14. Telegram、Telethon
  15. 快速上手ECharts,让你的数据不再冷冰!
  16. doodoo.js快速入门教程
  17. 空间相册显示服务器错误,空间相册服务器繁忙
  18. 操作系统介绍(按发展顺序)人工操作方式、单道批处理系统、多道批处理系统、分时系统、实时系统、微机操作系统
  19. 电脑文件夹改名快速重命名文件夹名的方法
  20. MySQL的varchar水真的太深了——InnoDB记录存储结构

热门文章

  1. python自动化测试视频教程_精品系列-悠悠python自动化测试视频教程
  2. 好用的分享代码的网站——ubuntu Pastebin
  3. 保险nbsp;车险险种及说明
  4. oracle移动表空间的数据文件,移动Oracle表空间数据文件方案
  5. NLP自然语言处理:神经网络语言模型(NNLM)
  6. 鱼蛋分类及加盟注意事项
  7. 【附源码】Java计算机毕业设计企业信息网站(程序+LW+部署)
  8. java几种读写文件的方式
  9. 跨年晚会之战硝烟四起 各大卫视比拼明星阵容
  10. Linux中的mmap的使用