邊緣CSP:降低延遲的同時(shí)保證安全性
內(nèi)容安全策略(Content Security Policy,CSP)是網(wǎng)絡(luò)瀏覽器中實(shí)現(xiàn)的一種安全功能,可用于保護(hù)網(wǎng)站和Web應(yīng)用程序免受各種類型的攻擊,如跨站腳本攻擊(XSS)和數(shù)據(jù)注入攻擊。CSP可控制并限制能夠在網(wǎng)頁上加載或執(zhí)行的不同類型內(nèi)容的來源。這些內(nèi)容類型包括:
- 腳本
- 樣式表
- 圖片
延伸閱讀,點(diǎn)擊鏈接了解 Akamai API Security
本文將首先介紹CSP的工作原理。我們會展示一些更有效、更動態(tài)地CSP用法,包括在服務(wù)器上進(jìn)行的一些計(jì)算工作。其實(shí)我們可以將這些計(jì)算轉(zhuǎn)移到邊緣,從而降低延遲并確保最佳的用戶體驗(yàn)。我們還將探討這種邊緣計(jì)算解決方案的工作原理。
CSP的工作原理
CSP通常是通過在HTTP響應(yīng)中添加Content-Security-Policy標(biāo)頭,從而在服務(wù)器端定義的。這種標(biāo)頭由Web服務(wù)器發(fā)送給請求網(wǎng)頁的用戶,其中指定了瀏覽器在加載和執(zhí)行頁面內(nèi)容時(shí)應(yīng)遵循的規(guī)則。
1.Content-Security-Policy標(biāo)頭范例
假設(shè)我們使用了Node.js中的Express,此時(shí)可以這樣設(shè)置CSP標(biāo)頭:
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
2.使用指令
每個(gè)CSP標(biāo)頭可以包含多個(gè)指令(directive),每個(gè)指令包含了與所提供的設(shè)置類型相關(guān)的值。這些指令定義了各種類型資源的安全規(guī)則。例如script-src指令規(guī)定了允許的樣式表來源。
請看下面的CSP標(biāo)頭:
Content-Security-Policy: default-src 'self'; script-src 'self' https://static.example.com; style-src 'self' 'unsafe-inline';
上述標(biāo)頭中可以看到三個(gè)指令,每個(gè)指令都有相應(yīng)的值。
- default-src指令設(shè)置為'self',表示默認(rèn)情況下,所有內(nèi)容都應(yīng)從與頁面本身相同的源加載。
- script-src指令允許從同一源('self')和指定的外部源(https://static.example.com)加載腳本。
- style-src指令允許從同一源加載樣式表,也允許內(nèi)聯(lián)樣式。
可用指令的列表實(shí)際上非常詳盡。其他指令還包括:
- font-src:使用@font-face加載字體的源代碼。
- frame-src:加載到<frame>和<iframe>等元素中的嵌套瀏覽上下文的源代碼。
- img-src:圖片和收藏夾圖標(biāo)的來源。
3.將CSP與HTML相結(jié)合
在服務(wù)器上設(shè)置了CSP標(biāo)頭后,瀏覽器在加載網(wǎng)頁資源時(shí)就會執(zhí)行這些規(guī)則。
在HTML源代碼中,開發(fā)人員可以通過內(nèi)聯(lián)或引用資源(來自同一源或其他源)來添加元素(如腳本或樣式表)。然后,瀏覽器將檢查CSP標(biāo)頭,確保這些資源符合定義的規(guī)則。如果CSP不允許某項(xiàng)資源,瀏覽器將阻止其包含和執(zhí)行。
4.每次請求中的唯一性
由于CSP標(biāo)頭是這樣定義的,因此在對特定網(wǎng)頁的所有請求中,它們通常都是一致的。對單個(gè)頁面的每次請求的詳細(xì)信息和指令,在該頁面的每次后續(xù)請求中都是相同的。
這就造成了一個(gè)有趣問題:如何處理動態(tài)的內(nèi)聯(lián)腳本和樣式?我們可能希望允許執(zhí)行特定內(nèi)聯(lián)腳本和樣式,同時(shí)又不愿意開放地包含所有內(nèi)聯(lián)腳本和樣式權(quán)限。
這種情況下可以引入nonce值或哈希值,以確保即使腳本或樣式的來源沒有在CSP中明確列出,只要與CSP標(biāo)頭指定的nonce值或哈希值相匹配,就仍然可以執(zhí)行。
每次請求時(shí),這些nonce值或哈希值都會發(fā)生變化,因此它們是唯一的。所以它們需要在服務(wù)器上生成和管理。雖然需要在服務(wù)器上執(zhí)行,但并不一定需要在網(wǎng)站的主服務(wù)器上執(zhí)行。這就是邊緣計(jì)算的用武之地。
邊緣計(jì)算是什么?
邊緣計(jì)算本質(zhì)上是一種概念,即某些計(jì)算可以設(shè)置在網(wǎng)絡(luò)外緣運(yùn)行,在地理位置上更靠近最終用戶。從本質(zhì)上說,這是一種分布式計(jì)算,可以實(shí)現(xiàn)更接近實(shí)時(shí)的計(jì)算速度(哪怕跨躍了互聯(lián)網(wǎng)),同時(shí)還能降低網(wǎng)絡(luò)延遲。
利用邊緣計(jì)算,我們可以將關(guān)注點(diǎn)轉(zhuǎn)移到離最終用戶更近的地方,為CSP標(biāo)頭生成nonce值或哈希值,從而減少等待的時(shí)間。
1.邊緣計(jì)算如何讓CSP受益
CSP會降低網(wǎng)站速度的一個(gè)重要原因是:標(biāo)頭中的nonce會導(dǎo)致緩存丟失,此時(shí)客戶的瀏覽器需要持續(xù)訪問服務(wù)器,網(wǎng)站才能正確生成最新標(biāo)頭。為了解決這個(gè)問題,我們可以在邊緣實(shí)例中實(shí)現(xiàn)動態(tài)CSP nonce生成器。這樣既能確保緩存仍然有用,又能保證安全。
這種方法的優(yōu)點(diǎn)包括:
- 降低延遲:邊緣計(jì)算實(shí)例生成nonce并將其插入請求。這樣,已插入nonce的請求將繼續(xù)進(jìn)入緩存,從而避免每次請求都需要訪問源服務(wù)器以獲取新響應(yīng)的情況。
- 分布式安全性:使用邊緣計(jì)算意味著,在客戶需要與系統(tǒng)主服務(wù)器和應(yīng)用程序代碼交互前,我們就擁有了額外的安全層。即使存在應(yīng)用程序漏洞,計(jì)算CSP nonce的邊緣計(jì)算也能提供額外的安全層,幫助我們減輕潛在的問題。
- 易于維護(hù):如果采用無服務(wù)器方法在邊緣管理CSP標(biāo)頭的動態(tài)nonce,這將簡化維護(hù)任務(wù)。特別是可以在不修改應(yīng)用程序代碼的情況下管理CSP策略。通常,我們還可以從中央控制系統(tǒng)管理這類變更,而無需部署任何特殊的代碼。邊緣計(jì)算功能還可用于多個(gè)獨(dú)立應(yīng)用程序,從而將關(guān)注點(diǎn)從為每個(gè)應(yīng)用程序工作的特定團(tuán)隊(duì)中分離出來,并讓安全專業(yè)人員確保能生成正確的nonce。
總結(jié)
是否有興趣進(jìn)一步了解邊緣計(jì)算?歡迎關(guān)注Akamai官網(wǎng),進(jìn)一步了解Akamai的特色產(chǎn)品和服務(wù),尤其是EdgeWorkers,它可以創(chuàng)建一種無服務(wù)器體驗(yàn),完全實(shí)現(xiàn)我們在本文中討論的功能,并且無需自行解決如何在網(wǎng)絡(luò)邊緣部署服務(wù)器的復(fù)雜問題。
—————————————————————————————————————————————————
如您所在的企業(yè)也想要進(jìn)一步保護(hù)API安全,
點(diǎn)擊鏈接 了解Akamai的解決方案