IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 关于HTTP中的CSP(Content-Security-Policy)内容安全策略 -> 正文阅读

[网络协议]关于HTTP中的CSP(Content-Security-Policy)内容安全策略

关于HTTP中的CSP

  • 在HTTP协议中为了使我们的网站足够的安全,经常要用到CSP(Content-Security-Policy)内容安全策略
  • CSP的作用
    • 限制网站中资源的获取,以及请求发送到哪里
    • 报告资源获取越权
  • CSP的限制方式
    • default-src限制全局和链接请求有关的东西
    • 指定资源类型
      • connect-src
      • manifest-src
      • img-src
      • font-src
      • media-src
      • style-src
      • frame-src
      • script-src
      • 网页上和链接有关的…

程序示例

1 ) 禁用行内脚本

  • test.html

    • 在html中写js,称为inline script
    • 写在页面里的脚本会有安全问题,如XSS
    • 在页面注入一些脚本来导致,比如网站中的富文本编辑器插入的文本
    • 处于安全考虑,不能直接执行写在页面里的脚本
    • 我们要想办法把它限制掉
    <script>
        console.log('inline js');
    </script>
    
  • server.js

    const http = require('http');
    const fs = require('fs');
    
    http.createServer((req, res) => {
        console.log('req come: ', req.url);
        const html = fs.readFileSync('test.html', 'utf8');
        res.writeHead(200, {
            'Content-Type': 'text/html',
            'Content-Security-Policy': 'default-src http: https:'
        });
        res.end('');
    }).listen(8000, () => {
        console.log('server is running on port 8000');
    });
    
  • 一般情况下谷歌会报这个错

    Refused to execute inline script because it violates the following Content Security Policy directive: "default-src http: https:". Either the 'unsafe-inline' keyword, a hash ('sha256-X4GPgiK5x/RXRod6t6oOY0TqUNEVnds4EvCOtFqUZUU='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
    
  • Safari会报这个错

    Refused to execute a script because its hash, its nonce, or 'unsafe-inline' appears in neither the script-src directive nor the default-src directive of the Content Security Policy.
    
  • 而且页面中的脚本不会被执行, 这样就限制了页面脚本的执行

2 ) 禁用行内脚本,允许外链脚本

  • 如果我们允许外链脚本不允许行内脚本,还需要修改一下代码
  • test.html
    <script>
        console.log('inline js');
    </script>
    <script src="/test.js"></script>
    
  • server.js
    const http = require('http')
    const fs = require('fs')
    
    http.createServer(function (req, res) {
    console.log('request comes', req.url)
    if (req.url === '/') {
        const html = fs.readFileSync('test.html', 'utf8')
        res.writeHead(200, {
            'Content-Type': 'text/html',
            'Content-Security-Policy': 'default-src http: https:'
        });
        res.end(html)
    } else {
        res.writeHead(200, {
            'Content-Type': 'application/javascript'
        });
        res.end('console.log("script loaded")')
    }
    }).listen(8000, () => {
        console.log('server is running on port 8000');
    });
    
  • 这个时候,行内被限制执行,外链脚本会被执行

3 ) 限制外链脚本域名进行加载

  • 稍微修改下程序
  • test.html
    <script src="/test.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
    
  • server.js
    const http = require('http')
    const fs = require('fs')
    
    http.createServer(function (req, res) {
    console.log('request comes', req.url)
    if (req.url === '/') {
        const html = fs.readFileSync('test.html', 'utf8')
        res.writeHead(200, {
            'Content-Type': 'text/html',
            'Content-Security-Policy': 'default-src \'self\' https://cdn.bootcdn.net'
        });
        res.end(html);
    } else {
        res.writeHead(200, {
            'Content-Type': 'application/javascript'
        });
        res.end('console.log("script loaded")');
    }
    }).listen(8000, () => {
        console.log('server is running on port 8000');
    });
    
  • 这样的配置可以使外链脚本不管是本站的还是指定的其他域名脚本都可以访问
  • 如果去除了指定的https://cdn.bootcdn.net,谷歌浏览器一般就会出现这个报错
    Refused to load the script 'https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
    
  • 此时站内脚本可执行,站外脚本被限制了

4 ) form表单的提交限制

  • 上述的设置default-src \'self\'针对表单的跳转是无法限制的,我们稍微修改下程序

  • test.html

    <form action='http://www.taobao.com'>
        <button type='submit'>Click Here</button>
    </form>
    
  • server.js

    const http = require('http')
    const fs = require('fs')
    
    http.createServer(function (req, res) {
    console.log('request comes', req.url)
    if (req.url === '/') {
        const html = fs.readFileSync('test.html', 'utf8')
        res.writeHead(200, {
            'Content-Type': 'text/html',
            'Content-Security-Policy': 'default-src \'self\'; form-action \'self\''
        });
        res.end(html)
    } else {
        res.writeHead(200, {
            'Content-Type': 'application/javascript'
        });
        res.end('console.log("script loaded")');
    }
    }).listen(8000, () => {
        console.log('server is running on port 8000');
    });
    
  • 此时就会出现限制性报错

    Refused to send form data to 'http://www.taobao.com/?' because it violates the following Content Security Policy directive: "form-action 'self'".
    
  • 如果去除了; form-action \'self\' 则无法限制,表单会正常的跳转

  • 更多相关内容可以访问:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP

5 ) 全局限制变成只配置脚本限制

  • 使用default-src进行全局限制会存在一些问题, 比如图片什么的请求可能会不方便
  • 我们只针对脚本作限制,可更改为script-src

6 ) 出现了不安全的情况, 我们可以让其发送请求主动给我们汇报

  • 只需要添加; report-uri /report 即可
  • 如果出现了情况,它会主动向 /report 发送报告数据
  • 我们针对/report的请求做一些程序处理即可
  • 其发送格式如下:
    {
        "csp-report": {
            "blocked-uri": "",
            "disposition": "",
            "document-uri": "",
            "effective-directive": "",
            "original-policy": "",
            "referer": "",
            "line-number": "",
            "script-sample": "",
            "source-file": "",
            "status-code": "",
            "violated-directive": ""
        }
    }     
    
  • blocked-uri 表示策略范围内执行限制的路径
  • disposition 表示强制加载enforce还是允许加载report
    • 一般 Content-Security-Policy 都是强制
    • 如果是Content-Security-Policy-Report-Only 则是允许并报告
  • document-uri 表示当前页面地址
  • effective-directive 表示如何进行限制的
  • original-policy 表示策略的具体内容,就是服务端设置的内容
  • line-number 表示在html中的第几行
  • source-file 表示当前请求的路径
  • status-code 表示请求的状态码

7 ) 除了服务端写Header,还可以在html写meta标签

  • test.html
    <meta http-equiv="Content-Security-Policy" content="script-src 'self'; form-action 'self';">
    
  • server.js 中去除Content-Security-Policy的设置
  • 两者效果一致,但是html中无法设置report-uri指令,只能在服务端来设置
  • 如果存在ajax的请求,可以设置connect-src
  • test.html
    <meta http-equiv="Content-Security-Policy" content="connect-src 'self'">
    <script>
        fetch('http://www.taobao.com'); // 用于限制ajax的示例
    </script>
    
  • 会报这个错误来限制
    Refused to connect to 'http://www.taobao.com/' because it violates the following Content Security Policy directive: "connect-src 'self'".
    Refused to connect to 'http://www.taobao.com/' because it violates the document's Content Security Policy.
    Uncaught (in promise) TypeError: Failed to fetch
    
  • 综上所述,仍推荐服务端来进行设置,可以更灵活更好的设置
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:59:52  更:2022-03-10 23:00:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:46:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码