Web安全快速入門
──幾個Web開發人員必知的安全縮略語
原文:A quick introduction to web security
作者:Austin Tackaberry 發表時間:2018/8/15
譯者:陳 昌茂 發表時間:2018/8/25
(轉載請註明出處)
你有很多理由需要了解Web安全,比如:
- 你是一位關心個人隱私資料正被洩露的使用者
- 你是一名Web開發人員,想要編寫更加安全的Web應用
- 你是一位正在應聘Web開發崗位,準備面試有關Web安全問題。
- 諸如此類~
本文將通俗易懂的準確地解釋一些常用的Web安全縮略語。
在此之前,我們要了解兩種模式,分別代表著兩個極端,但又同屬一個觀念層次。
安全的兩個模式
一種模式是追求絕對安全,結果無論如何努力也達不到絕對安全,而弄得自己痛苦不堪。
另一種是在採取了一定的防護措施後,便滿足地認為已達到絕對安全,於是放鬆警惕,最後遭受安全威脅的攻擊,損失慘重。
你不能就說:
喔,因為實現了CSP,所以我是安全的。我可以在漏洞清單中劃掉跨站指令碼,因為它不會發生。
你會發現自己和其他人一樣,也是按這種方式思考的。顯而易見,程式設計師們很容易按這種方式思考:非黑即白,非0即1,非對即錯。其實,安全遠沒有這麼簡單。
我們在Web開發工作中初期就遇到會這些問題,並嘗試從StackOverflow社群中能找到解決方案。
跨源資源共享(CORS)
你是否見到類似下面的錯誤資訊?
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
複製程式碼
你不是一個人在戰鬥,你Google查詢,有人說用這個方法,所有問題馬上解決。
太好了,不是嗎?
CORS是來保護你而不是傷害你的
為了解釋CORS是如何幫助你的,讓我們先從cookie說起,特別是認證cookie。認證cookie是用來告訴後臺程式你的登入狀態,它們自動隨任何請求傳送給後臺程式。
我們來假設:你已經登入了Facebook賬戶,且Facebook使用cookie認證。你點選連結bit.ly/r43nugi
,它重定向到惡意網站 superevilwebsite.rocks
。惡意網站 superevilwebsite.rocks
中的一段指令碼程式碼向facebook.com
後臺程式發起請求,你的認證cookie自動隨請求傳送給facebook.com
後臺程式。
在非CORS的世界,黑客可以在你毫不知情的情況下變更你的賬戶。只需要簡單幾步:1、黑客在你的時間線上發帖,帖子中包含bit.ly/r43nugi
惡意連結;2、你的朋友們點選了該惡意連結,惡意指令碼程式又在他們的時間線上發帖,這個過程不斷被重複,在廣度優先模式下,直到黑客佔領了全部的Facebook使用者的時間線,世界充斥著惡意網站 superevilwebsite.rocks
。 ?
然而在CORS的世界,Facebook將只允許來源自facebook.com
的請求方可在後臺程式中修改資料。換句話說,他們會限制跨源資源共享。你可能會問:
我們可以修改請求檔案頭,這樣請求不就看起來是來自facebook.com嗎?
你可以試試,但不會成功的,因為瀏覽器會忽略你的修改,它會使用真正的來源資訊。
好了,那如果惡意網站修改後臺程式的請求呢?
在這種情況下,你想繞過CORS,但你還是不會得逞,原因後臺程式不能同時傳送你的認證cookie。指令碼必須在瀏覽器上執行才能獲取到你存在瀏覽器上的cookie。
內容安全策略(CSP)
為了便於理解CSP,我們先談一下最常見的Web漏洞:跨站指令碼攻擊(簡稱:XSS)
XSS即黑客在你的瀏覽器中注入JavaScript程式碼。你可能會想:
黑客會做什麼,紅變綠嗎?
我們假如黑客在你的瀏覽器成功中注入JavaScript程式碼到你正在訪問的網站程式碼中。
他們可能會做哪些邪惡的事情?
- 他們能冒充你向其他網站傳送HTTP請求。
- (這句不會翻,囧)
- 他們能加script標籤,內嵌的一段JavaScript程式碼。
- 他們能加script標籤,引用遠端的JavaScript程式碼。
- 他們能內嵌一個網頁覆蓋正常網頁之上,提示你輸入密碼。
- 罄竹難書,發揮你的想象力吧。
CSP通過限制功能提供保護:
- 什麼能在框架內開啟。
- 什麼樣式表可以被載入。
- 哪些請求可以傳送,等等。
那它時怎麼工作的呢?
等你點選連結或在瀏覽器位址列輸入網址的時候,瀏覽器傳送GET請求。伺服器返回HTTP頭資訊以及HTML內容。如果你對返回頭資訊是什麼很好奇,(以谷歌Chrome瀏覽器為例,開啟瀏覽器開發者模式。括弧內為譯者補充,下同)切換到“網路”標籤,訪問網站facebook.com
。
你可能會看到如下返回頭資訊:
content-security-policy: default-src * data: blob:;script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self';style-src data: blob: 'unsafe-inline' *;connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;
複製程式碼
這些是facebook.com
的安全內容策略。讓我們調整成可讀性強的格式。
content-security-policy:
default-src * data: blob:;
script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self';
style-src data: blob: 'unsafe-inline' *;
connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;
複製程式碼
現在,我們逐條分解這些指令。
**default-src**
限制所有其他沒有顯示列出的CSP指令。**script-src**
限制指令碼載入。**style-src**
限制樣式表載入。**connect-src**
限制可以使用指令碼介面(如獲取、XHR、ajax等)的URL連結。
注意遠不止這3條指令,還有更多的CSP指令。瀏覽器將讀取CSP頭資訊並載入、渲染HTML檔案時執行這些指令。如果恰當地設定指令,瀏覽器將僅允許必要的操作。
如果沒有CSP頭資訊,那麼所有的操作都不會被限制。你可以想象這些指令全部替換成萬用字元*
,任何操作都將被允許。
HTTPS 或 HTTP安全
你肯定聽說過HTTPS。人們可能會這麼說:
為何我要關心一個我玩遊戲的網站是否啟用了HTTPS呢?
或者是這樣滴。。。
太瘋狂了,你的網站居然沒有啟用HTTPS。都2018年了,別信其他人(潛臺詞:必須啟用HTTPS)。
或許你聽說谷歌Chrome瀏覽器(自7月24日釋出的Chrome 68起)將把所有HTTP網站標記“不安全“。
重點是,HTTPS是加密的而HTTP不是。
如果你不傳送敏感資訊,(是否加密)有那麼重要嗎?
準備下一個縮寫MITM,它代表中間人攻擊。
如果你在咖啡館使用無密碼的公共Wi-Fi,任何人都很容易地冒充成路由器,使全部的請求和返回都通過該路由器。如果你的資料沒有加密,那麼他們可以做任何事。比如在HTML, CSS, 或 JavaScript到達你的瀏覽器之前修改。假如你已經知道XSS,那麼可以做什麼樣的壞事。
那麼怎樣才可以實現我的電腦和伺服器之間通訊加密而不被中間人攻擊呢?
最初SSL協議就是為了解決這個問題而設計的,1999年,TLS協議取代SSL協議用在HTTPS上。至於TLS如何工作已經超出本文範圍。
HSTS協議
讓我們還用Facebook的頭資訊為例,以下是一條很簡潔的指令。
strict-transport-security: max-age=15552000; preload
複製程式碼
max-age
標明HSTS在瀏覽器的生效時間。preload
對本文不重要。
這個頭資訊僅在用HTTPS訪問時生效,在用HTTP訪問時會被忽略。原因很簡單,HTTPS時如此不安全,很難被信任。
讓我們用Facebook的例子來描述下。你首次訪問facebook.com
,而且知道HTTPS比HTTP安全,所以你使用https://facebook.com
。當瀏覽器接收到HTML,收到頭資訊,告知瀏覽器在後續訪問中強制重定向到HTTPS網站。一個月後,有人通過HTTP給你傳送一個Facebook的連結,比如http://facebook.com
,在max-age
時間範圍內,瀏覽器會強制使用HTTPS,防止潛在的中間人攻擊。
結論
無論你在Web開發旅程中的何時何地Web安全都很重要。你越重視它,安全威脅離你越遠。安全時對每個人都很重要的事情,而不僅是對於工作中。?