我不允許的你不能做-網頁內容安全政策content security policy

前言

今天的資訊安全主題是(content security policy, CSP),也是一種藉由擴充Header的約定,來達成網站安全的目的。

我們會先從同源政策same-origin policy說起,接著提到惡意攻擊者如何成功突破這項限制,並說明常見的漏洞攻擊。

然後我們就會談到什麼是CSP,包括他如何偵測及防範攻擊,以及如何使用的內容。

那就開始吧~

同源政策SOP

為什麼要有同源政策

前面在驗證的環節時候曾說過,不管是什麼應證的方式,都會讓瀏覽器拿到一個類似身分憑證的東西,而伺服器是認證不認人的,而這個東西被儲存在個人的瀏覽器裡面。

假使今天,使用者在瀏覽一個惡意網站,裡面包含一段程式碼寫著,要讀取在你個人瀏覽器內其他網站(銀行、臉書…等)的身分憑證,讀取還不打緊,資料還是在你瀏覽器,他還要把資料傳回他自己的資料庫。

我們這樣看當然是不可以啦,如果有人跟你說他要你查出身分證,然後叫你交給她妳會答應嗎XD但很多在瀏覽器內發生的事情,一般的使用者並不知情,所以也就需要瀏覽器使用一套規則保護使用瀏覽器的使用者。

那到底是用什麼規則保護的?

概念

當我們在瀏覽器Client輸入url瀏覽網頁時,都是在Server取得相對應的資源。不同的網站有他們對應到的Server。

而同源政策的概念就是指,Client端只能呼叫「同源」的資源,而跨來源的資源僅能在特定情況下才允許存取。

再次注意: 以下所有的討論都以瀏覽器Client作為主詞,因為只有瀏覽器為了保護Client有實現這個概念,也因為是由瀏覽器實現的,所以規則多少有些微不同,但大方向是相似的

怎樣叫同源?

同源政策分兩種

  • DOM政策: 決定瀏覽器讀取本地資料、嵌入外地資料、傳送的規則
  • Cookie政策:決定cookie是否回傳給Server的政策

DOM政策

我們用一般狀況禁止,及例外允許的方式來理解DOM政策。

在看待未來的DOM政策時,先判斷是否在一般狀況下,若否,則判斷是否又落於例外。

一般狀況下

  • 相同協定: HTTPS, HTTP…
  • 相同port
  • 相同網域: 嚴格的,不接受子網域

來個表格來比較一下:
對照: https://ithelp.ithome.com.tw/articles/10290526

網址 同源與否 原因
https://ithelp.ithome.com.tw/anything
http://ithelp.ithome.com.tw/articles/10290526 協定不同
https://ithelp.ithome.com.tw:81/articles/10290526 port不同
https://anything.ithelp.ithome.com.tw/articles/10290526 網域不同

例外狀況
以下允許跨來源

  • 寫入: HTML標籤像是form送出(POST), link(GET), redirect(GET)
  • 嵌入: HTML標籤像是script, img, video

特別提一下,禁止讀取,包括:

  • 讀取瀏覽器資料
  • 使用API讀取其他網域的資料

於是前面提到取取瀏覽器內的資料就在這裡被擋住了。

例外中的例外XD
Cookie這個東西照規則在操作的時候只能在同源的狀況下。

但他有一個規則是,如果你在子網域(https://a.example.com)的狀況下,可以修改父網域(https://example.com)的cookie。

會發生什麼呢?如果一個駭客攻破子網域,他在裡面埋了惡意程式,那你在逛子網域的時候就可能惡意修改你存在瀏覽器中父網域的cookie,而瀏覽器也允許。然後你連線母網域的時後就會將cookie帶在身上,造成風險。

不過我在看資料時有兩個問題:

  1. 頂多大規模無法登入?能造成其他危害嗎?XD
  2. 這個例外是為了什麼啊…感覺沒事開了一個口

總之大概知道子網域的安全也是蠻重要的~

Cookie政策

這裡指的是針對瀏覽器內所存放的cookie資料(常是驗證用的資料),並針對將Cookie回傳給Server的行為做出的規範。

關於Cookie傳回,我們只要先理解,為了驗證需要,瀏覽器都會實作一個概念叫做Cookie,讓你每次訪問特定Server時都會帶著特定的Cookie,像是戴著會員卡一樣。

一般而言,邏輯大致和DOM政策相同,不同的地方我加粗是:

  • domain相同
  • 不理會port
  • 可設定是否針對protocol判斷同源

這個政策的設定也是使用Header,詳細我就不多說了XD

CORS: 跨網域資源請求

因為有些服務還是有跨網域做寫入、讀取的需求,也就是跟其他不同源的Server取得服務的需要,特別是網頁在前後分離之後。

所以就需要一個機制去允許有限度的跨網域,我們想像一下有可能的作法:

  1. 由瀏覽器判斷網站裡的資料控制我可以信任誰: 會出現的問題就是惡意網站本身,他可以自由修改信任對象,那同源政策白做了XDD
  2. 由Server決定他的資料可以由誰使用: 沒錯XD由Server透過設定Header決定所謂的「白名單」。

概述他的方式就是

  1. 瀏覽器上的網站在正式發出對於不同源Server的request前會先發一個preflight(預確認),內容包含正式request會用的HTTP Method
  2. Server判斷是否在白名單內,會傳出相對應的Header
  3. 瀏覽器看到Header會決定是否讓瀏覽器顯示

這邊就是關鍵了XD
如果是GET等不用preflight的方法,事實上瀏覽器已經收到資料了,他只是選擇不讓瀏覽器顯示而已。

所以開發者就會發生,明明有POSTMAN或curl都可以成功,但網頁就是出不來的狀況~~

攻破同源政策的攻擊

好不容易談完SOP,我們要接著說SOP並不是完美的,所以才需要擴充的政策去解決被攻擊的狀況。

首先我們要看一下,只有SOP時會怎麼被攻擊:

Cross-Site Scripting, XSS

中文名稱是跨站腳本(可執行的程式碼內容)攻擊。

我們先舉一個例子在定義這個攻擊:

比如今天有一個部落格可以留言,而惡意攻擊者在留言的地方輸入了撰寫了,你有可能覺得很可愛,想要點擊並放大時,就受到攻擊了。
常見網站資安問題與防禦方法(後端角度)

定義就是:

在一個可輸入資料且資料可改變網站內容的網站裡輸入惡意程式碼,導致使用者的損失

如果你覺得這個太淺怎麼會沒事去按(我也這麼覺得),那你可以點開參考資料看更惡意的方式~

總之,他把惡意的內容放在了被SOP允許的範圍內,以至於網頁被瀏覽器執行了,然後使用者就中招了XD

一般來說,前後端都須要做的事情是需要檢驗可輸入內容的位置是否夾帶程式碼並禁止這些行為,不過自從CSP推出後,這件事情變得更容易些。

CSP

概念

剛剛前面提到的XSS攻擊來自於瀏覽器無條件相信網站提供的內容,以至於造成損失。
既然如此,我們是不是可以透過Server告訴瀏覽器,哪些來源的script是足以被信任且可以執行的?

事實上也是這樣,我們再度透過擴展Header的使用約定,來實現這個技術。

使用

使用Content-Security-Policy

其中幾項最重要的原則包括:

  • 最嚴格: 若有多個Content-Security-Policy存在,則個別以最嚴格的條件去看待,不過因為實現的是各瀏覽器,還是實際測試好
  • 規則定義:
    • -src: 各式以-src為結尾的限制;像是image-src, iframe-src
    • navigation: 管理可以打開的連結、或可發出的表單連結
  • report功能: Content-Security-Policy-Report-Only,使用這個功能可以測試及實驗CSP的功能,他僅會回傳報告但不會實際作動

透過這個設定,如果Server對於輸入有沒有篩除到的地方就可以用這個方法在擋下第二層了。

小結

結果我們談SOP比談CSP來的更多XD

但這其實是有意義的,從這樣的脈絡看下來,我們可以發現:

CSP這個技術就是對同源政策SOP的例外再做出約束,主要是希望能在使用性跟安全性上做出客製化的調整。

好啦,今天就這樣囉,明天見!

此文章同步發表於部落格,歡迎來逛逛~

參考資料

Content Security Policy (CSP)
Content security policy
網站安全🔒 Same Origin Policy 同源政策 ! 一切安全的基礎
【Web】徹底理解同源政策(Same Origin Policy)
常見網站資安問題與防禦方法(後端角度)