做者:肖光宇
野狗科技聯合創始人,前後在貓撲、百度、搜狗任職,愛折騰的前端工程師。
野狗官博:https://blog.wilddog.com/
野狗官網:https://www.wilddog.com/
公衆訂閱號:wilddogbaasjavascript
Web安全是一個如何強調都不爲過的事情,咱們發現國內的衆多網站都沒有實現全站https,對於其餘安全策略的實踐更是不多,本文的目的並不是討論安全和攻擊的細節,而是從策略的角度引起對安全的思考和重視。php
http協議下的網絡鏈接都是基於明文的,信息頗有可能被泄露篡改,甚至用戶都不知道通訊的對方是否就是本身但願鏈接的服務器。所以,信息通道安全有如下兩個目標:css
身份認證html
數據不被泄漏和篡改前端
幸運的是https解決了上述問題的(更多關於https的細節能夠看下上一篇乾貨扒一扒https網站的內幕)。理論上https是安全的,即便如此,https依然應該被重視,由於理論上理論和實踐是同樣的,但實踐中又是另一回事。前段時間爆發的心血漏洞就是一個例子。html5
https解決了點到點的安全問題和身份認證問題,接下來會出現問題的地方就只有2個:瀏覽器和服務器,這個層面上的安全問題並無https同樣的銀彈能夠一次性解決。java
瞭解瀏覽器安全,有一個概念特別重要,那就是源(origin) 什麼是源呢?web
相同的HOSTjson
相同的協議瀏覽器
相同的端口
舉栗子:
https//www.wilddog.com和http//www.wilddog.com非同源,由於協議不一樣。
http//wilddog.com和http//www.wilddog.com非同源,由於域名不一樣。
http//wilddog.com和http//wilddog.com:8080非同源,由於端口不一樣。
源這個概念爲甚這麼重要,這要從同源策略提及。
同源策略限制了一個源(origin)中加載文本或腳本與來自其它源(origin)中資源的交互方式。簡單的說就是一個源的頁面上的js只能訪問當前源的資源,不能訪問其餘源的資源。那麼資源是什麼呢?
DOM
經過AJAX請求的網絡資源
Cookie
WebStorage,webSql
...
很顯然,同源策略以源爲單位,把資源自然分隔,保護了用戶的信息安全。
同源策略是一堵牆,然而牆並不是不透風。有不少方法能夠繞過同源策略讓javascript訪問其餘源的資源。好比:
JSONP:基於iframe的方法(iframe+window.name iframe+window.domain iframe+webMessage)
CORS:我認爲只有CORS是"正當的"繞過同源策略的方法 同源策略是瀏覽器安全策略的基礎,但同源策略面對不少攻擊是無能爲力的,好比XSS
跨站腳本攻擊,名字跟同源策略很像,事實上他們之間基本沒有關係。跨站腳本攻擊本質上是一種注入攻擊(有興趣瞭解更多注入攻擊能夠看Injection Theory)。其原理,簡單的說就是利用各類手段把惡意代碼添加到網頁中,並讓受害者執行這段腳本。XSS的例子只要百度一下有不少。XSS能作用戶使用瀏覽器能作的一切事情。能夠看到同源策略沒法保證不受XSS攻擊,由於此時攻擊者就在同源以內。
XSS攻擊從攻擊的方式能夠分爲:
反射型
存儲型
文檔型
這種分類方式有些過期,長久以來,人們認爲XSS分類有以上三種,但實際狀況中常常沒法區分,因此更明確的分類方式能夠分爲如下兩類:
client(客戶端型)
server(服務端型)
當一端XSS代碼是在服務端被插入的,那麼這就是服務端型XSS,同理,若是代碼在客戶端插入,就是客戶端型XSS。
不管是服務端型仍是客戶端型XSS,攻擊達成須要兩個條件:
代碼被注入
代碼被執行
其實只要作好不管任何狀況下保證代碼不被執行就能徹底杜絕XSS攻擊。詳情能夠看下XSS (Cross Site Scripting) Prevention Cheat Sheet這篇文章。
這裏簡單說下結論:任什麼時候候都不要把不受信任的數據直接插入到dom中的任何位置,必定要作轉義。
2.4.1 對於某些位置,不受信任的數據作轉義就能夠保證安全:
div body的內部html
通常的標籤屬性值
2.4.2 對於某些位置,即便作了轉義依然不安全:
<script>中
註釋中
表籤的屬性名名
標籤名
css標籤中
2.4.3 使用JSON.parse 而不是eval,request 的content-type要指定是Content-Type: application/json;
2.4.4 若是連接的URL中部分是動態生成的,必定要作轉義。
現代瀏覽器都對反射型XSS有必定的防護力,其原理是檢查url和dom中元素的相關性。但這並不能徹底防止反射型XSS。另外,瀏覽器對於存儲型XSS並無抵抗力,緣由很簡單,用戶的需求是多種多樣的。因此,抵禦XSS這件事情不能期望瀏覽器。
能夠經過http頭控制是否打開XSS-filter,固然默認是打開的.X-XSS-Protection
從原理上說防止XSS是很簡單的一件事,但實際中,業務代碼很是多樣和複雜,漏洞仍是時不時會出現。CSP並非用來防止XSS攻擊的,而是最小化XSS發生後所形成的傷害。事實上,除了開發者本身作好XSS轉義,並無別的方法能夠防止XSS的發生。CSP能夠說是html5給Web安全帶來的最實惠的東西。CSP的做用是限制一個頁面的行爲不管是否是javacript控制的。
如何引入CSP呢?
2.7.1 經過response頭
//只容許腳本從本源加載Content-Security-Policy: script-src 'self'
2.7.2 經過html的meta標籤
//做用同上<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
那麼CSP除了限制script-src以外還能限制什麼呢?
base-uri: 限制這篇文檔的uri;
child-src: 限制子窗口的源(iframe、彈窗等),取代frame-src;
connect-src: 限制腳本能夠訪問的源;
font-src: 限制字體的源;
form-action: 限制表單可以提交到的源;
frame-ancestors: 限制了當前頁面能夠被哪些頁面以iframe,frame,object等方式加載;
frame-src: deprecated with child-src,限制了當前頁面能夠加載哪些源,與frame-ancestors對應;
img-src: 限制圖片能夠從哪些源加載;
media-src: 限制video,audio, source,track可以從哪些源加載;
object-src: 限制插件能夠從哪些源加載;
sandbox: 強制打開沙盒模式;
能夠看出,CSP是一個強大的策略,幾乎能夠限制了全部可以用到的資源的來源。使用好CSP能夠很大成都下降XSS帶來的風險。另外,CSP還提供一個報告的頭Content-Security-Policy-Report-Only,使用這個頭瀏覽器向服務器報告CSP狀態,細節先不討論。
Content-Security-Policy-Report-Only:script-src'self'; report-uri/csp-report-endpoint/
CSP 目前有兩版:CSP1和CSP2。
兩版的支持狀態能夠在http://caniuse.com/#search=csp中查到。
CSP1:
CSP2:
這是response頭,如今正在使用,但之後能夠被CSP的frame-ancestors取代。目前支持的狀態比起CSP frame-ancestors要好,使用的方式:
X-Frame-Options:DENY//這個頁面不容許被以frame的方式加載
X-Frame-Options:SAMEORIGIN//這個頁面只容許同源頁面加載
X-Frame-Options:<uri> //這個頁面只能被特定的域加載
使用Http-only保護cookie,能夠保證即便發生了XSS,用戶的cookie也是安全的。使用Http-only保護的cookie是不會被javascript讀寫的。
雖然有同源策略,iframe的問題仍是有不少的,好比各類利用iframe進行跨源。HTML5爲iframe提供了安全屬性sandbox,若是使用此屬性,iframe的能力將會被限制,細節咱們將會在之後的文章中詳細討論。
X-Content-Type-Options阻止瀏覽器進行content-type 嗅探。告訴瀏覽器相信此服務器下發的資源的類型,防止類型嗅探攻擊。
HPKP(Public Key Pinning)Public Key Pinning是一個response頭,用來檢測一個證書的公鑰是否發生了改變,防止中間人攻擊。
HSTS (HTTP Strict-Transport-Security) 強制使用TSL做爲數據通道,在扒一扒HTTPS網站的內幕中也有詳細介紹。
說了這麼多咱們看如下一些各個網站實現的狀況:
谷歌是行業的標杆,在互聯網無出其右,學習Google就對了!
咱們野狗的官網https://www.wilddog.com/一樣也實現了幾個重要的http頭。
百度作的就比較差了,一家如此大規模的互聯網公司,對於安全,對於技術如此不敏感,只能說是很悲哀,充分說明中國互聯網企業對安全的重視是很是低的!值得注意的是,百度的http到https的跳轉竟然是服務端作的。
咱們再來看下行業笑話12306。
HTML5帶來了不少新的特性,讓瀏覽器和javascript得到了更大的能力。然而能力越大,被攻破後的危險就越大。
HTML5對XSS的影響主要體如今:
更大的攻擊面,HTML5帶來來更多的標籤和更多的屬性,XSS發生的可能性更大。
更大的危害,HTML5更多的資源能夠被XSS利用。黑客能夠利用瀏覽器的一切權限,好比本地存儲,GEO,WebSocket,Webworker。
遺憾的是HTML並無針止XSS和XSRF帶來系統性解決方案。在這個前提下,CSP變得很是重要,能夠大大下降XSS後的危害。
HTML5時代實際對開發者提出來更高的要求,由於有更多的交互,更多的前端行爲,HTML5有更多的API。但願共勉,不作蒙古大夫,與廣大的開發者一同提升中國互聯網的用戶體驗!
安全相關的HTTP頭 https://www.owasp.org/index.php/List_of_useful_HTTP_headers
同源策略 https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
HPKP https://developer.mozilla.org/en-US/docs/Web/Security/Public_Key_Pinning
w3c iframe element http://www.w3.org/TR/2011/WD-html5-20110525/the-iframe-element.html
MDN web security https://developer.mozilla.org/en-US/docs/Web/Security
XSS cheet sheet https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
野狗科技官網 https://www.wilddog.com/