安全设计--CSRF跨站伪造

概念


定义

CSRF跨站点请求伪造(Cross—Site Request Forgery):顾名思义,攻击者伪造用户请求请求服务端,但并非在官方站点发起,而是攻击者的站点,或者攻击者的脚本。而服务器认为却是合法的,有点借刀杀人的意思。

原理

攻击者伪造的网站,或者伪造请求作为一个链接或者按钮。提供给正常用户点击或者在其他站点提交,请求的地址是官方服务器,携带的是当前操作人的Cookie信息。导致操作的内容为攻击者的想要的,达成攻击目标。

案例

电商网站,商品详情页往往有评论,攻击者制作一个点击按钮,用户点击就能对自己下过单的商品进行评论,评论的内容和动作都是攻击者来设定。对网站和个人的名誉产生负面影响。

防御方案


体验与安全兼顾:在请求中添加 token 并验证

  • token hidden在页面,对用户透明。
  • 攻击者无法获取到token和伪造。
解决思路
  • 首先将这种操作类请求做成post请求。避免URL上带token,防止获取Referer得到token
  • token是在进入操作页面时由服务端生成并埋入。提交时携带token,服务端对token进行校验,确定请求有效性
  • token要求:与请求用户有唯一绑定关系,防止伪造。
具体实现

redis + session 实现token (集群情况下要求分布式session实现方案)

  • 用户请求,服务端获取当前用户sessionId;同时生成一个UUID,将UUID作为key sessionId作为Value存入redis。目的:特定发起者有唯一的token,攻击者不能模仿请求获取到token来伪造。
  • 将UUID作为Token 返回给用户页面,用户提交时携带UUID作为入参,传递到服务端。
  • 服务端获取操作请求,利用UUID获取SessionId 和本次请求的sessionId比对,通过校验之后才放过 。不一致则拒绝。
  • 利用sessionId的理由:就算攻击者模仿请求获取到UUID的token给到用户提交的sessionId是不同的,起不到攻击作用
  • 注意:不要钻请求劫持的牛角尖,如果用户请求时被劫持了,这种情况不止是CSRF那么简单了,啥都能发生。

关键代码


token
public void generateToken(){
    String userToken = UUID.randomUUID().toString();
    String sessionId = request.getSession().getId();
    RedisUtils.put(userToken,sessionId);
}
check token
public void checkToken(){
	String sessionId = request.getSession().getId();
	String userSessionId = RedisUtils.get(userToken);
	 
	if (sessionId == null || !sessionId.equals(userSessionId)){
	    // false;
	}
	// go
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值