內容安全性原則(Content Security Policy,CSP)是網路流覽器中實現的一種安全功能,可用於保護網站和Web應用程式免受各種類型的攻擊,如跨站腳本攻擊(XSS)和資料注入攻擊。CSP可控制並限制能夠在網頁上載入或執行的不同類型內容的來源。這些內容類別型包括:
腳本
樣式表
圖片
本文將首先介紹CSP的工作原理。我們會展示一些更有效、更動態地CSP用法,包括在伺服器上進行的一些計算工作。其實我們可以將這些計算轉移到邊緣,從而降低延遲並確保最佳的用戶體驗。我們還將探討這種邊緣計算解決方案的工作原理。
CSP通常是通過在HTTP回應中添加Content-Security-Policy
標頭,從而在伺服器端定義的。這種標頭由Web伺服器發送給請求網頁的用戶,其中指定了流覽器在載入和執行頁面內容時應遵循的規則。
假設我們使用了Node.js中的Express,此時可以這樣設置CSP標頭:
const express = require('express');
const app = express();
app.get('/', (req, res) =\> {
res.set('Content-Security-Policy', 'directive1 value1; directive2 value2; ...');
res.status(200).send('hello world');
});
如果使用Python和Flask,那麼所用代碼如下:
app = Flask(__name__)
\@app.route('/hello', methods=['GET'])
def hello_world():
response = make_response('hello world')
response.headers['Content-Security-Policy'] = 'directive1 value1; directive2
value2; ...'
return response
每個CSP標頭可以包含多個指令(directive),每個指令包含了與所提供的設置類型相關的值。這些指令定義了各種類型資源的安全規則。例如script-src
指令規定了允許的樣式表來源。
請看下面的CSP標頭:
Content-Security-Policy: default-src 'self'; script-src 'self'
https://static.example.com; style-src 'self' 'unsafe-inline';
上述標頭中可以看到三個指令,每個指令都有相應的值。
default-src
指令設置為'self'
,表示預設情況下,所有內容都應從與頁面本身相同的源載入。
script-src
指令允許從同一源('self')
和指定的外部源(https://static.example.com)
載入腳本。
style-src
指令允許從同一源載入樣式表,也允許內聯樣式。
可用指令的清單實際上非常詳盡。其他指令還包括:
font-src
:使用\@font-face
載入字體的原始程式碼。
frame-src
:載入到\<frame\>
和\<iframe\>
等元素中的嵌套流覽上下文的原始程式碼。
img-src
:圖片和我的最愛圖示的來源。
在伺服器上設置了CSP標頭後,流覽器在載入網頁資源時就會執行這些規則。
在HTML原始程式碼中,開發人員可以通過內聯或引用資源(來自同一源或其他源)來添加元素(如腳本或樣式表)。然後,流覽器將檢查CSP標頭,確保這些資源符合定義的規則。如果CSP不允許某項資源,流覽器將阻止其包含和執行。
由於CSP標頭是這樣定義的,因此在對特定網頁的所有請求中,它們通常都是一致的。對單個頁面的每次請求的詳細資訊和指令,在該頁面的每次後續請求中都是相同的。
這就造成了一個有趣問題:如何處理動態的內聯腳本和樣式?我們可能希望允許執行特定內聯腳本和樣式,同時又不願意開放地包含所有內聯腳本和樣式許可權。
這種情況下可以引入nonce值或雜湊值,以確保即使腳本或樣式的來源沒有在CSP中明確列出,只要與CSP標頭指定的nonce值或雜湊值相匹配,就仍然可以執行。
每次請求時,這些nonce值或雜湊值都會發生變化,因此它們是唯一的。所以它們需要在伺服器上生成和管理。雖然需要在伺服器上執行,但並不一定需要在網站的主要伺服器上執行。這就是邊緣計算的用武之地。
邊緣計算本質上是一種概念,即某些計算可以設置在網路外緣運行,在地理位置上更靠近最終用戶。從本質上說,這是一種分散式運算,可以實現更接近即時的計算速度(哪怕跨躍了互聯網),同時還能降低網路延遲。
利用邊緣計算,我們可以將關注點轉移到離最終用戶更近的地方,為CSP標頭生成nonce值或雜湊值,從而減少等待的時間。
CSP會降低網站速度的一個重要原因是:標頭中的nonce會導致緩存丟失,此時客戶的流覽器需要持續訪問伺服器,網站才能正確生成最新標頭。為了解決這個問題,我們可以在邊緣實例中實現動態CSP
nonce生成器。這樣既能確保緩存仍然有用,又能保證安全。
這種方法的優點包括:
降低延遲:邊緣計算實例生成nonce並將其插入請求。這樣,已插入nonce的請求將繼續進入緩存,從而避免每次請求都需要訪問原始伺服器以獲取新回應的情況。
分散式安全性:使用邊緣計算意味著,在客戶需要與系統主要伺服器和應用程式碼交互前,我們就擁有了額外的安全層。即使存在應用程式漏洞,計算CSP
nonce的邊緣計算也能提供額外的安全層,幫助我們減輕潛在的問題。
易於維護:如果採用無伺服器方法在邊緣管理CSP標頭的動態nonce,這將簡化維護任務。特別是可以在不修改應用程式碼的情況下管理CSP策略。通常,我們還可以從中央控制系統管理這類變更,而無需部署任何特殊的代碼。邊緣計算功能還可用于多個獨立應用程式,從而將關注點從為每個應用程式工作的特定團隊中分離出來,並讓安全專業人員確保能生成正確的nonce。
是否有興趣進一步瞭解邊緣計算?歡迎關注Akamai,進一步瞭解Akamai的特色產品和服務,尤其是EdgeWorkers,它可以創建一種無伺服器體驗,完全實現我們在本文中討論的功能,並且無需自行解決如何在網路邊緣部署伺服器的複雜問題。
歡迎註冊免費試用,體驗邊緣計算的強大威力。