前端專案中遇到 Client Dynamic File Inclusion 的高風險回報,出問題的地方是在這樣的地方,舉例來說是一個表單詢問:
async submitForm(name){
const sendData = new FormData()
formData.append('name', name) // 出問題
const response = await axios.post(
API_CONFIG.baseURL + '<api endpoint>',
sendData,
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
)
}
其中的 append 被認為有 Client Dynamic File Inclusion 風險:
formData.append('name', name)
先來看看他的說明
可能發生什麼問題
If an attacker can select the name of the library, or the location of the code file that is loaded by the application, they would be able to cause the application to execute arbitrary code. This effectively allows the attacker to control the code run by the application. Execution of code in web application context may result with Cross-Site Scripting.
可能發生的問題是:如果攻擊者可以選擇應用程式要載入的程式庫名稱或程式碼檔案位置,他們就能讓應用程式執行任意的惡意程式碼。這等於讓攻擊者能控制應用程式執行的內容。在網頁應用程式的執行環境中,這種情況可能導致跨網站指令碼攻擊(XSS, Cross-Site Scripting)。
如何發生
The application uses untrusted data to specify the library or code file, without proper sanitization. This causes the application to load any arbitrary code, as specified. The loaded code will then be executed.
發生的情況是:應用程式在指定要載入的程式庫或程式碼檔案時,使用了未受信任的資料(例如來自使用者的輸入),而且沒有進行適當的驗證或過濾。結果導致應用程式可能載入並執行任何由攻擊者指定的惡意程式碼。
如何避免
- 不要動態載入程式庫或程式碼檔案,特別是不要根據使用者輸入動態載入。
- 如果確實有必要根據未受信任的資料來選擇要載入的程式庫,應該驗證該資料是否屬於預先定義的白名單(whitelist)中的合法項目。或者,將使用者輸入作為「識別碼(identifier)」來對應選擇白名單內的安全程式庫。
- 對所有未受信任的資料進行驗證與完整性檢查(integrity check),確保載入或處理的程式庫、檔案是可信任且未被竄改的。
然後有一些範例如下:
<script>
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const lib = urlParams.get('lib');
var script = document.createElement("script");
const safeDomain = 'https://' + TRUST_DOMAIN_NAME + '/';
script.src = safeDomain + lib;
var element = document.getElementById(DIV_ID);
element.appendChild(script);
</script>
在 Stack Overflow 中可以找到類似的討論:
How to mitigate against Client Dynamic File Inclusion vulnerability detected by Checkmarx
心得
說明滿清楚的,但是很納悶為什麼是 append 出問題,合理懷疑是因為 Checkmarx 認為這邊的 append 跟 jQuery 的 append 是一樣的,但我的理解是 formData.append() 不會直接執行內容,不會造成動態載入的狀況。
不過目前的解決方式就是不要用 append 來處理 formData,而是用一次性賦值的做法來打包 formData。