1.10 操作业务
1.10.1【必须】部署CSRF防御机制
CSRF是指跨站请求伪造(Cross-site request forgery),是web常见的攻击之一。对于可重放的敏感操作请求,需部署CSRF防御机制。可参考以下两种常见的CSRF防御方式
设置CSRF Token
服务端给合法的客户颁发CSRF Token,客户端在发送请求时携带该token供服务端校验,服务端拒绝token验证不通过的请求。以此来防止第三方构造合法的恶意操作链接。Token的作用域可以是Request级或者Session级。下面以Session级CSRF Token进行示例
登录成功后颁发Token,并同时存储在服务端Session中
String uuidToken = UUID.randomUUID().toString();
map.put("token", uuidToken);
request.getSession().setAttribute("token",uuidToken );
return map;
创建Filter
public class CsrfFilter implements Filter {
...
HttpSession session = req.getSession();
Object token = session.getAttribute("token");
String requestToken = req.getParameter("token");
if(StringUtils.isBlank(requestToken) || !requestToken.equals(token)){
AjaxResponseWriter.write(req, resp, ServiceStatusEnum.ILLEGAL_TOKEN, "非法的token");
return;
}
...
CSRF Token应具备随机性,保证其不可预测和枚举。另外由于浏览器会自动对表单所访问的域名添加相应的cookie信息,所以CSRF Token不应该通过Cookie传输。
校验Referer头
通过检查HTTP请求的Referer字段是否属于本站域名,非本站域名的请求进行拒绝。
这种校验方式需要注意两点:
- 要需要处理Referer为空的情况,当Referer为空则拒绝请求
- 注意避免例如qq.com.evil.com 部分匹配的情况。
1.10.2【必须】权限校验
对于非公共操作,应当校验当前访问账号进行操作权限(常见于CMS)和数据权限校验。
- 验证当前用户的登录态
- 从可信结构中获取经过校验的当前请求账号的身份信息(如:session)。禁止从用户请求参数或Cookie中获取外部传入不可信用户身份直接进行查询。
- 校验当前用户是否具备该操作权限
- 校验当前用户是否具备所操作数据的权限。避免越权。
1.10.3【建议】加锁操作
对于有次数限制的操作,比如抽奖。如果操作的过程中资源访问未正确加锁。在高并发的情况下可能造成条件竞争,导致实际操作成功次数多于用户实际操作资格次数。此类操作应加锁处理。