互联网并发与安全系列教程(06) - 常见的Web安全漏洞(CSRF攻击)

CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用也就是人们所知道的钓鱼网站。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。

防御CSRF手段

解决方案:使用图形验证码 防止机器模拟接口请求攻击,在调用核心业务接口时,比如支付、下单、等接口,最好使用手机短信验证验证或是人脸识别,防止其他用户使用Token伪造请求。

下面来引申其它的一些知识 - - -> 使用Token机制,防止页面重复提交。

基于Token方式防止API接口幂等

需求

  • 业务要求:页面的数据只能被点击提交一次
  • 发生原因:由于重复点击或者网络重发,或者 nginx 重发等情况会导致数据被重复提交

解决办法

  • 集群环境:采用 token 加 redis(redis 单线程的,处理需要排队)
  • 单 JVM 环境:采用 token 加 redis 或 token 加 jvm 内存

处理流程

  • 数据提交前要向服务的申请 token,token 放到 redis 或 jvm 内存,token 有效时间 提交后后台校验 token,同时删除 token,生成新的 token 返回。
  • token 特点:要申请,一次有效性,可以限流

客户端每次在调用接口的时候,需要在请求头中,传递令牌参数,每次令牌只能用一次。
一旦使用之后,就会被删除,这样可以有效防止重复提交。

步骤:

  1. 生成令牌接口
  2. 接口中获取令牌验证

生成令牌接口:

public class TokenUtils {

	private static Map<String, Object> tokenMap = new ConcurrentHashMap<String, Object>();

	// 获取token
	public static synchronized String getToken() {
		// 1.生成令牌
		String token = "token-" + System.currentTimeMillis();
		// 2.存入tokenMap
		tokenMap.put(token, token);
		return token;
	}

	// 验证token,并且删除对应的token
	public static Boolean exisToken(String token) {
		// 1.从集合中获取token
		Object result = tokenMap.get(token);
		if (result == null) {
			return false;
		}
		// 2.删除对应的token
		tokenMap.remove(token);
		return true;
	}
}

接口中获取令牌验证:

@RestController
public class OrderController {

	@Autowired
	private OrderMapper orderMapper;

	// 获取Token
	@RequestMapping("/getToken")
	public String getToken() {
		return TokenUtils.getToken();
	}

	// 验证Token
	@RequestMapping(value = "/addOrder", produces = "application/json; charset=utf-8")
	public String addOrder(@RequestBody OrderEntity orderEntity, HttpServletRequest request) {
		String token = request.getHeader("token");
		if (StringUtils.isEmpty(token)) {
			return "参数错误!";
		}
		if (!TokenUtils.exisToken(token)) {
			return "请勿重复提交!";
		}
		int result = orderMapper.addOrder(orderEntity);
		return result > 0 ? "添加成功" : "添加失败" + "";
	}
}

总结

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值