网络安全

91 阅读7分钟

一、浏览器的同源策略

如果两个 URL 的 protocolport (en-US) (如果有指定的话) 和 host 都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是 “元组”。(“元组” 是指一组项目构成的整体,双重/三重/四重/五重/等的通用形式)。

下表给出了与 URL store.company.com/dir/page.ht… 的源进行对比的示例:

URL结果原因
store.company.com/dir2/other.html同源只有路径不同
https://store.company.com/secure.html失败协议不同
store.company.com :81/dir/etc.html失败端口不同 ( http:// 默认端口是 80)
http://news.company.com/dir/other.html失败主机不同

二、跨域解决方案

1、JSONP跨域请求方案[局限性:仅能支持GET请求]

    • link/script/img...都不存在域的限制,直接可以跨域请求资源{请求方式是:get}

利用script不存在域的限制,的特点,我们再发送数据请求,不再使用axios和fetch了,直接基于script的src发送请求即可【这样避开了域的限制】,但是他有很强的局限性:因为script都是GET的请求,所以我们能够发送的数据请求,也只能是GET。

img

2、客户端允许跨域

不允许跨域是因为,当前WEB页面的“源地址origin”向服务器发送请求是不被允许的,所以如果想解决这个问题,只需要服务器端设置为允许即可‘Access-Control-Allow-Origin'

header("Access-Control-Allow-Origin:http://127.0.0.1") header("Access-Control-Allow-Credentials", true);

3、PROXY跨域资源代理

  1. 客户端访问的地址由代理服务器提供
  2. 客户端请求的数据接口,全部由代理来进行处理
  1. 代理服务器收到客户端请求后,帮助客户端向目标服务器发送请求 “服务器与服务器之间不存在跨域”
  2. 代理服务器把获取的数据,再返回给客户端

img

4、document.domain + iframe跨域

此方案仅限主域相同子域不同的跨域应用场景。实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。

1)父窗口:(www.domain.com/a.html)

<iframe id="iframe" src="http://child.domain.com/b.html">
</iframe><script>    
    document.domain = 'domain.com'; var user = 'admin'; 
</script> 

2)子窗口:(child.domain.com/a.html)

<script>     
    document.domain = 'domain.com';     
    // 获取父窗口中变量     
    console.log('get js data from parent ---> ' + window.parent.user); 
</script>

5、postMessage跨域

postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,可以通过postMessage的特性来解决跨域问题

A页面:

<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;">
</iframe> 
<script>            
    var iframe = document.getElementById('iframe');     
    iframe.onload = function() {    
        var data = {  name: 'aym' };         
        // 向domain2传送跨域数据         
        iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');
    };     
    // 接受domain2返回数据     
    window.addEventListener('message', function(e) { 
        alert('data from domain2 ---> ' + e.data);  
    }, false); 
</script>

B页面:

<script>     
    // 接收domain1的数据     
    window.addEventListener('message', function(e) { 
        alert('data from domain1 ---> ' + e.data);
        var data = JSON.parse(e.data);
        if (data) { 
            data.number = 16;             
            // 处理后再发回domain1            
            window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');        
        }     
    }, false);
</script>

6、WebSocket协议跨域

WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。 原生WebSocket API使用起来不太方便,我们可以使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。

三、xss/csrf

XSS

什么是XSS

XSS攻击通常指的是通过利用 网页 开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序

img

如何进行xss攻击:

1、假设有一个博客网站,我发表一篇博客,其中嵌入

2、脚本内容:获取cookie 发送到我的服务器(服务器配合跨域)

3、发布这篇文章,有人查看它,我轻松收割访问者的cookie

4、可以 获取到当前域名的cookie,然后发送给攻击者的服务器,攻击者的服务器提前设置好允许跨域。

预防XSS攻击

  1. 替换特殊字符,如 < 变为&It; > 变为&gt;
    

3.对于 a 标签的 href 等外链请求,添加白名单进行过滤,禁止以 javascript: 开头的链接,和其他非法的 scheme

csrf

什么是CSRF/XSRF攻击

CSRF 概念:CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者 Session Riding,通常缩写为 CSRF 或者 XSRF,是一种对网站的恶意利用。

尽管听起来像跨站脚本(XSS),但它与 XSS 非常不同,XSS 利用站点内的信任用户,而 CSRF 则通过伪装成受信任用户的请求来

利用受信任的网站。

与 XSS 攻击相比,CSRF 攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比 XSS 更具危险性。

CSRF攻击原理

img

  1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;

2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;

  1. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
  1. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
  1. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不

知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

预防CSRF攻击

目前防御 CSRF 攻击主要有三种策略:验证 HTTP Referer 字段;在请求地址中添加 token 并验证;在 HTTP 头中自定义属性并验证。

验证 HTTP Referer 字段。

根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址。在通常情况下,访问一个安全受限页面的请求来自于同一个网站。

但是Referer 的值是由浏览器提供的,虽然 HTTP 协议上有明确的要求,但是每个浏览器对于 Referer 的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。使用验证 Referer 值的方法,就是把安全性都依赖于第三方(即浏览器)来保障,从理论上来讲,这样并不安全。事实上,对于某些浏览器,比如 IE6 或 FF2,目前已经有一些方法可以篡改 Referer 值

设置token验证

我们要防御CSRF关键在于请求放入的时候黑客不能去伪造信息,并且这个信息不存在cookie之中,所以我们就可以在通过http的请求中或者是头信息中加入一个随机产生的token,这个token就会存在服务端,通过拦截器去验证这个token,如果请求头中不存在token或者token不正确,拦截器就会认为这是一次CSRF攻击,拒绝此次请求。

token 是最普遍的一种防御方法,后端先生成一个 token ,之后将此放在数据库中并发送给前端,那么前端发送请求时就会携带这个 token ,后端通过校验这个 token 和数据库中的 token 是否一致,以此来判断是否是本网站的请求

HTTP 头中自定义属性并验证

自定义属性的方法也是使用token并进行验证,和前一种方法不同的是,这里并不是把token以参数的形式置于HTTP请求之中,而是把它放到HTTP头中自定义的属性里。通过XMLHttpRequest这个类,可以一次性给所有该类请求加上csrftoken这个HTTP头属性,并把token值放入其中。这样解决了前一种方法在请求中加入token的不便,同时,通过这个类请求的地址不会被记录到浏览器的地址栏,也不用担心token会通过Referer泄露到其他网站。


以上只是个人在代码学习中的一些心得体会和笔记分享 如有错误还望大家能够指出批评