[dj]csrf/xsrf vs 跨域(cors)问题

你能回答两个常见问题吗?

  • 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是什么?

  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 信息。

原文地址:https://www.cnblogs.com/iiiiiher/p/12354260.html