你能回答两个常见问题吗?
- 1.为什银行一直强调,不要胡乱点不明链接.
- 2.前端说接口访问不了了. 你从服务端允许跨域后就可以正常post了.
//一看浏览器console:
Access to XMLHttpRequest at 'http://127.0.0.1:8000/' from origin 'http://localhost:63344' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
test.html?_ijt=r4v9pnluh36cd56h5vno6hku60:20 Error: Network Error
at createError (createError.js:17)
at XMLHttpRequest.handleError (xhr.js:83)
csrf概述
一.CSRF是什么?
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。
CSRF 顾名思义,是伪造请求,冒充用户在站内的正常操作。
二.CSRF可以做什么?
你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,
甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。
三.CSRF漏洞现状
CSRF这种攻击方式在2000年已经被国外的安全人员提出,但在国内,直到06年才开始被关注,08年,国内外的多个大型社区和交互网站分别爆出CSRF漏洞,如:NYTimes.com(纽约时报)、Metafilter(一个大型的BLOG网站),YouTube和百度HI......而现在,互联网上的许多站点仍对此毫无防备,以至于安全业界称CSRF为“沉睡的巨人”。
四.CSRF的原理
下图简单阐述了CSRF攻击的思想:
从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤:
1.登录受信任网站A,并在本地生成Cookie。
2.在不登出A的情况下,访问危险网站B。
看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:
1.你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。
2.你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了......)
3.上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。
认证凭据不要泄漏
如何获取认证凭据的? cookie/token
用户登陆提供user pass, 后端验证通过颁发一个字符串, 以后每次发request都鞋带上.
cookie有什么特点?
response的cookie,浏览器下次请求会自动被携带.是浏览器默认行为.
cookie泄漏了会有什么危害?
具备了你的身份的任何操作权限.
cookie泄漏了怎么补救?
对于cookie, 服务端db里去失效.
对于jwt token, 只能等,或者reload server. 尽量把token过期时间缩短(refresh token和用户凭据token)
登陆状态,不要被人利用.
为什么不要点不明链接?
那个链接可能就是你操作银行的链接. 不过参数是伪造的.
服务端如何规避点不明链接的风险?
token机制. 你来获取转账表单,顺带给你一个token,构建转账参数+token一并提交.
所以这里说的csrf token核心是,黑客假冒你的身份, 给你胡贴了一些提交参数.让你受损害.
跨域问题
前后端分离后, 为什么要解除csrf token策略.
试问, django使用csrf token做校验时, ajax请求是怎么规避的?
当前前后端都是restful风格开发, ajax请求, 前端发post前, 并不会去请求这个token, 因此没办法通过这种方式规避csrf校验.
django是怎么解决跨域的
pip install django-cors-headers
INSTALLED_APPS = [
...
'corsheaders',
...
]
什么是跨域
是浏览器的一种安全策略. 如postman测试ok, 为什么浏览器就不行了? 因为postman, python的requests库等一些后端非浏览器请求, 是不会检测同源策略的.
//三者任一不同, 则浏览器同源策略通过失败
https:// www.baidu.com: 80
协议相同 域名相同 端口相同
非同源 浏览器到底有什么限制?
(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。 -- 前后端分离开发, 触发了这一点.
如何允许浏览器关闭跨域检查?
- jsonp
安全性差,已经不推荐
- CORS(W3C标准,跨域资源共享 - Cross-origin resource sharing)
服务端设置,安全性高,推荐使用
- websocket
特殊场景时使用,不属于常规跨域操作
- 代理服务(nginx)
可作为服务端cors配置的一种方式,推荐使用
真实场景, 前端脚手架node可以设置代理解决(同源访问)请求问题, 也可以在服务端设置response header解决.(遵从w3c规范访问)
cors就是跨域吗?
不是, cors(Cross-origin_resource_sharing?) 是一种解决跨域的方式.
Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served.[1]
ajax请求到底发出去了没?
浏览器的同源策略会导致跨域,也就是说,如果协议、域名或者端口有一个不同,都被当作是不同的域,就不能使用 Ajax 向不同源的服务器发送 HTTP 请求。首先我们要明确一个问题,请求跨域了,请求到底发出去没有?
答案是肯定发出去了,但是浏览器拦截了响应。
cors到底是怎么解决跨域的?
第一次打开页面, 直接ajax, 其实浏览器是将请求发出去了.
浏览器拦截 response 检查Access-Control-Allow-Origin类似的响应头. 有则放行,正常.浏览器就知道了哦, 你ajax访问的这个url允许别的url来共享资源
无则报资源共享失败.
观察network面板 发现:
观察console 说与检查失败了. 因为没有xxx response头.
服务端本次访问日志
[24/Feb/2020 00:59:50] "OPTIONS / HTTP/1.1" 200 77
cors解决方式看, 到底是服务端限制了访问, 还是浏览器限制了访问
是浏览器限制了访问. 服务器只是给设置了一些response header.
什么时候浏览器会出现provisional headers are shown?
跨域,请求被浏览器拦截
请求被浏览器插件拦截
服务器出错或者超时,没有真正的返回: // 这种情况 在django-header-cors里如果服务端出现问题, 跨域头也配了.
// 但是console就是提示没xxx头跨域问题. 其实是服务端接口逻辑错误导致header没设置上
强缓存from disk cache或者from memory cache,此时也不会显示
跨域和csrf有关系吗?
没啥关系. csrf是仿冒身份. 跨域是浏览器安全策略.
后端是怎么区别ajax和普通请求的?
request.is_ajax() # 检查下面的, 难道每次ajax请求会自动携带下面的请求头吗? 感觉不太靠谱.
xmlhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
跨域踩坑经验总结(内涵:跨域知识科普)
跨域常见错误
首先让我们看一下前端报出的跨域错误信息
第一种:No 'Access-Control-Allow-Origin' header is present on the requested resource,并且The response had HTTP status code 404
XMLHttpRequest cannot load http://b.domain.com, Response to preflinght request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.domain.com' is therefore not allowed access. The Response had HTTP status code 404.
ps.并且The response had HTTP status code 404
问题原因:服务器端后台没有允许OPTIONS请求
第二种:No 'Access-Control-Allow-Origin' header is present on the requested resource,并且The response had HTTP status code 405
XMLHttpRequest cannot load http://b.domain.com, Response to preflinght request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.domain.com' is therefore not allowed access. The Response had HTTP status code 405.
ps.并且The response had HTTP status code 405
问题原因:服务器端后台允许了OPTIONS请求,但是某些安全配置阻止了OPTIONS请求
第三种:No 'Access-Control-Allow-Origin' header is present on the requested resource,并且The response had HTTP status code 200
XMLHttpRequest cannot load http://b.domain.com, Response to preflinght request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.domain.com' is therefore not allowed access.
ps.并且The response had HTTP status code 200
问题原因:服务器端后台允许了OPTIONS请求,并且OPTIONS请求没有被阻止,但是头部不匹配。
第四种:heade contains multiple values ',',并且The response had HTTP status code 200
XMLHttpRequestcannot load http://b.domain.com. The 'Access-Control-Allow-Origin' header contains multiple values'*, *', but only one is allowed. Origin 'http://a.domain.com' is therefore notallowed access.
ps.并且The response had HTTP status code 200
问题原因:设置多次Access-Control-Allow-Origin=*,可能是配置的人对CORS实现原理和机制不了解导致
后端的header要有那些?
# 服务端允许访问的域名
Access-Control-Allow-Origin=https://idss-uat.jiuyescm.com
# 服务端允许访问Http Method
Access-Control-Allow-Methods=GET, POST, PUT, DELETE, PATCH, OPTIONS
# 服务端接受跨域带过来的Cookie,当为true时,origin必须是明确的域名不能使用*
Access-Control-Allow-Credentials=true
# Access-Control-Allow-Headers 表明它允许跨域请求包含content-type头,我们这里不设置,有需要的可以设置
#Access-Control-Allow-Headers=Content-Type,Accept
# 跨域请求中预检请求(Http Method为Option)的有效期,20天,单位秒
Access-Control-Max-Age=1728000
ps. 如果跨域需要携带cookie去请求,Access-Control-Allow-Credentials必须为true,但是需要注意当Access-Control-Allow-Credentials=true时,Access-Control-Allow-Origin就不能为” * “ ,必须是明确的域名,当然可以多个域名使用 “,” 分割
前端如何配合发起请求?
如果是浏览器直接访问跨域请求url,只要服务端返回 “Access-Control-Allow-X” 系列header在response中即可成功访问。
如果是ajax发起的请求该如何处理?
第一种:请求不需要携带cookie
$.ajax({
url : 'url',
data : data,
dataType: 'json',
type : 'POST',
crossDomain: true,
contentType: "application/json",
success: function (data) {
var a=JSON.stringify(data);
if(data.result==true){
...........
}else{
...........
}
},
error:function (data) {
var a=JSON.stringify(data);
alert(a);
}
});
ps. 增加crossDomain=true
第二种:请求需要携带cookie(不兼容安卓)
$.ajax({
url : 'url',
data : data,
dataType: 'json',
type : 'POST',
xhrFields: {
withCredentials: true
},
crossDomain: true,
contentType: "application/json",
success: function (data) {
var a=JSON.stringify(data);
if(data.result==true){
...........
}else{
...........
}
},
error:function (data) {
var a=JSON.stringify(data);
alert(a);
}
});
ps. 增加crossDomain与xhr.withCredentials,发送Ajax时,Request header中便会带上 Cookie 信息。