筆者初學資訊安全,在學習資訊安全的過程中,回顧自己過往的程式碼,發現自己的程式碼因為貪圖方便,而用了可能會造成資安漏洞的方式進行實作,十分地糟糕。
為了實踐所學,筆者嘗試透過改善錯誤的範例來反思有可能會造成資安漏洞的思維,並且透過常見攻擊實例,來介紹常見的攻擊手法,希望藉此可以為自己與讀者帶來一些避雷準則。
在建立一個網站應用時,我們經常會碰到各種實作情境,例如: 登入主頁、將使用者導向到其他頁面等等,然而這些在進行這些功能實作時,可能會因為沒有特別 review 到某些 "功能",而讓自己的網站暴露到風險之中。
首篇文章將著重在建立實作安全系統的概念,嘗試統整出建立安全 "元素" 可以思考的方向,以便往後能帶入有漏洞的網站實例並加以改善。
Input 可能會成為攻擊目標的原因:
"Input" 時常會被攻擊者視為一個可以攻擊的目標,試想你是一個攻擊者,進入到一個畫面,看到有一些可以"輸入值"的欄位,想必會手癢想要試試看可以撈出什麼使用者資料或是可以間接存入東西到資料庫吧?
好比你看到以下的網站 (請忽略我拙劣的畫圖技巧),有 login form,並且 input 可以讓你輸入 ID、password,有了兩個可以 "進入" 網站的通道 - input,這時候 input 的控管就變得十分關鍵:
有關如何實作安全的 Input,我列出幾點需要考量的大方向:
今天首篇的內容將會針對 "讓 Input 變乾淨"、"避免外人執行指令" 來進行說明:
讓 Input 變乾淨
實作原因:
考量元素:
過濾那些跟 script 相關的符號
在實作的時候嘗試過濾掉這些符號,因為這些符號可能會間接導致使用者執行了他想要執行的 script:
! $ ^ & * ( ) ~ [ ] \ | { } ‘ “ ; < > ? —
以 js 為例,過濾掉那些文字
const originalString = "hello test !$;";
const stringWithoutSpecialCharacters = originalString.replace(
/[@!^&\/\\#,+()$~%.'":*?<>{}]/g,
'',
);
// output stringWithoutSpecialCharacters
console.log(removeSpecialCharacters);
限制 input 的長度
嘗試針對 input 設定 input 長度,避免如果在處理該 input 時,背後若有比較複雜的處理邏輯,有可能會堵塞服務。
<input maxlength="maxLenNum">
避免在處理 input 時,使用可能會造成 正則表達式注入攻擊 (Regex Injection)
的 正規表達式
:
正則表達式注入攻擊 (Regex Injection)
是什麼 ?
如果 正則表達式
是從不受信任的 input 中生成的,或者 code 中存在的正則表達式設計不當,攻擊者可以通過 "發送惡意輸入" 來執行 正則表達式注入 (Regex Injection)
攻擊,而這種攻擊會花費系統大量的時間計算能力,可能導致 CPU 資源的耗盡,就有可能導致服務堵塞而被中斷服務 (ReDoS)。
要避免什麼樣的 正規表達式
?
舉例:
(a+)+
這樣的嵌套量詞,其中可以多次應用可能匹配多個字符的模式。(a|a)+
這樣的重疊。\d+\d+
。(其他 Regex Injection 相關的內容可以參考 OWASP - https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS )
避免外人執行指令
實作原因:
為了避免讓使用者在系統執行他想要執行的程式碼,所以我們必須避免在 Browser 上執行其他人的 javascript code 的可能。
考量元素:
設定 CSP (Content Security Policy)
CSP (Content Security Policy) 有什麼作用 ?
CSP 允許開發者控制從何處加載和執行 JavaScript(和其他資源),透過設定 CSP,我們可以告訴瀏覽器永遠不要執行 inline JavaScript,並鎖定哪些域可以為頁面託管 JavaScript。
如何設定?
若我們要只允許同源載入 & 禁止 inline script 的執行,在 http header 內,我們可以設定 CSP 如下:
Content-Security-Policy: default-src 'self'; script-src 'self'
[!] 說明:
default-src:
此處的 default-src 'self' 意味者會被導入 CSP 的預設設定,若只寫 default-src 'self',任何來自其他網站的 js、css、font 等等,如果其網站內容有源自於其他來源(非自身來源),有可能會在引入時出事情。
script-src:
此處的 script-src 'self' 設定表示只允許源自於自身來源的 js script,如果有引用第三方 js, 則可以設定成 script-src 'self' https://example.a.com https://example.b.com 來列舉允許外部 js 來源。
(其他 CSP 相關設定可以參考: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)
避免執行 inline js
舉例:
在 tag 中的 onclick:
<a href="#" onclick="alert('inline')"> Click Me </a>
script in html:
<script>
// JavaScript Code
</script>
這次大致上介紹到這邊~ 下一篇會繼續介紹 Input 的其他兩點與實作方式~
這次參賽真的滿趕的,第一次參賽感覺也沒有完全準備好就開始了,不過既然開始了就要努力做完,希望之後能夠越來越進步!