zoukankan      html  css  js  c++  java
  • [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 信息。

  • 相关阅读:
    数据库访问表的问题
    UVA 10943全加和(规律)
    POJ 2594 最小路径覆盖 + 传递闭包
    phonegap入门7 capture.captureVideo 录像
    第二部分 Linux Shell高级编程技巧——第二章 Shell工具
    C#写的光模块烧写软件
    关于java的++和操作符,你真的搞明白了吗?
    MFCATL IDispatch调度接口
    c/c++函数调用约定
    HDOJ 2955 Robberies (0/1背包)
  • 原文地址:https://www.cnblogs.com/iiiiiher/p/12354260.html
Copyright © 2011-2022 走看看