什么是 CSRF?
CSRF(Cross-site request forgery)跨站请求伪造, 也被称为 "One Click Attack" 或者 Session Riding, 通常缩写为 CSRF 或者 XSRF, 是一种对网站的恶意利用. 尽管听起来像跨站脚本(XSS), 但它与 XSS 非常不同, XSS 利用站点内的信任用户, 而 CSRF 则通过伪装成受信任用户的请求来利用受信任的网站.
CSRF 攻击的本质原因:
CSRF 攻击是源于 web 的隐式身份验证机制! Web 的身份验证机制大致就是说为了防止用户每次发送请求的时候都需要登录, 在进行一次登录验证通过后, 之后发向该域名的请求都会自动带上 cookie. 虽然可以保证一个请求是来自于某个用户的浏览器, 但却无法保证该请求是用户批准发送的. CSRF 攻击的一般是由服务端解决, 而 XSS 主要是由客户端解决.
CSRF 攻击的原理:
1. 用户打开浏览器, 访问受信任网站 A, 输入用户名和密码请求登录网站 A.
2. 在用户信息通过验证后, 网站 A 产生 Cookie 信息并返回给浏览器.
3. 用户在未退出网站 A 之前, 在同一浏览器中, 打开一个 TAB 页访问网站 B.
4. 网站 B 接收到用户请求后, 发出一个访问网站 A 的请求.
5. 浏览器根据网站 B 的请求, 在用户不知情的情况下携带 Cookie 信息, 向网站 A 发出请求. 网站 A 并不知道该请求其实是由 B 发起的, 所以会根据用户的 Cookie 信息处理该请求, 达到模拟用户操作的目的.
- tips:Session Cookie(在浏览器关闭后, 就会失效, 保存到内存)
- Third-party Cookie(关闭浏览器后, 不会失效, 保存到本地)
常见的 CSRF 攻击:
Get 请求, 操作数据库内容
比如网站 A 的修改密码接口是 GET 方式, 通过调用 API/ChangePassword?psw=123 就可以进行密码的修改, 所以在开发的过程中如果涉及到数据改动都建议采用 POST 请求
隐藏表单提交 POST 请求
单纯的 POST 当然也是能伪造的, JS 利用 form 表单可以跨域请求的特性的提交 POST 请求仍然能够产生 CSRF 攻击.
如果网站 A 有使用 Flash, 并将跨域策略文件中的 allow-access-from domain 设置为素有, 也是有可能产生 CSRF 攻击的.
XSRF
通常来说 CSRF 是由 XSS 实现的, 所以 CSRF 时常也被称为 XSRF, 用 XSS 的方式实现伪造请求, 比如网站 A 存在 XSS 漏洞, 被注入恶意代码后, 当有用户访问到有恶意代码的网页的时候, 就会发送一条类似转账, 关注啊之类的请求, 做到 XSRF 攻击.
看完这几种攻击方式, 大概应该能辨别什么时候是 CSRF 攻击了, 简单说就是只要发起了冒牌请求那么就算是 CSRF(XSRF)
顺便再总结下 XSS 和 CSRF 的其他区别, 面试官可能会问到哦~
区别一, 发生位置
XSS: 发生在客户端
CSRF: 发生在服务端
区别二, 原理
XSS: 注入代码, 执行代码, 篡改内容
CSRF: 携带 Cookie 模拟请求
区别三, 根源
XSS: 同源策略机制
CSRF:Web 隐式身份验证机制
区别四, 就 Cookie 而言
XSS: 盗取 Cookie 来干坏事
CSRF: 借用 Cookie 来干坏事
最后还是要说下如何防范 CSRF 攻击
一, Referer(记录 HTTP 请求的来源地址) Check
好处是只需要增加一个拦截器来检查 Referer , 用于过滤非该服务器域名的地址, 不需要改变当前系统的任何已有代码和逻辑, 非常快捷.
但是, Referer 的值是由浏览器提供的, 虽然 HTTP 协议上有明确的要求, 但是每个浏览器对于 Referer 的具体实现可能有差别, 并不能保证浏览器自身没有安全漏洞. 使用验证 Referer 值的方法, 就是把安全性都依赖于第三方 (即浏览器) 来保障, 不是很靠谱, 并且一些低版本的浏览器像 IE6 等有方法对 Referer 进行篡改. 还有重要的一点是, 用户可以设置浏览器不携带 Referer 字段.
二, 验证码
强制用户必须与应用进行交互, 才能完成最终请求. 在通常情况下, 验证码能很好遏制 CSRF 攻击. 但是出于用户体验考虑, 网站不能给所有的操作都加上验证码. 因此验证码只能作为一种辅助手段, 不能作为主要解决方案.
三, Token
在 HTTP 请求中以参数的形式添加一个随机产生的 token, 并在服务器端建立一个拦截器来验证这个 token, 假设请求中没有 token 或者 token 内容不对, 则觉得可能是 CSRF 攻击而拒绝该请求. 并且涉及数据库操作的接口使用 POST, 因为 GET 不好加 Token, 会暴露 Token 的保密性.
关于 Token
Token 应该保存到 local / session stograge(不会跨域工作) 或者 cookies
Tokens 除了像 cookie 一样有有效期, 还要提供过期重新获取, 强制刷新, 撤回等操作
有需要的话, 要加密并且签名 token
将 JSON Web Tokens(JWT) 应用到 OAuth 2
四, HTTP 头中自定义属性并验证
类似方法三, 只不过不是以参数形式, 而是请求头字段携带 Token 信息. 但是要把所有请求都改为 XMLHttpRequest 请求.
至此, 有关 XSS 和 CSRF 的内容都讲解完毕了, 感谢大家抽空阅读.
来源: https://www.cnblogs.com/anyhoo/p/10635540.html