by ouvenjavascript
web前端安全方面技術含有的東西較多,這裏就來理一理web安全方面所涉及的一些問題。css
入門級的安全知識,攻擊手段和防範方法這裏略過,不過注意的是xss分存儲型xss、反射型xss、mxss(dom xss),主要防範思路是檢查驗證要輸入到頁面上的內容是否安全。前端
入門級的安全知識,攻擊手段和防範方法這裏略過java
請求劫持如今主要分爲兩種,DNS劫持與HTTP劫持:git
DNS劫持:github
DNS劫持就是經過劫持了DNS服務器,經過某些手段取得某域名的解析記錄控制權,進而修改此域名的解析結果,致使對該域名的訪問由原IP地址轉入到修改後的指定IP,其結果就是對特定的網址不能訪問或訪問的是假網址,從而實現竊取資料或者破壞原有正常服務的目的。DNS劫持經過篡改DNS服務器上的數據返回給用戶一個錯誤的查詢結果來實現的。 DNS劫持症狀:在某些地區的用戶在成功鏈接寬帶後,首次打開任何頁面都指向ISP提供的「電信互聯星空」、「網通黃頁廣告」等內容頁面。還有就是曾經出現過用戶訪問Google域名的時候出現了百度的網站。這些都屬於DNS劫持。 再說簡單點,當你輸入google.com這個網址的時候,你看到的網站倒是百度的首頁。web
http劫持:算法
在用戶的客戶端與其要訪問的服務器通過網絡協議協調後,兩者之間創建了一條專用的數據通道,用戶端程序在系統中開放指定網絡端口用於接收數據報文,服務器端將所有數據按指定網絡協議規則進行分解打包,造成連續數據報文。 用戶端接收到所有報文後,按照協議標準來解包組合得到完整的網絡數據。其中傳輸過程當中的每個數據包都有特定的標籤,表示其來源、攜帶的數據屬性以及要到何處,全部的數據包通過網絡路徑中ISP的路由器傳輸接力後,最終到達目的地,也就是客戶端。 HTTP劫持是在使用者與其目的網絡服務所創建的專用數據通道中,監視特定數據信息,提示當知足設定的條件時,就會在正常的數據流中插入精心設計的網絡數據報文,目的是讓用戶端程序解釋「錯誤」的數據,並以彈出新窗口的形式在使用者界面展現宣傳性廣告或者直接顯示某網站的內容。列入本地的fiddler爲一種劫持sql
請求劫持惟一可行的預防方法就是儘可能使用HTTPS協議訪問。chrome
什麼是https,這裏再也不解釋了,簡單理解就是經過SSL(Secure Sockets Layer)層來加密http數據來進行安全傳輸。 那使用HTTPS是怎樣進行安全數據傳輸的?
先看個有意思的問題:
A、B兩我的分別在兩個島上,而且分別有一個箱子,一把鎖,和打開這把鎖的鑰匙(A的鑰匙打不開B手上的鎖,B的鑰匙也打不開A的鎖)。此時A要跟B互通情報,此時須要藉助C的船運輸,C是一個不可靠的人,若是A直接把情報送給B或把情報放在箱子裏給B,均可能會被C偷走;若是A把情報鎖在箱子裏,B沒有打開A鎖的鑰匙沒法得到情報內容。請問有什麼辦法能夠儘量快的讓A和B互通情報。
這就是公鑰和私鑰的問題了,答案比較簡單,也對應了公鑰和私鑰在https中的應用過程。
公鑰(Public Key)與私鑰(Private Key)是經過一種算法獲得的一個密鑰對(即一個公鑰和一個私鑰),公鑰是密鑰對中公開的部分,私鑰則是非公開的部分。公鑰一般用於加密會話密鑰、驗證數字簽名,或加密能夠用相應的私鑰解密的數據。經過這種算法獲得的密鑰對能保證在世界範圍內是惟一的。使用這個密鑰對的時候,若是用其中一個密鑰加密一段數據,必須用另外一個密鑰解密。好比用公鑰加密數據就必須用私鑰解密,若是用私鑰加密也必須用公鑰解密,不然解密將不會成功。—百度百科
整個通訊過程以下圖,以公鑰加密方式爲例:
一、客戶端發送https請求,告訴服務器發將創建https鏈接 二、服務器將服務端生成的公鑰返回給客戶端,若是是第一次請求將告訴客戶端須要驗證連接 三、客戶端接收到請求後’client finished’報文串經過獲取到的服務器公鑰加密發送給服務器,並將客戶端生成的公鑰也發送給服務器 四、服務器獲取到加密的報文和客戶端公鑰,先使用服務器私鑰解密報文,而後將報文經過客戶端的公鑰加密返回給客戶端。 五、客戶端經過私鑰解密報文,判斷是否爲本身開始發送的報文串;若是正確,說明安全鏈接驗證成功,將數據經過服務器公鑰加密不斷髮送給服務器,服務器也不斷解密獲取報文,並經過客戶端公鑰加密返回給客戶端驗證。這樣就創建了不斷通訊的鏈接。
以打開 https://github.com/ 的過程爲例,請求通用頭部以下
Request URL:https://github.com/ouvens\n Request Method:GET Status Code:200 OK (from cache) Remote Address:192.30.252.131:443 Response Headers |
先看下請求頭的字段
再截取部分返回頭的字段
須要注意的upgrade-insecure-requests
https正常升級後chrome瀏覽器會出現下面的警告
考慮到這個問題,w3c在2015年4月份出了一個 Upgrade Insecure Requests 的草案,他的做用就是讓瀏覽器自動升級請求。在服務器的響應頭中加入:
header(「Content-Security-Policy: upgrade-insecure-requests」);
http層面上瀏覽器設置的安全性控制較多,這裏列幾個典型的來看看:
這個header主要是用來防止瀏覽器中的反射性xss。如今,只有IE,chrome和safari(webkit)支持這個header。
正確的設置:
X-XSS-Protection:1; mode=block 0 – 關閉對瀏覽器的xss防禦 1 – 開啓xss防禦 1; mode=block – 開啓xss防禦並通知瀏覽器阻止而不是過濾用戶注入的腳本。 1; report=http://site.com/report – 這個只有chrome和webkit內核的瀏覽器支持,這種模式告訴瀏覽器當發現疑似xss攻擊的時候就將這部分數據post到指定地址。 一般不正確的設置 |
&ems; 這個header主要用來防止在IE九、chrome和safari中的MIME類型混淆攻擊。firefox目前對此還存在爭議。一般瀏覽器能夠經過嗅探內容自己的方法來決定它是什麼類型,而不是看響應中的content-type值。經過設置 X-Content-Type-Options:若是content-type和指望的類型匹配,則不須要嗅探,只能從外部加載肯定類型的資源。舉個例子,若是加載了一個樣式表,那麼資源的MIME類型只能是text/css,對於IE中的腳本資源,如下的內容類型是有效的:
application/ecmascript application/javascript application/x-javascript text/ecmascript text/javascript text/jscript text/x-javascript text/vbs text/vbscript |
對於chrome,則支持下面的MIME 類型:
text/javascript text/ecmascript application/javascript application/ecmascript application/x-javascript text/javascript1.1 text/javascript1.2 text/javascript1.3 text/jscript text/live script |
nosniff – 這個是惟一正確的設置,必須這樣。
Strict Transport Security (STS) 是用來配置瀏覽器和服務器之間安全的通訊。它主要是用來防止中間人攻擊,由於它強制全部的通訊都走TLS。目前IE還不支持 STS頭。須要注意的是,在普通的http請求中配置STS是沒有做用的,由於攻擊者很容易就能更改這些值。爲了防止這樣的現象發生,不少瀏覽器內置了一個配置了STS的站點list。
正確的設置 : 注意下面的值必須在https中才有效,若是是在http中配置會沒有效果。
max-age=31536000 – 告訴瀏覽器將域名緩存到STS list裏面,時間是一年。 max-age=31536000; includeSubDomains – 告訴瀏覽器將域名緩存到STS list裏面而且包含全部的子域名,時間是一年。 max-age=0 – 告訴瀏覽器移除在STS緩存裏的域名,或者不保存此域名。 一般不正確的設置 |
判斷一個主機是否在你的STS緩存中,chrome能夠經過訪問chrome://net-internals/#hsts,首先,經過域名請求選項來確認此域名是否在你的STS緩存中。而後,經過https訪問這個網站,嘗試再次請求返回的STS頭,來決定是否添加正確。
CSP是一種由開發者定義的安全性政策性申明,經過CSP所約束的的規責指定可信的內容來源(這裏的內容能夠指腳本、圖片、iframe、fton、style等等可能的遠程的資源)。經過CSP協定,讓WEB可以加載指定安全域名下的資源文件,保證運行時處於一個安全的運行環境中。
正確配置:
Content-Security-Policy:default-src *; base-uri 'self'; block-all-mixed-content; child-src 'self' render.githubusercontent.com; connect-src 'self' uploads.github.com status.github.com api.github.com www.google-analytics.com github-cloud.s3.amazonaws.com wss://live.github.com; font-src assets-cdn.github.com; form-action 'self' github.com gist.github.com; frame-src 'self' render.githubusercontent.com; img-src 'self' data: assets-cdn.github.com identicons.github.com www.google-analytics.com collector.githubapp.com *.gravatar.com *.wp.com *.githubusercontent.com; media-src 'none'; object-src assets-cdn.github.com; plugin-types application/x-shockwave-flash; script-src assets-cdn.github.com; style-src 'self' 'unsafe-inline' assets-cdn.github.com |
這個header主要用來配置哪些網站能夠經過frame來加載資源。它主要是用來防止UI redressing 補償樣式攻擊。IE8和firefox 18之後的版本都開始支持ALLOW-FROM。chrome和safari都不支持ALLOW-FROM,可是WebKit已經在研究這個了。
正確的設置
X-Frame-Options: deny deny – 禁止全部的資源(本地或遠程)試圖經過frame來加載其餘也支持X-Frame-Options 的資源。 sameorigion – 只容許遵照同源策略的資源(和站點同源)經過frame加載那些受保護的資源。 allow-from http://www.example.com – 容許指定的資源(必須帶上協議http或者https)經過frame來加載受保護的資源。這個配置只在IE和firefox下面有效。其餘瀏覽器則默認容許任何源的資源(在X-Frame-Options沒設置的狀況下)。 |
Access-Control-Allow-Origin是從Cross Origin Resource Sharing (CORS)中分離出來的。這個header是決定哪些網站能夠訪問資源,經過定義一個通配符來決定是單一的網站仍是全部網站能夠訪問咱們的資源。須要注意的是,若是定義了通配符,那麼 Access-Control-Allow-Credentials選項就無效了,並且user-agent的cookies不會在請求裏發送。
正確的設置
Access-Control-Allow-Origin : * *– 通配符容許任何遠程資源來訪問含有Access-Control-Allow-Origin 的內容。 http://www.example.com – 只容許特定站點才能訪問(http://[host], 或者 https://[host]) |
公鑰固定(Public Key Pinning)是指一個證書鏈中必須包含一個白名單中的公鑰,也就是說只有被列入白名單的證書籤發機構(CA)才能爲某個域名*.example.com簽發證書,而不是你的瀏覽器中所存儲的任何 CA 均可覺得之簽發。能夠理解爲https的證書域名白名單。 Public-Key-Pins (PKP)的目的主要是容許網站經營者提供一個哈希過的公共密鑰存儲在用戶的瀏覽器緩存裏。跟Strict-Transport-Security功能類似的是,它能保護用戶免遭中間人攻擊。這個header可能包含多層的哈希運算,好比pin-sha256=base64(sha256(SPKI)),具體是先將 X.509 證書下的Subject Public Key Info (SPKI) 作sha256哈希運算,而後再作base64編碼。然而,這些規定有可能更改,例若有人指出,在引號中封裝哈希是無效的,並且在33版本的chrome中也不會保存pkp的哈希到緩存中。
這個header和 STS的做用很像,由於它規定了最大子域名的數量。此外,pkp還提供了一個Public-Key-Pins-Report-Only 頭用來報告異常,可是不會強制阻塞證書信息。固然,這些chrome都是不支持的。
請求頭說明參考:
https://www.veracode.com/blog/2014/03/guidelines-for-setting-security-headers/
總結下web的安全策略,主要介紹了websql注入防範、xss防範、csrf防範、劫持與https、Content-Security-Policy、Strict-Transport-Security、Access-Control-Allow-Origin、X-Frame-Options等。