CSP: Content-Security-Policy詳解

前言

跨域腳本攻擊(XSS)是最常見、危害最大的網頁安全漏洞。

為了防止它,要采取很多編程措施(比如大多數人都知道的轉義、過濾HTML)。很多人提出,能不能根本上解決問題,即瀏覽器自動禁止外部注入惡意腳本?

這就是"內容安全策略"(Content Security Policy,縮寫 CSP)的由來。

兩種方法可以啟用 CSP:

  • 設置 HTTP 的 Content-Security-Policy 頭部字段
  • 設置網頁的<meta>標簽。

網上的資料都有講到它們怎么使用,但是很少有代碼演示,不敲一遍就不夠理解,下面我會直接上些例子。

(1)使用HTTP的 Content-Security-Policy頭部

在服務器端使用 HTTP的 Content-Security-Policy頭部來指定你的策略,像這樣:

Content-Security-Policy: policy

policy參數是一個包含了各種描述CSP策略指令的字符串。

例1 禁止內聯js、css
// index.html

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<script type="text/javascript">
    console.log('inline js.');
</script>
</body>
</html>
// index.js
const http = require('http');
const fs = require('fs');
http.createServer((req, res) => {
        const html = fs.readFileSync('index.html', 'utf8');
        res.writeHead(200, {
            'Content-Type': 'text-html',
            'Content-Security-Policy': 'default-src http: https:' 
        });
        res.end(html);
}).listen(9000);

console.log('server listening on 9000');

上面代碼使用原生nodejs起了個服務,然后設置響應頭部
'Content-Security-Policy': 'default-src http: https:'

表示只能通過外聯的方式來引用js和css,如果使用內聯的將報錯:

image.png
    <style type="text/css">
        * { background-color: red; }
    </style>
image.png
例2

只能在指定的域下加載文件,這里表示只能從同域下加載,斜杠為轉義符:
'Content-Security-Policy': 'default-src \'self\''

<script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
image.png

打開控制臺也可以看到請求在瀏覽器就已經被限制了:


image.png

如果要允許請求到這個域,添加進策略即可:

'Content-Security-Policy': 'default-src \'self\' https://cdn.bootcss.com/' 
例3

上面的策略是無法限制form表單的提交的,如下列表單,點擊后直接跳到了百度頁面:

    <form action="https://baidu.com">
        <button>click me</button>
    </form>

這時候就要設置form-action策略:

'Content-Security-Policy': 'default-src \'self\' https://cdn.bootcss.com/; form-action \'self\''
image.png
例4

在例子1中,設置了default-src的限制,這時img的src也會受到限制。

<img src="https://www.baidu.com/img/baidu_jgylogo3.gif">

image.png

default-src設置的是全局,如果我只想限制js的請求,可以將default-src改為script-src

(2) 啟用違例報告

默認情況下,違規報告并不會發送。為啟用發送違規報告,你需要指定 report-uri策略指令,并提供至少一個URI地址去遞交報告:

'Content-Security-Policy': 'script-src \'self\'; report-uri /report'

這里的報告我們可以直接在瀏覽器看到,它會自動發送一個請求出去:


image.png

如果我只想收集報告,但是不真正的去限制請求,那怎么辦?除了Content-Security-Policy,還有一個Content-Security-Policy-Report-Only字段,表示不執行限制選項,只是記錄違反限制的行為。將頭部改為這個即可。

(3)使用meta標簽

以上規則可以在瀏覽器端設置,如:

<meta http-equiv="Content-Security-Policy" content="form-action 'self';">

效果是一樣的!現在終于理解了meta標簽 http-equivcontent 屬性的意思了,TT。。。

但與服務器端設置有點不同的是,meta無法使用report,這樣只能在服務器端設置了:

image.png
總結

可以看到,一經設置Content-Security-Policy,對加載外部腳本限制較為嚴格。這個東西好不好用呢?似乎使用的人不多,目前我知道有知乎和github在用。

參考

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP
http://www.ruanyifeng.com/blog/2016/09/csp.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,837評論 18 139
  • https://www.html5rocks.com/en/tutorials/security/content-...
    謝大見閱讀 5,721評論 0 3
  • 今天在瀏覽微信頁面的時候,發現他的script標簽上都有個once屬性,好奇之下查閱了一番,發現這個屬性是和一個h...
    牧羊童鞋閱讀 51,845評論 5 14
  • 做ease庫判斷opacity有了疑問查詢結果: 較為簡潔的辦法是 擴展所有屬性檢測 參考鏈接Check whet...
    前端歷險記閱讀 336評論 0 0
  • 暑假即將過去,抓著假期的尾巴帶著孩子去海邊走走。汕尾紅海灣沙灘,水清沙幼,十分適合玩。
    江夏月閱讀 283評論 0 0