为什么我们总在说 POST
比 GET 安全,那么到底安全在哪里呢?是只有面试题上洋洋洒洒罗列的那些问题么。
为什么我们总在说 POST 比 GET 安全,那么到底安全在哪里呢?是只有面试题上洋洋洒洒罗列的那些问题么。
起源
这个问题的起源是小伙伴在面试的时候问候选人 “ POST 与 GET 的差异,然后提到了 POST 比 GET 安全”,然后前端小组内由 PSOT 比 GET 安全在哪些地方进行了充分的讨论。
讨论
那我们先来看看普通版本的面试题答案,POST 比 GET 的优势:
1 | GET 请求参数是放在 URL 上,有长度的限制,POST 没有 |
那么我们一起来看看,到底为什么 POST 会比 GET 安全。
首先我们来看一个场景,萌新入职第一天愉快的登陆了 A网站 完成了注册登陆大礼包。
这时候老司机想看看萌新的安全意识直接丢了一个神秘链接给萌新,萌新开心的打开,突然发现页面 CSRF 四个大字在页面上。
萌新一脸无辜赶紧请教老司机,老司机不疾不徐的道来: “刚你在 A网站进行了登陆,这个时候服务端会给你设置一个cookie,这里cookie会存在浏览器本地,在有效期内同源的请求都会默认携带上这个cookie。我就是利用了这一点对你完成了 CSRF 的跨站脚本攻击”。
“可是什么究竟什么是跨站脚本攻击呢?”
CSRF(Cross-site request forgery)跨站请求伪造:即为在第三方网站中,向被攻击网站发送跨站请求。利用浏览本地存储的被攻击网站的cookie,绕过服务端的验证,达到冒充用户的目的。
“那么 CSRF 与 POST 更安全有什么关系呢?”
我们来展示一个简单的 demo 被攻击网站:
1 | // index.html |
1 | const express = require('express') |
1 | // csrf.html |
简单来说就是启动一个被攻击网站,然后攻击网站利用 image 发送一个 GET 请求来窃取用户的 cookie 达到CSRF攻击的目的。
那 POST 相较 GET 更安全那我们就要看 POST 与 GET 的区别了。
首先 GET 请求发送没有同源策略的限制,在任意的域名下都会直接发起请求,而POST请求在跨域的情况下会先发一个 OPTION 请求到服务端探寻是否允许跨域,如果服务端的设置的 Access-Control-Allow-Origin 没有设置 * 或者允许特定的域名的情况下。比如你的服务端仅设置 Access-Control-Allow-Origin: http://www.a.com 那么你在 http://www.b.com 的域名下发送一个 POST 请求会先发出一个 OPTION 的请求来探测服务端是否允许跨域。如果服务端设置的 Access-Control-Allow-Origin没有当前域名的话则POST 的请求主体则不会发送。这样的差异在服务端的差异就变成了 GTE 请求在服务端会直接收到请求并按照正常请求的逻辑去处理,而 POST 请求业务上会变成在跨域的时候仅会发送 OPTION 请求服务端并不会处理具体的业务逻辑,且 OPTION 请求并不会携带 cookie 。
从这个方面我们可以看出在跨域的情况下 POST
请求因为会预发一个 OPTION 请求从而避免像 GET 请求一样被恶意窃取 cookie 。
GET请求究竟有哪些缺陷?1
2
3
4
51. 在低版本浏览器上GET请求会被缓存,造成意外的结果。
2. JSONP实现的GET请求天然存在被XSS的风险
3. GET请求会被缓存,造成意外的返回值。
4. GET请求URL长度限制
5. GET请求参数类型限制(GET仅能接受ASCII)
PSOT好在哪里1
2
3
41. POST在跨域的时候会先发一个option请求检查服务端是否允许跨域。(CORS跨站脚本攻击)
2. POST参数无类型/大小限制
3. 重放POST请求的时候会提示用户。
4. POST在设置 csrfToken 放置在header中不会被窃取。