2016年4月7日 星期四

《打造安全無虞的Web Applications:從策略制定、程式開發,到防止惡意攻擊之必備對策白皮書》筆記

一、Web安全的基礎知識 - HTTP、Session管理、相同來源政策

1.HTTP Response 狀態列:

1XX:持續處理中
2XX:正常結束
3XX:重新導向
4XX:用戶端錯誤
5XX:伺服器錯誤


2.以POST傳送機密資訊的原因,是因為GET可能會出現如下狀況:

(1)在URL上指定的參數會透過Referer洩漏出去

(2)在URL上指定的參數會留下存取紀錄


3.即使被使用者本身改寫也無所謂的認證或授權之相關資訊應該儲存在session變數中,但其他資訊則應該優先考慮存放在hidden參數中,原因在於:

(1)hidden參數的優點,在於雖然可以被使用者自己改寫,但卻不容易洩露資訊或被第三者改寫

(2)cookie和session變數的缺點,在於缺少對session ID固定化攻擊的防禦能力


4.HTTP 的Basic認證:

(1)無狀態:在登入時,伺服器的Response中會帶「Authorization: Basic xxxxx」,且xxxxx可透過Base64 Decode取得明文帳號密碼。

(2)Digest:在登入時,伺服器的Response中會帶「Authorization: Digest nonce=xxxxx」,以及其他包含使用者帳號、密碼及其他資訊的hash值。


5.使用HTTP認證,瀏覽器會記住使用者的帳號密碼;若不使用HTTP認證,就必須透過session管理讓伺服器端記住登入的認證狀態。

而為了在HTTP實現session管理,則需透過cookie機制,cookie會從伺服器指示瀏覽器記住「名稱=變數」的組合。


6.常見session ID安全問題:

(1)登入認證後,session ID未變更

(2)URL中包含session ID時,由Referer 標頭洩漏

(3)session ID可遭猜測


7.cookie屬性:
  • Domain:cookie傳送到的伺服器位址(不指定時,則傳送給產生該cookie的伺服器)
  • Path:cookie傳送到的URL目錄
  • Expires:cookie的有效期限(不指定時,則到瀏覽器關閉為止)
  • Secure:只在SSL時傳送cookie
  • HttpOnly:設定不讓JavaScript存取

8.相同來源政策(same origin policy):禁止以JavaScript進行跨網站存取的限制。視為相同來源的條件:

(1)URL的主機一致(可透過JavaScript變更document.domain讓同網域上的不同主機存取)

(2)通訊協定一致

(3)埠號一致




二、Web應用程式的各種功能之安全性臭蟲

1.PHP正規表示式驗證輸入值相關函數:

(1)preg_match:須以「/」框住正規表示式、中文環境下需指定u修飾子。

(2)mb_ereg:回傳值為整數型態或邏輯型態,故須使用區別型態的比較運算子===進行比較。


2.XSS類型:

(1)反射型(reflected):攻擊用的JavaScript位於目標網站之外的其他網站。

(2)持續型(stored):攻擊用的JavaScript會儲存在目標的資料庫中。

(3)DOM based:伺服器產生的HTML上不會出現攻擊者注入的JavaScript。


3.CSRF的攻擊,僅限於伺服器原本就準備好的處理;XSS則是可在瀏覽器上進行任何攻擊。


4.PHP的跳脫處理:

htmlspecialchars(string $string, int $quote_style, string $charset)
  • 屬性值應以雙引號框住
  • $quote_style指定ENT_QUOTES
  • 第三引數需指定內部字元編碼

5.在href屬性、src屬性等指定URL的地方,若此URL可以從外部變更時,即可透過「javascript:JavaScript運算子」的形式啟動JavaScript。

ex:javascript:alert(document.cookie)


6.動態產生JavaScript字串常數的保護方式:

(1)從JavaScript的語法跳脫引號(「”"」或「’」)、「\」與換行
ex:” -> \”、’ -> \’、換行 -> \n、\ -> \\

(2-1)在事件處理器中要以字元參照對(1)的結果進行HTML跳脫,然後以雙引號框住

(2-2)在script元素內要讓(1)的結果不會出現「</」這樣的字串


7.XSS的防範對策:

(1)針對元素內容使用htmlspecialchars進行HTML跳脫

(2)針對屬性值使用htmlspecialchars進行HTML跳脫,並以雙引號框住

(3)使用HttpOnly禁止讓JavaScript讀取cookie

(4)在HTTP回應中明確指定字元編碼

(5)驗證輸入值(控制字元、字元數)

(6)關閉TRACE傳輸方式

(7)以程式產生URL時,檢查是否只允許http、https為開頭的絕對URL,或以「/」開始的相對URL

(8)通過(7)檢查的URL,必須作為屬性值進行HTML跳脫

(9)驗證連結目標的URL,當URL為外部網域時就出錯

(10)當伺服器方會自動產生JavaScript常數時,可透過Unicode跳脫,或在script元素外定義參數,再以JavaScript進行參照(如hidden參數)

(11)在開發允許輸入HTML標籤和CSS的網站時,最好是使用可以對HTML進行語法解析並抽出必要元素的函式庫(如PHP中的HTML Purifier)

(12)關閉應用程式發生錯誤時顯示的錯誤訊息


8.CSRF的防範對策:

(1)區別需要CSRF對策的頁面

(2)將應用程式實作成能夠區別請求是否合乎使用者意圖:
<1>嵌入機密資訊(token),如利用session ID
<2>重新輸入密碼
<3>檢查Referer

(3)在執行重要處理後,發一封信件通知使用者

補充資料:Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet


9.SQL注入攻擊的防範對策:

(1)以靜態PlaceHolder建立SQL敘述句

(2)在應用程式方建立SQL敘述句時,讓SQL敘述句無法被變更

(3)當應用程式會隨著使用者的輸入改變SQL敘述句時,就要寫成透過會字串連結動態嵌入包含PlaceHolder符號「?」的SQL敘述句,並在SQL呼叫時綁定實際參數的指令碼

(4)當無法使用PlaceHolder時,要在字串常數內跳脫具有特殊意義的符號字元,並且不要讓數值以外的字元混入數值常數中

(5)抑止詳細的錯誤訊息

(6)輸入值的妥當性驗證

(7)資料庫的權限設定

8.避免將session ID嵌入URL,應將session ID除存在cookie中:

PHP:
[Session]
session.use_cookies = 1
session.use_only_cookies =1

ASP.NET:
<sessionState cookieless=“false” />


9.Session固定攻擊的防範對策:

(1)在認證後變更session ID

(2)當無法變更session ID時,則產生token,並同時存放在cookie和session變數中

(3)不在登錄前的session變數中存放機敏資訊

(4)不使用嵌入URL的session ID

(5)不使用地域型網域

10.重新導向攻擊的防範對策:

(1)不直接指定重新導向標的之URL,而是指定頁面編號

(2)檢查重新導向標的之URL

11.HTTP標頭注入的防範對策:

(1)不要將來自外部的參數輸出為HTTP標頭:
<1>不直接將重新導向標的指定為URL,而是指定為編號或將它固定
<2>使用應用程式開發工具所提供的session變數傳遞URL

(2)以專用API進行重新導向和產生cookie

(3)檢查產生標頭的參數之換行字元:
<1>讓URL中的換行出錯
<2>對cookie值的換行進行百分比編碼


12.cookie的不當屬性防範對策:

(1)為cookie加上secure flag:
PHP:session.cookie_secure = On
ASP.NET:<httpcookies requireSSL=“true” />

(2)為token中的cookie加上secure flag


13.郵件標頭注入的防範對策:

(1)使用專用函式庫傳送郵件

(2)不讓郵件標頭含有來自外部的參數

(3)檢查來自外部的參數是否包含換行

(4)檢查郵件信箱

(5)檢查主旨


14.目錄走訪攻擊的防範對策:

(1)固定檔案名稱

(2)將檔案名稱儲存在session變數中

(3)不直接指定檔案名稱,而是以編號間接指定

(4)不讓檔案中包含目錄名稱

(5)將檔案名稱限定為英數字元


15.檔案意外公開的防範對策:

(1)在設計應用程式時決定好檔案的安全存放位置

(2)在租借伺服器時確認是否使用非公開目錄

(3)目錄列表功能要設為無效

(4)禁止特定副檔名被瀏覽


16.OS指令注入的防範對策:

(1)選擇不呼叫OS指令的實作方式

(2)避免利用具有介殼呼叫功能的函數

(3)不將來自外部的字串交給指令列參數

(4)以安全的函數跳脫交給OS指令的參數

(5)驗證參數

(6)只賦予應用程式執行者最低限度的權限

(7)套用Web伺服器作業系統和中介軟體的更新程式


17.檔案上傳弱點的防範對策:

(1)限制副檔名

(2)不將上傳的檔案存放在公開目錄底下時,應透過指令碼才能下載該檔案

(3)上傳圖片時要確認magic-byte


18.檔案下載弱點的防範對策:

(1)檢查副檔名是否為允許的名稱

(2)正確設定Content-Type

(3)視需要設定Content-Disposition標頭

(4)下載圖片時要確認magic-byte


19.檔案引入弱點的防範對策:

(1)避免從外部指定檔案名稱的規格

(2)不讓檔案名稱中包含目錄名稱

(3)將檔案名稱限定為英數字元


20.eval注入的防範對策:

(1)不使用eval(包含同類功能),若目的為進行序列化,可使用:
<1>implode/explode
<2>serialize/unserialize

(2)不在eval的引數中指定來自外部的參數

(3)將交給eval的外部參數限制為英數字元




三、代表性的安全性功能

1.登入與登出的安全實作方式:

(1)在登入時發布token:Cookie中要設定適當的Expires,然後發布以虛擬亂數產生機制建立的token。同時加上HttpOnly;若使用HTTPS則應額外加上Secure flag。

(2)確認登入狀態:利用check_auth_token對token搜尋自動登入資訊,若有紀錄且未超過有效期限時,傳回登入中的使用者ID。

(3)自動登入:登入成功後便刪除原本的token紀錄,再以新的有效期限重新發布token。

(4)登出:以使用者ID作為主鍵,從自動登入資訊的資料表中刪除相關的列。


2.授權控制的安全實作方式:

(1)以存放於session變數中的使用者ID為基準檢查權限。

(2)不用cookie或hidden參數儲存權限資訊。


3.字元編碼的安全實作方式:

(1)統一整個應用程式的字集。

(2)讓輸入時的不當字元編碼出錯。(PHP需透過mb_check_encoding檢查字元編碼)

(3)在處理過程中正確操作字元編碼:
<1>只使用支援多位元字元的處理系統與函數
<2>以函數的引數正確指定字元編碼

(4)在輸出時指定正確的字元編碼:
<1>在HTTP回應標頭的Content-Type中正確指定字元編碼
<2>正確指定資料庫的字元編碼
<3>確保所有需要指定字元編碼的地方都沒有遺漏


4.使用SSL時的注意事項:

(1)從輸入畫面開始使用HTTPS

(2)注意cookie的secure屬性

(3)圖片、CSS和JavaScript也要以HTTPS指定

(4)不使用frame、iframe

(5)讓瀏覽器的預設設定不會顯示錯誤

沒有留言:

張貼留言