
授權(quán)與合規(guī)聲明本文全部操作對象均為自建隔離靶場本機容器或隔離虛擬機涉及安全測試的環(huán)節(jié)必須以取得合法授權(quán)為前提。未經(jīng)授權(quán)的滲透測試違反《中華人民共和國網(wǎng)絡(luò)安全法》與《刑法》相關(guān)條款須承擔相應(yīng)法律責任。本文只講環(huán)境配置、版本對照與靶場隔離不含任何攻擊步驟、利用載荷與繞過手法請勿將文中環(huán)境指向任何非自有系統(tǒng)。一、先分清 CSP 管的是「加載」還是「執(zhí)行」1.1 兩行一模一樣的頭兩個不一樣的結(jié)果先說一個具體的場面。有人在自建靶場里給站點加 CSP加得很樸素nginx 里多寫一行add_header。加完打開兩個頁面A 頁面圖表區(qū)整塊白了B 頁面同一個模板圖表正常。他把兩邊的響應(yīng)頭抓下來逐字比對那一行完全相同。頭一樣結(jié)果不一樣于是他判斷是瀏覽器實現(xiàn)有差異。這個判斷是錯的而錯的地方不在瀏覽器。差別在 B 頁面的模板里——那是一份舊模板里面還留著一條script-src。因為這條script-src存在A 頁面那行default-src在 B 頁面對腳本請求的判定里根本沒有參與。它不是總開關(guān)只填空缺同一條頭給出兩種結(jié)果不是瀏覽器不一致是兩條策略里「空缺」的位置不同。出處先說清本文引用 W3C《Content Security Policy Level 3》。截至 2026-10-25它的狀態(tài)是W3C Working Draft日期 2026-09-16地址https://www.w3.org/TR/CSP3/。它是工作草案不是 Recommendation條文還會改所以本文每處原文只對 2026-09-16 這一版負責。1.2 一條策略里混著四種東西很多人把 CSP 當成一份資源白名單。這個印象在早期版本勉強夠用放到 Level 3 就不夠了一條策略里的指令按作用對象至少分成四類。類別管的問題本文涉及的指令有default-src兜底嗎fetch 指令某一類請求能不能發(fā)出去script-src-elem、script-src-attr、img-src、connect-src、font-src、object-src有文檔指令文檔自身的某些行為受不受限base-uri、sandbox沒有導(dǎo)航指令誰能嵌我、我能往哪里提交frame-ancestors、form-action沒有上報指令違規(guī)信息往哪里送report-uri、report-to沒有最右一列是全文的骨架只有第一類有兜底后三類沒有。default-src的覆蓋范圍比多數(shù)人以為的窄得多——它只管「請求發(fā)不發(fā)得出去」不管「這份文檔能不能被嵌」。分類不是按危險程度分的是按判定發(fā)生在哪一刻分的fetch 指令在請求發(fā)起前判定手里有一個目標 URL 可比對導(dǎo)航指令沒有這個 URLframe-ancestors判的是「能不能被某個祖先嵌進去」也就無從兜底。1.3 「我加了 CSP」這句話本身沒有信息量要判斷一條 CSP 在做什么至少問清三件事。加在哪里。響應(yīng)頭還是meta元素——meta裝不下某些指令第六章。加了幾條。一個響應(yīng)可以有多條策略頭多條之間不是「后一條覆蓋前一條」第三章。每條里寫了哪些指令。寫了哪幾條 fetch 指令剩下的才輪到default-srcnone那處的列表是否真為空Report-Only 那條是否根本沒在攔第二、五、四章。少問一個結(jié)論就可能反過來。本章可以帶走的一句CSP 不是一份資源白名單而是按請求類型分開判的一組規(guī)則說「我加了 CSP」信息量等于零。二、誤解一把default-src當成總開關(guān)2.1 「no inheritance」這五個字要讀三遍規(guī)范講這件事只用了一句話位置很不起眼但它是否掉后面一半誤讀的鑰匙There is no inheritance. If a script-src directive is explicitly specified, for example, then the value of default-src has no influence on script requests.兩個詞要抓住。no inheritance這里沒有繼承。has no influence不是影響變小不是優(yōu)先級更低是沒有任何影響。我們平時說「默認值」模型是繼承子級沒寫用父級寫了用自己父級還在那兒放著。CSP 不是這個模型它是填表沒填的格子default-src幫你填上填過的它連看都不看。Content-Security-Policy: default-src self; script-src https://cdn.example.com??代碼待驗證這條策略有兩處容易讀錯。第一script-src這一格被填過了default-src從此不參與腳本判定。腳本的放行范圍只有「https://cdn.example.com」self不在里面——它不允許加載同源腳本。寫它的人想的是「同源照舊再加一個 CDN」按規(guī)范語義做的是「把腳本源換成 CDN 一個域」。第二default-src剩下的權(quán)力還在圖片、字體、樣式、連接、媒體、對象沒被單獨填仍由它兜著。所以在本條策略內(nèi)部再寫一條script-src是替換不是疊加。這和「多寫一條更保險」的直覺正好相反。2.2 規(guī)范給的等價寫法里沒有script-srcdefault-src self等價于什么規(guī)范直接給了展開式值得原樣抄一遍Content-Security-Policy: connect-src self; font-src self; frame-src self; img-src self; manifest-src self; media-src self; object-src self; script-src-elem self; script-src-attr self; style-src-elem self; style-src-attr self; worker-src self??代碼待驗證一共 12 項序號等價清單里的指令它管的是哪一類請求1connect-src腳本發(fā)起的連接XHR、WebSocket 這一類2font-src字體文件3frame-src這一頁里嵌進去的子框架4img-src圖片5manifest-srcWeb App Manifest6media-src音頻與視頻7object-src插件類對象8script-src-elem腳本元素9script-src-attr元素上的內(nèi)聯(lián)腳本屬性10style-src-elem樣式元素11style-src-attr元素上的內(nèi)聯(lián)樣式屬性12worker-srcWorker 類腳本有一個必須原樣保留、不能「順手改對」的細節(jié)清單里是script-src-elem和script-src-attr不是script-src是style-src-elem和style-src-attr不是style-src。因為在這套判據(jù)里「腳本」本來就不是一個東西是兩個腳本元素和內(nèi)聯(lián)腳本屬性走兩條判定路徑各有各的指令。script-src不在清單里是因為它在這套結(jié)構(gòu)里統(tǒng)管這兩者不是被統(tǒng)管的一項——把它展開進清單會把兩層壓成一層。實際影響有兩處。想單獨管住內(nèi)聯(lián)腳本屬性有專門的指令可用不必動整體。排查時看報告里的effective-directive寫script-src-attr說明問題出在屬性上寫script-src-elem才是腳本元素改法完全不同。script-src與這兩條如何回落需要另開一篇本篇只把「清單是四位不是兩位」釘住。2.3 它兜不到的東西比兜得到的更值得記default-src只是 fetch 指令的兜底。規(guī)范的措辭很干脆frame-ancestors、base-uri、form-action、sandbox、report-urireport-to這些都不在 fetch 指令的兜底范圍內(nèi)。這五條里最容易誤解的是frame-ancestors。有人寫default-src none覺得「什么都禁了肯定也沒法被嵌了」。實際是外部資源全加載不了但被別的站點用框架嵌進來這件事一點沒受影響——「我能加載誰」和「誰能嵌我」是兩個方向。還有一處更細的例外prefetch、preconnect 這類資源提示請求不歸任何單一條 fetch 指令管而是「governed by the union of servers allowed in all of a policy’s directives’ source lists」——由這條策略里所有指令源列表允許的服務(wù)器的并集來管。后面還跟了一句更要緊的沒寫default-src時這類請求「will always be allowed」。所以只寫了img-src的策略對 prefetch 完全不管。CSP 逐條生效沒寫到的地方就是沒寫到。本章可以帶走的一句default-src只填空缺不覆蓋已寫它管的是 fetch 指令管不到文檔、導(dǎo)航和上報也管不住 prefetch 這類資源提示。三、誤解二多條策略取「誰更寬」3.1 兩條頭不是兩套方案是兩道閘第二個高頻誤讀出在多條策略并存時網(wǎng)關(guān)加一條寬的應(yīng)用加一條嚴的最后應(yīng)該以應(yīng)用那條為準或者后加的覆蓋先加的。規(guī)范說得明白Enforcing both policies means that a potential connection would have to pass through both unscathed.adding additional policies to the list of policies to enforce can only further restrict the capabilities of the protected resource.第一句給判據(jù)一個連接要「毫發(fā)無傷地穿過兩條」。第二句給方向增加策略只能進一步限制不可能放寬。合起來就是一個詞——交集。「兩個都過」聽起來溫和后果經(jīng)常不溫和。網(wǎng)關(guān)寫default-src self應(yīng)用寫default-src self; img-src https://img.example.com后者看起來更寬但交集之后圖片域只在應(yīng)用那條里成立網(wǎng)關(guān)仍只認同源圖片照樣加載不了。要放寬只能改第一條本身或者撤掉它。3.2 腳本那句話最短也最容易被跳過交集這件事規(guī)范在腳本這里給了一句最短的話Script will only load if it meets both policy’s criteria.短但藏了一個順序問題正是本章與第二章的接縫?!竷蓷l都要滿足」?jié)M足的是各自展開之后的判據(jù)每條策略先用自己的指令填空缺第二章形成完整判據(jù)再取交集本章。順序決定排查的第一步動作不能跨策略借用。A 策略寫了script-src、B 策略沒寫但有default-src那么 B 對腳本的判據(jù)來自它自己的default-src不來自 A 的script-src。報告若不指明觸發(fā)的是哪條策略就得把每條單獨展開一遍。3.3 兩個后果都不輕白屏來得莫名其妙。兩條頭分開看都沒問題合起來不允許這時單改任何一條都改不動。判斷方法很簡單臨時去掉其中一條看頁面是否恢復(fù)。你看到的頭可能不是用戶拿到的頭。規(guī)范有一句容易被忽略同一資源的不同表示可以帶不同的策略——「A server MAY send different Content-Security-Policy header field values with different representations of the same resource」。落地后果是多機房、灰度、緩存變體都可能讓同一個 URL 帶不同的頭。本章可以帶走的一句多條策略是取交集只有收緊一條路把「再加一條寬一點的」當成補丁方向一開始就反了。四、誤解三把 Report-Only 當成「先開著看看會不會攔」4.1 它在判定里是被跳過的不是被降級的這個誤讀最容易出在灰度上線先用 Report-Only 發(fā)出去觀察沒問題再切成強制。流程對錯的是理解——很多人以為它是「軟性攔截」攔還是會攔只是不顯示、只上報。規(guī)范在判定算法里給了一句很硬的話If policy’s disposition is “report”, then skip to the next policy.skip to the next policy——跳過看下一條。這句在判定循環(huán)內(nèi)部也就是說disposition為report的策略在「要不要攔這個請求」這個判斷里根本沒被問過。不是「問了但答案被忽略」是「沒問」。由此帶出一個直接連著第三章的推論一條 Report-Only 策略不參與交集。它在取交集之前就被跳過了既不放寬也不收緊。寫一條比 enforce 更嚴的頁面行為不會有任何變化寫一條更寬的也一樣。拿「加了 Report-Only 頁面還是白的」說明「兩條策略取了交集」是把兩件事搞混白屏一定來自 enforce 那條。4.2 它能回答什么不能回答什么能回答的這條策略的語法能不能被接受如果切成強制哪些請求會被擋上報通道通不通。不能回答的擋下來之后業(yè)務(wù)還能不能跑。這是它最大的盲區(qū)。一個被擋的請求在 Report-Only 階段是「一條報告」在 enforce 階段是「一個功能壞了」——隔的不是程度是性質(zhì)?!笀蟾胬餂]有關(guān)鍵請求」推不出「切成強制沒問題」風險恰恰常在「被攔了但沒人知道那是個關(guān)鍵請求」這一側(cè)報告數(shù)量本身也受采樣與去重影響不能當風險分數(shù)用。4.3 從「只報」到「真攔」四步的順序不能亂對比項Content-Security-PolicyContent-Security-Policy-Report-Only處置dispositionenforcereport是否參與攔截判定參與不參與判定時被跳過是否阻斷請求會阻斷不阻斷是否與其他策略取交集會不會能否寫在meta里能不能主要用途執(zhí)行策略觀察這條策略會攔什么第一步先只報內(nèi)容與將來 enforce 的那條逐字相同。差一個字觀察結(jié)果就不作數(shù)。常見錯誤是「Report-Only 里先不寫那么嚴」觀察到的就不是將來要上線的策略。第二步收集一段時間把「會攔」的請求按指令歸類。單位是指令不是 URL因為改法跟著指令走img-src改圖床connect-src改接口域名script-src-attr得改代碼。第三步拿歸類結(jié)果去改業(yè)務(wù)而不是回頭改策略。報告一出來就想著把域名補進策略當然能消掉報告但抹掉的是觀察結(jié)果不是問題。第四步切成 enforce上報通道保留。保留上報不是可選項enforce 之后仍會有新頁面帶來新違規(guī)沒有上報只能等用戶反饋。本章可以帶走的一句Report-Only 是「不攔、只記」它在判定里被直接跳過連交集都不參與把它當成「軟性攔截」是最常見的一處誤讀。五、誤解四none并列、空指令、重定向路徑5.1none不是加鎖是表示「列表為空」第四個誤讀藏在寫法層面策略看著更嚴了實際更松了。The ‘none’ keyword has no effect when other source expressions are present. That is, the list ? ‘none’ ? does not match any URL. A list consisting of ? ‘none’, https://example.com ?, on the other hand, would match https://example.com/.拆成兩句讀。第一句說none和其他源表達式同時存在時沒有效果。第二句給對照? none ?匹配不了任何 URL而? none, https://example.com ?會匹配https://example.com/。源列表內(nèi)部是「或」的關(guān)系任一項匹配即匹配。none永遠匹配不上是恒假項恒假項和別的項做「或」結(jié)果等于別的項——它被吸收了。這不是「加了一道鎖」是「寫了一個不生效的項」。有人為了保險把none和允許的域并列期待「既允許這個域又禁止別的」實際是「只允許這個域none那句白寫」。結(jié)果一樣但理解錯了下一步會出問題他可能又往里加一個域以為none會攔住它。寫法源列表里實際有什么結(jié)果script-src none只有none一項任何 URL 都不匹配全部攔下script-src none https://example.comnone加一個主機源等價于只寫了example.comscript-src空等價于none任何 URL 都不匹配script-src self一個關(guān)鍵字源同源可加載第三行是下一節(jié)的主角。5.2 空指令是最像「沒寫」的「全禁」An empty source list (that is, a directive without a value: script-src, as opposed to script-src host1) is equivalent to a source list containing ‘none’, and will not match any URL.沒有值的指令等價于源列表里只有none。注意方向空不等于「沒寫」空等于「全禁」。這個語義危險是因為它在配置文件里長得太像「沒配」Content-Security-Policy: script-src self https://cdn.example.com Content-Security-Policy: script-src none https://cdn.example.com Content-Security-Policy: script-src??代碼待驗證第一種正常。第二種里none白寫等價于第一種去掉self。第三種最要命語法合法、語義全禁而掃一眼都像「這一行什么都沒寫」。工程上它幾乎總是從模板變量來的。script-src {{ .ScriptSources }}在變量有值時正常為空時渲染出script-src語法合法、語義全禁、頁面白屏而模板文件里看不出異常。排查這類問題第一件事是把渲染后的頭發(fā)出來看而不是讀模板。還有一種反向誤解以為「寫了指令名就算設(shè)了一條規(guī)則」。按上面那句原文它設(shè)的是一條全禁規(guī)則。指令名的存在只說明這一格被填了填進去的是空。5.3 重定向之后路徑那一段不再參與判定the matching algorithm ignores the path component of a source expression if the resource being loaded is the result of a redirect配套例子是img-src example.com example.org/path。讀法是源表達式可以帶路徑主機部分一直有效路徑部分只在直接命中時有效一旦這次加載是重定向的結(jié)果路徑部分就被忽略。這是判定規(guī)則不是技巧本文只講讀法。實際影響很具體寫https://static.example.com/assets/想表達「只允許這個目錄」它在重定向場景下退化成「允許static.example.com整個主機」。你以為限定到了一個目錄實際是一個主機。由此有一條紀律不要用源表達式里的路徑來表達安全邊界。路徑只能表達直接請求時的前綴真要限制到目錄那是服務(wù)端的事。完整版對照資料這份資料把 CSP3 工作草案里 fetch 指令、文檔指令、上報指令的歸屬逐條列成一張對照表和本章「哪條指令歸誰管、哪條有兜底」是同一套骨架可以直接拿去核自己站點的那幾條頭。放在資料包里掃碼即可獲取本章可以帶走的一句none只在列表為空時有意義空列表等于none源表達式里的路徑是最不可靠的那一段重定向一發(fā)生它就不作數(shù)了。六、部署位置和頭之間的關(guān)系也會改結(jié)論6.1meta裝不下三樣?xùn)|西也裝不下 Report-Only前五章講「策略里寫了什么」這一章講「寫在哪里」——位置本身帶限制。The Content-Security-Policy-Report-Only header is not supported inside a meta element. Neither are the report-uri, frame-ancestors, and sandbox directives.一句話里四個「不行」Report-Only 整個不支持report-uri、frame-ancestors、sandbox三個指令不支持。共同點是meta是文檔自己說的話而有些判斷必須在文檔說話之前完成。frame-ancestors最典型。它判的是「這個文檔能不能被某個祖先嵌進來」這個判斷發(fā)生在解析之前——瀏覽器得先決定要不要把它放進那個框。而meta是解析到那一行才被讀到的那時框已經(jīng)建好了。所以它寫在meta里不是「不推薦」是「讀不到」。能力響應(yīng)頭meta元素Report-Only 策略支持不支持report-uri支持不支持frame-ancestors支持不支持sandbox支持不支持report-to支持不在上述限制的列舉范圍內(nèi)本文不進一步推斷解析后修改是否生效不適用響應(yīng)到達時已固定不生效生效時機響應(yīng)到達即生效元素被解析時生效越靠前越好倒數(shù)第三行是有意留白那句限制只點了三個指令加一個頭類型沒把report-to列進去但「沒列進禁止名單」和「確定可用」是兩件事。6.2meta的時機、重復(fù)指令、大小寫Modifications to the content attribute of a meta element after the element has been parsed will be ignored.元素解析完成后再改content屬性改動被忽略。規(guī)范順帶建議meta盡量靠前寫。這條對應(yīng)一類很隱蔽的問題有人在腳本里按環(huán)境動態(tài)改content本地看著生效改動發(fā)生在解析之前上線后不生效兩邊代碼一模一樣。判斷方法只有一個看最終解析出來的那份策略不看 DOM 里現(xiàn)在的content值。指令名大小寫不敏感。原話「script-SRC ‘none’ and ScRiPt-sRc ‘none’ are equivalent」。按大小寫精確匹配script-src搜配置或日志會漏掉寫成Script-Src的那些。同一條策略里重復(fù)的指令只取第一個其余忽略。規(guī)范有一個 Note 建議瀏覽器在這種情況下給控制臺警告但那只是建議。Content-Security-Policy: script-src self; img-src self; script-src https://cdn.example.com??代碼待驗證這里script-src出現(xiàn)兩次。第二條不合并、不覆蓋它被整條忽略。效果是「腳本只認同源」那個 CDN 域等于沒寫。所以排查時要按出現(xiàn)順序數(shù)而不是找到一個匹配項就停。6.3 同一個響應(yīng)里兩個頭誰說了算最后說一處「頭與頭之間」的關(guān)系理解錯了會做出「多加一個更保險」這種反向操作。the frame-ancestors directive overrides the X-Frame-Options header覆蓋。只要有 enforce 狀態(tài)的frame-ancestors出現(xiàn)在響應(yīng)里X-Frame-Options就被忽略。不是「兩個都生效取交集」是「前者作數(shù)后者不作數(shù)」。兩者是粗略換算none大致相當于DENYself大致相當于SAMEORIGIN。所以「兩個都加更保險」在這里明確是錯的frame-ancestors寫寬了那個更嚴的X-Frame-Options不會來兜底。你以為加了兩道鎖實際是把嚴的那道換成了寬的。最后補一句report-uri的結(jié)論它已被report-to取代原話是「The report-uri directive is deprecated in favor of the new report-to directive, which relies on [REPORTING] as infrastructure」。這也屬于替代關(guān)系——新的生效舊的按廢棄處理不會疊加。本章可以帶走的一句部署位置決定哪些指令能被讀到頭與頭之間是覆蓋不是疊加「多加一個更保險」在 CSP 里經(jīng)常恰好相反。七、一份可執(zhí)行的自查順序7.1 七步按順序走前面六章拆了四個誤讀落到操作上需要順序后面的結(jié)論依賴前面的結(jié)果不先數(shù)清有幾條策略就談不上「哪條在攔」。第 1 步 數(shù)清有幾條策略響應(yīng)頭里幾條 Content-Security-Policy頁面里幾個 meta 第 2 步 每條策略單獨展開把寫了的 fetch 指令標出來剩下的才歸 default-src 第 3 步 每條策略單獨看 none有沒有和別的源并列有沒有空值指令 第 4 步 分清哪條是 enforce、哪條是 Report-Only后者不計入交集 第 5 步 確認部署位置寫在頭里還是 meta 里用到的指令 meta 收不收 第 6 步 按出現(xiàn)順序數(shù)重復(fù)指令同一條策略里第一條生效后面的忽略 第 7 步 最后再看上報報告里 effective-directive 落在哪一條決定改法??代碼待驗證七步里有三個「先別看」的位置。第 2 步之前別看頁面表現(xiàn)。白屏和「哪條策略在攔」之間隔著好幾層可能是交集可能是空指令可能是default-src被替換掉了。第 5 步之前別改策略。策略寫在meta里而你改的是frame-ancestors改一百次也不會生效。第 7 步之前別信報告。報告只說哪個請求被攔了不說「這條策略是不是你要的那條」。被忽略的重復(fù)指令不產(chǎn)生報告Report-Only 的報告看起來和 enforce 的一樣。7.2 四條誤讀并到一張表里被讀錯的點規(guī)范里的實際語義自查時先做什么default-src是總開關(guān)無繼承寫了script-src之后default-src對腳本零影響第 2 步標出每條策略里已寫的 fetch 指令多條策略取更寬的那條取交集增加策略只能收緊第 1 步數(shù)清策略條數(shù)別只抓一次頭Report-Only 是軟性攔截disposition為 report 時在判定里被跳過不參與交集第 4 步先分清哪條在攔none是一種更嚴的寫法與其他源并列時無效果空源列表等價于none第 3 步逐條看源列表是否真的為空概括成一句四條誤讀共用一個形狀——把「沒生效的部分」當成了「生效的部分」。default-src在寫了具體指令后不生效none在并列時不生效Report-Only 在攔截上不生效重復(fù)的第二條指令不生效。你以為它在管其實它沒被問到。7.3 這套規(guī)則以后會變嗎會。這是這一節(jié)唯一想強調(diào)的。本文所有原文都來自 CSP3 的 2026-09-16 工作草案。它是 Working Draft不是 Recommendation開頭說過結(jié)尾再說一次因為它決定這份筆記的保質(zhì)期草案條文會改改的時候不發(fā)通知??蛇w移的不是這些句子是讀的方法——先確認版本再確認這段說的是哪個階段解析、判定、上報最后確認它管哪一類請求。規(guī)范對開發(fā)者還有一句明確建議可以直接照做developers SHOULD NOT include either ‘unsafe-inline’, or data: as valid sources in their policies. Both enable XSS attacks by allowing code to be included directly in the document itself措辭是 SHOULD NOT建議而非禁止但它給的是一個很硬的性質(zhì)判斷這兩個源會把「代碼能不能進到文檔」這道門整個打開。至于它們在有其他放行機制時如何被處理本文不寫——本批沒核到可直接引用的原文寫出來就是替規(guī)范說話。strict-dynamic按規(guī)范 §8.2 的描述是一種針對 non-parser-inserted 腳本元素的放行機制。這句只作概念說明它改變的是「腳本怎么進來的」這個判據(jù)不是「哪個域被允許」具體行為與組合效果需要單獨一篇。本章可以帶走的一句CSP 的四條誤讀共用一個形狀——把沒被問到的部分當成了在管的部分規(guī)則本身會隨草案版本變只有「先確認版本、再確認階段、再確認請求類型」這個讀法不會變。完整版對照資料這份資料把本文七章用到的那幾條判定規(guī)則做成了單頁檢查表從「數(shù)清幾條策略」到「報告里的 effective-directive 對應(yīng)哪條改法」和第七章的七步順序一一對應(yīng)。放在資料包里掃碼即可獲取附表 A本文引用事實與官方出處對照表序號事實出處核驗日期本文位置1CSP3 文檔身份W3C Working Draft2026-09-16是工作草案不是 RecommendationW3C CSP3CSP-012026-10-25一 1.1、七 7.32default-src self的等價形式共 12 項腳本與樣式拆為-elem與-attr四條無單獨的script-srcstyle-srcW3C CSP3CSP-022026-10-25二 2.23「There is no inheritance…the value of default-src has no influence on script requests.」W3C CSP3CSP-02b2026-10-25二 2.1、三 3.14default-src只是 fetch 指令的兜底不是全局開關(guān)W3C CSP3CSP-032026-10-25一 1.2、二 2.35prefetchpreconnect 由所有指令源列表的并集管轄未寫default-src時「will always be allowed」W3C CSP3CSP-03b2026-10-25二 2.36多條策略取交集「pass through both unscathed」增加策略「can only further restrict」W3C CSP3CSP-042026-10-25三 3.17「Script will only load if it meets both policy’s criteria」W3C CSP3CSP-052026-10-25三 3.28disposition為 report 的策略在判定中被跳過「then skip to the next policy」W3C CSP3CSP-062026-10-25四 4.19none與其他源并列時無效果? none, https://example.com ?會匹配該域W3C CSP3CSP-072026-10-25五 5.110空源列表等價于none不匹配任何 URLW3C CSP3CSP-082026-10-25五 5.211加載結(jié)果是重定向時匹配算法忽略源表達式里的路徑部分W3C CSP3CSP-092026-10-25五 5.312指令名大小寫不敏感同一策略內(nèi)重復(fù)指令只取第一個W3C CSP3CSP-102026-10-25六 6.2、七 7.113frame-ancestors覆蓋X-Frame-Optionsnone約等于DENYself約等于SAMEORIGINW3C CSP3CSP-112026-10-25六 6.314meta不支持 Report-Only也不支持report-uri、frame-ancestors、sandboxW3C CSP3CSP-122026-10-25六 6.1、四 4.315meta解析后再改content不生效規(guī)范建議meta盡量靠前W3C CSP3CSP-132026-10-25六 6.216report-uri已被report-to取代W3C CSP3CSP-142026-10-25四 4.3、六 6.317開發(fā)者 SHOULD NOT 把unsafe-inline或data:作為有效源W3C CSP3CSP-152026-10-25七 7.318同一資源的不同表示可以帶不同的策略頭值W3C CSP3CSP-162026-10-25三 3.319待驗證禁止unsafe-inline與 nonce 的交互結(jié)論本批未在規(guī)范中檢到可引用原句全文不寫本批紀律CSP-172026-10-25七 7.320禁止本文不寫任何繞過類做法與具體白名單技巧strict-dynamic僅作概念說明本批紀律CSP-182026-10-25七 7.321default-src none不覆蓋frame-ancestors、base-uri、form-action、sandbox、上報指令W3C CSP3CSP-032026-10-25二 2.32212 項等價清單中每一項各自管轄的請求類型W3C CSP3CSP-022026-10-25二 2.2附表 B術(shù)語速查表術(shù)語一句話解釋fetch 指令管某類請求能不能發(fā)出去的指令只有這一類有default-src兜底文檔指令管文檔自身行為的指令如base-uri、sandbox無兜底導(dǎo)航指令管「誰能嵌我、我能往哪提交」的指令如frame-ancestors、form-action無兜底上報指令管違規(guī)信息往哪送的指令如report-uri、report-to無兜底無繼承寫了具體指令default-src對那一類請求零影響不是優(yōu)先級低是不參與源列表一條指令后面的那些值內(nèi)部是「或」的關(guān)系任一項匹配即放行none表示「列表為空」的關(guān)鍵字任何 URL 都不匹配與其他源并列時被吸收空源列表只寫指令名、不寫值語義等價于none即全禁enforcedisposition為 enforce 的策略參與攔截判定與其他 enforce 策略取交集Report-Only只上報不阻斷的策略判定時被跳過不參與交集也不能寫進metascript-src-elemscript-src-attr腳本元素與內(nèi)聯(lián)腳本屬性兩條分開的判據(jù)覆蓋frame-ancestors存在時X-Frame-Options被忽略不是疊加是后者不作數(shù)寫在最后這篇用到的資料寫這篇文章時我把 CSP3 工作草案里跟default-src、none、Report-Only 有關(guān)的段落來回讀了幾遍最費勁的是「多條策略取交集」和「Report-Only 不參與交集」要同時成立順手也整理了幾份配套的東西靶場環(huán)境對照表DVWA、upload-labs 在 Windows / macOS / Linux 三平臺的可行性與推薦路徑Web 安全學習路線圖從基礎(chǔ)打牢到安全管理四個階段各學什么常用靶場清單每個靶場練什么、適合哪個階段資料是我自己整理的放在下面這個碼上掃碼即可獲取添加時備注「靶場」優(yōu)先通過。拿到之后建議先看環(huán)境對照表那一份再回到自己站點的那幾個響應(yīng)頭上按第七章的七步順序數(shù)一遍究竟有幾條策略在同時生效。