csrf 跨站请求伪造
csrf( cross-site request forgery) 属于一种跨站攻击, 在 tornado 中被称为 xsrf
不一定是站内输入, 被伪造的请求可以使任何来源, 并非一定是站内输入
产生背景
前后端完全分离;
跨域资源共享;
核心
伪造服务器, 攻击正常访问网站的用户
解决策略
过滤请求的处理者
1. client 端提交表格是增加随机数 hash 值(用隐藏标签的方式提交), 在 server 端进行验证是否一致, 只有真正的 server 端拥有正确的 hash 值
2. 使用”认证令牌”, 身份认证从 cookies 变为 token
3. 增加验证码
4. 增加 http 中的 referer 标识, 来判断是同域还是跨域, 跨域是否是允许的
cors 跨域资源共享
cors (cross-origin resource sharing) 是 W3C 提出的一个标准, 如今是较为主流的解决跨域资源请求方案. [ IE8+都可以兼容 ]
产生背景
为了防止 csrf
»»»浏览器引入同源(同domain/ip, 同端口, 同协议)策略(sop)保证访问安全, 爱能互相获取资源
»»»前后端不能分离,不能操作 cookies, 不能发送 ajax等问题
提出服务器跨域 (使用反向代理 或 cors)
核心思想
通过一系列新增的 http 头信息来实现 server 和 client 之间的通信, 所以, 要支持 cors, server 端要做一些相应的配置, 这样, 在保证安全性的同事, 也方便了前端的开发
此时, 浏览器会将 cors 请求分为两类:
- 简单请求: HEAD GET POST
- 非简单请求: PUT DELETE OPTIONS
非简单请求会触发 cors preflight (预检请求)触发预检请求也有其他情况:
- 传输的数据格式不是 application/x-www-form-urlencoded
- 操作 cookies
# 后端header配置(举例: tornado中)
def set_default_headers(self):
self.set_header("Access-Control-Allow-Origin", self.request.headers.get("Origin", "*")) # 限定请求源
self.set_header("Access-Control-Allow-Headers", "x-requested-with,authorization") # 请求头
self.set_header("Access-Control-Allow-Methods", "POST,GET") # 限定合法的请求方式
self.set_header("Access-Control-Allow-Credentials", "true") # 证书
self.set_header("Content-type", "application/json") # 限定请求数据格式
参考和延伸:
tornado 的防 csrf
那些跨域
csrf & cors
跨域解决方案一: cors
cors简单请求和预检请求
post 中 content-type 的几种取值