[精讚] [會員登入]
422

【Wicket】[CSP] Content-Security-Policy & Content-Security-Policy-Report-Only

Wicket 預設開啟的,所以如果要加載外部資源甚至是同源資源都會被擋下。

分享此文連結 //n.sfs.tw/15702

分享連結 【Wicket】[CSP] Content-Security-Policy & Content-Security-Policy-Report-Only@小編過路君子
(文章歡迎轉載,務必尊重版權註明連結來源)
2022-05-20 16:41:58 最後編修
2022-03-24 14:33:41 By 過路君子
 

哈囉大家好,這裡是又踩進Wildfly大坑裡面的小編過路君子

Wicket 9.x API真的很過分,就放兩個函式在那裡,然後底下全白,誰知道在做什麼的。

 

 

那因為本篇文章高度相關 CSP,還不太了解的人可以參考由其他筆者所撰寫的這篇:Content Security Policy (CSP) — 幫你網站列白名單吧@Hannah Lin

或是直接生咬 W3C 所提供的完整原文文檔:Content Security Policy Level 3@W3C,這兩篇也是小編所參考的文獻資料。

小編這邊要特別提醒:不是使用了 CSP 就可以高枕無憂,CSP 只是我們眾多安全防線中的第一道而已,就算開啟,我們伺服器後端也要做校驗檔案之類的動作,相關的資訊可以參考這篇:前端防禦從入門到棄坑——CSP變遷@程序猿哪些事

 

那至於 Wicket 的 API 也有小小的提及,但是前提是建立在他們認為我們已經具有 CSP 的基本知識了,所以如果完全沒有 CSP 知識點進去會完全看不懂。

關於如何設定 CSP 和 Content-Security-Policy-Report-Only 可以參考這篇:org.apache.wicket.csp.ContentSecurityPolicySettings

關於 Wicket 有什麼 CSP 可以設定,可以參考這篇:org.apache.wicket.csp.CSPDirective

 

小編就是靠上面三篇文檔和硬咬 Wicket 9.x API 才終於搞懂的,不得不說,Wicket 這方面的資料網路上超級缺乏,沒什麼有用的資料可以參考。

其實小編有看到更為簡單粗暴的解法,這個小編下面會提到,簡單來說就是直接關閉 CSP,那樣是可以跑啦,但是一點都不優雅,小編不喜歡,就是喜歡搞自己。

所以才跑去讀了好幾遍 CSP 後好不容易搞懂,然後又要了解 Wicket 如何魔改 CSP,又要如何更訂 Wicket 原始預設值,最後才誕生出這篇筆記的。

 

這篇文章的主要目的是要記錄 Wicket CSP 該如何設定,那事實上 Wicket 有提供我們在這高強度的 CSP 下依舊可以使用外部 css 和 javascript 的(運用隨機 nonce)。

有興趣知道如何新增 css 或是 javascript 到我們當前頁面(直接使用 HTML 標籤,這兩者都會被 Wicket 預設的 CSP 擋下),可以參考這篇:【Wicket】[nonce]如何導入css以及javascript@小編過路君子

那在開始之前照慣例附上目錄結構:

(所有圖片點擊都可以放大、變高清)

 

 

當我們今天部屬好 Wicket 時,很高興地開始撰寫我們的網頁,那既然是網頁,想必 CSS 和 JavaScript 是不可少的吧!

所以我們就很高興的像平常一樣使用了 <link href="..." /> 或 <script scr="...">,結果竟然被 CSP 擋下來了......

然後仔細看了一下檔頭:

好傢伙,竟然 Wicket 預設連同源的 CSS 檔案也會拒絕掉。

不僅如此連 inline 和 <style type="text/css"></style> 也擋掉了,總之只要是 css 一律無效。

那各位可能會看到網路上其他人的解法是使用 <wicket:head></wicket:head> 來解決行內 css 或是 js,但對於外部檔案一樣無解。

 

那接下來我們就要開始對 CSP 動刀了,接下來的所有程式都是寫在 webRoute.java 內,index.html 以及 index.java 等等檔案都不需要做修正。

第一步當然就是要來取得我們整個網站的 CSP 設定了,Wicket 的 CSP 是以一個網站作為單位的,全站統一用一個 CSP。

那為了達成這個任務,我們首先要到我們的 WebApplication 下,以小編的例子來說是 webRoute.java 這個檔案,使用以下函式:

public class webRoute extends WebApplication
{
    @Override
    public void init()
    {
        getCspSettings();
    }
}

 

就這樣,但如果各位有偷偷看過 Wicket 9.x API 的話,應該不難發現我們後面還要接一個函式,根據 API 的解釋:

沒了。

真的是有夠搞笑,至少這樣寫一下吧!

blocking() reporting()
設定 Content-Security-Policy 設定 Content-Security-Policy-Report-Only

那 Wicket 預設不啟用 Content-Security-Policy-Report-Only,如果各位之後有自行啟用的話......記得要設定 report-to,要不然網頁會一直送出警告,就算沒有錯誤也一樣,很討厭。

 

其中 Wicket 對於這兩項的預設值如下,其中 nonce 後面接的數值每次頁面載入都會重新產生,所以這邊僅寫 nonce:

  Content-Security-Policy(CSP) Content-Security-Policy-Report-Only
default-src none -
script-src nonce
strict-dynamic
-
style-src nonce -
img-src self -
connect-src self -
font-src self -
anifest-src self -
child-src self -
frame-src self -
base-uri self -
report-to - -

表註:可能會有人發現,若真的有設定 report-to,實際去抓取檔頭的話會看到 Wicket 用的是 report-uri,那因為 report-uri 即將被淘汰,所以小編評估之後還是決定寫 report-to。

 

所以如果我們今天要設定 Content-Security-Policy 要這樣寫:

public class webRoute extends WebApplication
{
    @Override
    public void init()
    {
        getCspSettings().blocking();
    }
}

反之,如果只是要設定 Content-Security-Policy-Report-Only 要這樣寫:

public class webRoute extends WebApplication
{
    @Override
    public void init()
    {
        getCspSettings().reporting();
    }
}

那如果兩個都要設定就都寫,簡單吧!

 

接下來就是重頭戲了,我們要開始添加、移除或是關閉 CSP 規則了。

那 Wicket 官方也很好心的提供了四個快速建構式給我們,分別是:

  strict() disabled() clear() unsafeInline()
default-src none - - none
script-src nonce
strict-dynamic
- - self
unsafe-eval
unsafe-inline
style-src nonce - - self
unsafe-inline
img-src self - - self
connect-src self - - self
font-src self - - self
anifest-src self - - self
child-src self - - self
frame-src self - - self
base-uri self - - self
report-to - - - -

其中的 strict() 設定有沒有眼熟呢?對,我們的 Wicket 預設值就是 strict()。

 

這也是為什麼現在看到網路上的解法有些人就叫你直接下:

public class webRoute extends WebApplication 
{
    @Override
    public void init()
    {
        getCspSettings().blocking().disabled();
    }
}

然後我們照著下,唉!可以跑了,我的資源正常載入了!

看了上表之後我們就可以理解了,因為我們直接把 CSP 關掉了嘛!俗話說的好,解決不了問題就解決提出問題的人。

所以其實下 getCspSettings().blocking().clear(); 也有同樣的效果。

 

那關於設定 SCP 的方式有以下四種:

add() remove() reportBackAt() setAddLegacyHeaders()
添加 SCP 指定項狀態 完全移除 SCP 指定項設定 設定 report-to 的網址路徑 是否啟用 Legacy 來相容其他瀏覽器,像是 IE

 

那可以設定的 SCP 總共有以下 16 種。

這邊要注意的是:要先 import org.apache.wicket.csp.CSPDirective; 才能使用喔。

Wicket CSP 屬性 對應的 CSP 值
BASE_URI base-uri
CHILD_SRC child-src
CONNECT_SRC connect-src
DEFAULT_SRC default-src
FONT_SRC font-src
FRAME_ANCESTORS frame-ancestors
FRAME_SRC frame-src
IMG_SRC img-src
MANIFEST_SRC manifest-src
MEDIA_SRC media-src
OBJECT_SRC object-src
REPORT_URI report-uri
SANDBOX sandbox
SCRIPT_SRC script-src
STYLE_SRC style-src
WORKER_SRC worker-src

 

那對每個設定可以添加的值有以下七種。

這邊也要注意的是:要先 import org.apache.wicket.csp.CSPDirectiveSrcValue; 才能使用喔。

Wicket CSP 值 對應的 CSP 值
NONCE nonce-xxx
NONE none
SELF self
STRICT_DYNAMIC strict-dynamic
UNSAFE_EVAL unsafe-eval
UNSAFE_INLINE unsafe-inline
WILDCARD *

表註:nonce後面所接的值 Wicket 會自動幫我們產生,我要只要填入 NONCE 即可。

 

那我們一個一個來看,先從最簡單的 setAddLegacyHeaders() 來看好了,我們先看看關於此函式的介紹:

由上圖我們可以知道,此函數接受一個 boolean 值,而且預設為關閉。

所以如果我們今天要打開此項設定,應該要這樣下:

@Override
public void init()
{
    getCspSettings().blocking()
        .setAddLegacyHeaders(true);
}

當我們重新載入頁面之後就可以看到我們的檔頭裡多了 X-Content-Security-Policy 的屬性。

而且相關的設定跟我們目前的 Content-Security-Policy 一模一樣喔。

 

第二個小編緊接著要來介紹的是 reportBackAt(),一樣先來看看有關此函式的說明:

由上圖的函式說明我們可以得知,此函數接受一個字串,而這個字串就是要瀏覽器將使用者違反相關的 CSP 資訊傳送到我們所指定的地方。

所以如果小編想要瀏覽器將相關資訊傳送到 http://192.168.88.128:8080/CSPwarning,那我們應該要這樣下指令:

public class webRoute extends WebApplication
{
    @Override
    public void init()
    {
        getCspSettings().blocking()
            .reportBackAt("http://192.168.88.128:8080/CSPwarning");
    }
}

然後我們再次重新載入網頁。

瞧~現在我們的檔頭的 Content-Security-Policy 這欄是不是出現了剛剛一直都沒有看到的 report-uri 呢?

那各位啟用前要對於處理這些訊息做一些規範,包括短時間內大量的 CSP 警告接收,如果對方真的有心,那這也是一種 DDoS 攻擊。

 

那接下來要來介紹的就是 remove() 囉,照慣例我們先來一起看 API 對於此函式給出的說明吧~

根據上圖我們可以得知,只要將我們想要移除項目填入,就可以成功將其移除掉囉。

import org.apache.wicket.csp.CSPDirective;

public class webRoute extends WebApplication
{
    @Override
    public void init()
    {
        getCspSettings().blocking()
            .remove(CSPDirective.STYLE_SRC)      //移除 style-src
            .remove(CSPDirective.SCRIPT_SRC);    //移除 script-src
    }
}

這邊小編示範移除原預設 CSP 裡的 style-src 和 script-src 屬性,若要移除其他屬性可以參照上表,換成要移除的屬性即可。

那根據 Wicket 9.x API 上所寫的,小編沒有找到只移除某一屬性某個值的函式,所以目前要刪除屬性的某一值的話......只能全部移除再添加回來其他不須刪除的。

 

最後一個函數!沒錯,終於來到了最後一個函式 add() 了。

就像剛剛一樣,來吧。

那不同於 remove() 是移除整個屬性,每次 add() 都只會增加某一屬性的指定值。

import org.apache.wicket.csp.CSPDirective;
import org.apache.wicket.csp.CSPDirectiveSrcValue;

public class webRoute extends WebApplication
{
    @Override
    public void init()
    {
        getCspSettings().blocking()
                /* 在 font-src 裡添加 nonce-xxx */
            .add(CSPDirective.FONT_SRC, CSPDirectiveSrcValue.NONCE)

                /* 在 style-uri 裡添加 self */
            .add(CSPDirective.REPORT_URI, CSPDirectiveSrcValue.SELF);
    }
}

所以我們在使用的時候就要告訴 Wicket 我們要設定什麼屬性的什麼值對不對~

 

 

那這就是 Wicket 的 CSP 全操作了,其中小編有省略掉解釋 CSP 屬性所代表的意義,像是 STYLE_SRC 是用來限定可執行 Css 來源或是 SCRIPT_SRC 是用來限定可執行 JavaScript 來源等等。

那其實 Wicket 已經有內建導入外部 Script 或是 Css 的方法了,各位想到了嗎?那小編這邊也不賣關子了,簡單來說就是使用 nonce 啦!

相關的資訊可以參考小編的這篇文章:【Wicket】[nonce]如何導入css以及javascript@小編過路君子

 

 

 

後記

其實當下小編一得知是因為 CSP 才會造成資源無法加載,就跑去找其他人是怎麼解決這個問題,發現絕大部份就是教你直接關閉 CSP,然後原發問者就很高興的在下面回覆:「它有用,開始運作了!」小編看到真的是額頭三條線冒出來......相當的不以為意,小編就不信邪小編不能在不更動 Wicket 預設 CSP 的狀況下使用小編想要的資源。

然後花了兩天去研讀 CSP,然後又花了一天去了解要怎麼使用 Wicket 來全面控制 CSP,最後又花了一天來寫這篇文;那你問小編最後有沒有解決問題,當然有!就是使用 nonce,而且除了同源之外還可以加載外部的資源檔案喔!

下圖的 nonce 是 Wicket 自己產生的,所以每次載入頁面所顯示的值都不一樣,詳細的步驟小編寫在了此文章末的那篇文章了。

END

你可能感興趣的文章

【Maven】如何創建一個簡單可執行的JAR檔 滿重要的一個小功能,畢竟有時候是要傳遞的是JAR檔,而不是直接透過Maven直接部屬之類的

【Arduino/LinkIt 7697】實作小小的 MQTT Publish & Subscribe 若是要多點對多點傳輸資料,那使用 MQTT 即可快速的達成我們所需的目的

【Stable Diffusion web UI】[AI 作畫](Linux)無 NVIDIA 顯卡之伺服器運行測試 凡事就是要試試看,才知道最後的結果

【C++】一些好用的C++小功能 —— 貳 承襲上一篇的C++小功能,筆記下來以免自己以後忘記了。

【無料版模】﹝CSS&HTML﹞製作epub電子書版模免費下載&附使用教學 一個專門用來製作epub的簡單CSS檔案,基本上已經可以做出一本還不錯的電子書,讓妳的電子書不在只有預設的字體、樣式

【C++】SFML安裝於Microsoft Visual Studio 2019 此方法僅適用單個C++專案,因為一次就適用整台電腦的方式有人寫了,而且寫得非常不錯。

我有話要說

>>

限制:留言最高字數1000字。 限制:未登入訪客,每則留言間隔需超過10分鐘,每日最多5則留言。

訪客留言

[無留言]

隨機好文

高捷少女:小穹與果仁巧克力㊥ 艾咪臉上泛起笑容說:「妳知道嗎?就跟花語一樣,每一種巧克力也都有各自的涵義:薄荷巧克力代表初戀;卡通巧克力代表天真爛漫;而果仁巧克力代表的是窩心,還有想陪伴對方的心情,這在德國是女生之間在慶生時會彼此

高捷少女:小穹與果仁巧克力㊦ 「如果妳跟一個女生同班三年,看過她午休流口水跟狼吞虎嚥地吃午餐,就算變成高捷代言人,也很難把她當女神的啦!」她說,小穹氣得搶走她義大利麵裡的蝦子,其他人笑得花枝招展。

高捷少女:地下城的探險少女② 「等我一下喔,我好像有帶去漬的清潔噴霧。」婕兒翻翻飛揚,拿出噴霧劑給小穹,小穹趕緊對著汙漬噴了噴,紅茶漬果然乾淨了許多。「婕兒,謝謝妳。來,還妳。」小穹感謝地把噴霧還給她,卻發現婕兒盯著打開的飛揚,一

高捷少女:地下城的探險少女④ 耐耐突然抖了一下。「妳們聽到了嗎?」她說。「聽到什麼?」婕兒問。「那個腳步聲啊!」耐耐嚥了一下喉嚨,覺得有些害怕。「有一陣腳步聲經過,很小聲,但我還是聽到了。』「妳聽錯了吧……等等!」婕兒使終維持著將

【專輯介紹】蓮台野夜行 ~ Ghostly Field Club,れんだいのやこう 就讓我們隨著音樂跟著秘封俱樂部一起探詢那不可思議的未知和神秘,若處理不好,說不定會招來奇怪的靈呦(・ω<)☆