一文讀懂 Web 安全

Web 安全是互聯網中不可或缺的一個領域,這個領域中誕生了大量的黑帽子與白帽子,他們都是安全領域的王者,在平時裏,他們利用各類巧妙的技術互相博弈,時不時就會掀起一場 Web 安全浪潮,真可謂神仙打架,各顯神通。php

本文從一個吃瓜羣衆的角度,聊一聊 Web 安全的一些有趣故事。css

  • 安全世界觀
  • 安全攻防案例
  • 總結與思考

安全世界觀

在互聯網發展之初,IE 瀏覽器壟斷的時期,你們上網的目的都很單純,主要經過瀏覽器分享信息,獲取新聞。但隨着互聯網的不斷髮展發展,一個網頁能作的事情愈來愈多,除了看新聞,咱們還能夠看視頻、玩遊戲、購物、聊天等,這些功能都大大豐富了咱們的生活。前端

隨着網頁功能的逐漸增多,就開始出現了一些黑帽子,他們試圖經過一些技術手段來牟取利益。在我小的時候,印象最深的就是木馬病毒,它能夠監控你的鍵盤,將你在鍵盤上敲打的內容發送到黑客的機器上,黑客經過分析這些內容,很容易就能獲得你的遊戲帳號和密碼。web

在這以後,就誕生出了一些殺毒軟件,致力於解決網絡上的各類病毒,隨着不斷地發展,殺毒軟件已經成爲一臺電腦必不可少的軟件。正則表達式

爲何會出現這樣的安全問題?

安全歸根究竟是信任的問題,若是全部人都按照正常的流程去上網,不去謀取私利,也就沒有安全問題可談了。算法

安全的根本在於信任,但要讓全部人互相信任談何容易。在當前階段,咱們能夠作到:持續作好安全防禦,讓漏洞愈來愈少,非法攻擊愈來愈困難,這樣就能逐漸減小黑帽子的數量,讓病毒製造者愈來愈少。sql

如何作好安全

要作好安全,首先得理解安全問題的屬性,前人經過無數實踐,最後將安全的屬性總結爲安全三要素,分別爲:機密性、完整性、可用性。shell

  • 機密性數據庫

    • 保護數據內容不被泄露。
    • 一般使用加密的方法。
  • 完整性後端

    • 保護數據內容是完整的、沒有被篡改。
    • 一般使用數字簽名的方法。
  • 可用性

    • 數據隨時都可以使用。
    • 一般是在防護 DOS。

有了安全 3 要素以後,咱們就能夠對安全問題進行評估了。

  • 資產等級劃分

    • 找出最重要的數據。
    • 找出最重要數據的宿主空間,如:在數據庫裏,那麼數據庫就得重點防護。
    • 找出數據庫的宿主空間,如:在一臺服務器上,那麼這臺服務器就得作次等防護。
    • 找出服務器的宿主空間,如:在 OSI 網絡層級上,那麼在網絡層面就得作通常防護。
  • 威脅分析

    • 找出威脅(可能形成危害的來源)。
    • 找出風險(可能出現的損失叫作風險)。
  • 風險分析

    • 採起多標準決策分析,即:風險 = 威脅等級 * 威脅可行性。
    • 計算全部的威脅,將最終的風險進行排序,優先解決風險大的問題。
  • 確認解決方案

    • 找出不安全的實現方式,並肯定解決方案。
    • 解決方案不要改變商業需求的初衷。
    • 解決方案需對用戶透明,不要改變用戶的習慣。

作好安全評估以後,咱們就有了一份安全解決方案,後續的安全工做只需按照這個方案去作,就沒有任何問題。

安全的原則

有了安全解決方案以後,咱們還能夠制定一些安全原則,遵照原則作事,可讓咱們事半功倍。

  • 黑名單、白名單原則

    • 白名單方案指的是給安全的資源受權。
    • 黑名單方案指的是禁用不安全的資源。
    • 咱們應該優先使用白名單方案,由於黑名單一般統計不完全部的不安全資源。
    • 如:XSS 攻擊的方式很是多,能夠經過 script、css、image 標籤等,儘管你將這些標籤都加入黑名單,也不能保證其餘的標籤都沒有 XSS 的攻擊隱患。
  • 最小權限原則

    • 只授予必要的權限,不要過分受權,減小出錯機會。
    • 如:普通權限的 Linux 用戶只能操做 ~ 文件夾下的目錄,若是有人想刪庫跑路,在執行 rm -rf / 時,就會提示無權限。
  • 縱深防護原則

    • 這條原則相似 木桶理論,安全水平每每取決於最短的那塊板。
    • 即:不要留下短板,黑帽子們每每能夠利用短板爲突破口,挖掘更大的漏洞。
  • 數據與代碼分離原則

    • 當用戶數據被當成代碼執行時,混淆了數據和代碼的邊界,從而致使安全問題。
    • 如:XSS 就是利用這一點去攻擊的。
  • 不可預測性原則

    • 這條原則是爲了提升攻擊門檻,有效防止基於篡改、僞造的攻擊。
    • 如:數據庫中使用 uuid 代替 number 型的自增主鍵,能夠避免 id 被攻擊者猜到,從而進行批量操做。
    • token 也是利用不可預測性,攻擊者沒法構造 token 也就沒法進行攻擊。

有了這些安全原則,咱們就能夠開幹了,接下來介紹幾個常見的攻防案例。

安全攻防案例

安全攻防的案例很是多,這裏主要介紹幾個出鏡率比較高的安全問題。

客戶端攻擊

  • XSS 攻擊
  • CSRF 攻擊
  • 點擊劫持

XSS 攻擊

XSS 攻擊的本質是將用戶數據當成了 HTML 代碼一部分來執行,從而混淆本來的語義,產生新的語義。

如圖所示,咱們註冊了一個 <script>alert(document.cookie)</script> 的用戶名,全部能看到此用戶名字的頁面,都會彈出當前瀏覽器的 Cookie,若是代碼的邏輯是將 Cookie 發送到攻擊者的網站,攻擊者就能冒充當前用戶進行登陸了。

XSS 攻擊方式有不少,全部和用戶交互的地方,都有可能存在 XSS 攻擊。

例如:

  • 全部 input 框。
  • window.location。
  • window.name。
  • document.referrer。
  • document.cookie。
  • localstorage。
  • ...

因爲頁面中與用戶交互的地方很是多,確定還有一些 XSS 的攻擊方式沒有被發現,而一旦被黑帽子發現,就可能形成嚴重的影響,因此咱們務必引發重視。

XSS 攻擊影響

被 XSS 攻擊成功後,攻擊者就能夠獲取大量的用戶信息,例如:

  • 識別用戶 UA。
  • 識別用戶瀏覽器擴展。
  • 識別用戶瀏覽過的網站。

    • 經過 CSS 的 Visited 屬性。
  • 獲取用戶真實的 IP。

    • 經過 WebRTC 等。
  • 盜取 Cookie

    • 僞造用戶登陸,竊取用戶資料。
  • XSS 釣魚。

    • 向頁面注入一個登陸彈窗,讓用戶認爲是網站內的登陸彈窗(實際上是釣魚網站的),一旦用戶登陸,帳號密碼就泄露給了釣魚網站。
XSS 攻擊防護

目前來講,XSS 已經獲得了互聯網行業的重視,許多開發框架都內置了安全的 HTML 渲染方法。

咱們也能夠自定義進行一些安全配置。

  • 配置 HTTP 中的 http-only 頭,讓前端 JS 不能操做 Cookie。
  • 輸入檢查,在用戶提交數據時,使用 XssFilter 過濾掉不安全的數據。
  • 輸出檢查,在頁面渲染的時候,過濾掉危險的數據。

CSRF 攻擊

CSRF(Cross-site request forgery)跨站請求僞造,是一種利用用戶身份,執行一些用戶非本意的操做。

如圖所示:

  1. 用戶先登陸了服務器 B,而後去訪問服務器 C。
  2. 服務器 C 經過惡意腳本,冒充 A 去調用服務器 B 上的某個功能,
  3. 對於服務器 B 來講,還覺得這是 A 發起的請求,就看成正常請求處理了。

試想一下,若是 C 冒充 A 進行了一次轉帳,一定會形成大量的經濟損失。

CSRF 防護方式

防護 CSRF 主要有如下幾種方式:

  • 驗證碼

    • 每一次請求都要求用戶驗證,以確保請求真實可靠。
    • 即:利用惡意腳本不能識別複雜的驗證碼的特色,保證每次請求都是合法的。
  • Referer 檢查

    • 檢查發起請求的服務器,是否爲目標服務器。
    • 即:HTTP 請求中的 Referer 頭傳遞了當前請求的域名,若是此域名是非法服務器的域名,則須要禁止訪問。
  • Token

    • 利用不可預測性原則,每一請求必須帶上一段隨機碼,這段隨機碼由正經常使用戶保存,黑帽子不知道隨機碼,也就沒法冒充用戶進行請求了。

點擊劫持

點擊劫持是一種視覺欺騙的攻擊手段。攻擊者將須要攻擊的網站經過 iframe 嵌套的方式嵌入本身的網頁中,並將 iframe 設置爲透明,在頁面中透出一個按鈕誘導用戶點擊。

就像一張圖片上面鋪了一層透明的紙同樣,你看到的是攻擊者的頁面,可是其實這個頁面只是在底部,而你真正點擊的是被攻擊者透明化的另外一個網頁。

若是所示,當你點擊了頁面上的按鈕以後,本覺得會...... ,而真正執行的操做是關注了某人的博客。

點擊劫持防護

因爲點擊劫持主要經過 iframe,因此在防護時,主要基於 iframe 去作。

  • 方案一:frame busting

    • 正常網站使用 JS 腳本判斷是否被惡意網站嵌入,如:博客網站監測到被一個 iframe 打開,自動跳轉到正常的頁面便可。
    if (self !== top) {  // 跳回原頁面  top.location = self.location;}
  • 方案二:使用 HTTP 中的 x-frame-options 頭,控制 iframe 的加載,它有 3 個值可選:

    • DENY,表示頁面不容許經過 iframe 的方式展現。
    • SAMEORIGIN,表示頁面能夠在相同域名下經過 iframe 的方式展現。
    • ALLOW-FROM,表示頁面能夠在指定來源的 iframe 中展現。
  • 配置 iframe 的 sandbox 屬性

    • sandbox = "allow-same-origin" 則只能加載與主站同域的資源。

服務器端攻擊

服務器端的攻擊的方式也很是多,這裏列舉幾個常見的。

  • SQL 注入攻擊
  • 文件上傳漏洞
  • 登陸認證攻擊
  • 應用層拒絕服務攻擊
  • webServer 配置安全

SQL 注入攻擊

SQL 注入和 XSS 同樣,都是違背了數據和代碼分離原則致使的攻擊方式。

如圖所示,咱們利用 SQL 注入,就能在不須要密碼的狀況下,直接登陸管理員的帳號。

攻擊的前提是:後端只用了簡單的拼接 SQL 的方式去查詢數據。

# 拼接出來的 sql 以下:select * from user where username = 'admin' or 1=1 and password = 'xxx'# 不管密碼輸入什麼,這條 sql 語句都能查詢到管理員的信息

除此以外,SQL 注入還有如下幾種方式:

  • 使用 SQL 探測,猜數據庫表名,列名。

    • 經過 MySQL 內置的 benchmark 探測數據庫字段。
    • 如:一段僞代碼 select database as current if current[0]==='a',benchmark(10000,'猜對了') 若是代表猜對了,就延遲 10 s 並返回成功。
  • 使用存儲過程執行系統命令

    • 經過內置的方法或存儲過程執行 shell 腳本。
    • 如:xp_cmdshell、sys_eval、sys_exec 等。
  • 字符串截斷

    • 如:MySQL 在處理超長的字符串時,會顯示警告,但會執行成功。
    • 註冊一個 admin + 50 個空格的用戶,會觸發截斷,最終新增一個 admin 用戶,這樣就能擁有管理員權限了。
SQL 注入防護

防止 SQL 注入的最好的辦法就是,不要手動拼接 SQL 語句。

  • 最佳方案,使用預編譯語句綁定變量

    • 一般是指框架提供的拼接 SQL 變量的方法。
    • 這樣的語義不會發生改變,變量始終被當成變量。
  • 嚴格限制數據類型,若是注入了其餘類型的數據,直接報錯,不容許執行。
  • 使用安全的存儲過程和系統函數。
CRLF 注入

在注入攻擊中,換行符注入也是很是常見的一種攻擊方式。

  • 若是在 HTTP 請求頭中注入 2 個換行符,會致使換行符後面的全部內容都被解析成請求實體部分。
  • 攻擊者一般在 Set-Cookie 時,注入換行符,控制請求傳遞的內容。

文件上傳漏洞

上傳文件是網頁開發中的一個常見功能,若是不加處理,很容易就會形成攻擊。

如圖所示,攻擊者上傳了一個木馬文件,而且經過返回的 URL 進行訪問,就能控制服務器。

一般咱們會控制上傳文件的後綴名,但也不能徹底解決問題,攻擊者還能夠經過如下方式進行攻擊:

  • 僞造正常文件

    • 將木馬文件假裝成正常的後綴名進行上傳。
    • 若是要避免這個問題,咱們能夠繼續判斷上傳文件的文件頭前 10 個字節。
  • Apache 解析方式是從後往前解析,直到找到一個認識的後綴名爲止

    • 如:上傳一個 abc.php.rar.rar.rar 能繞事後綴名檢查,但在執行時,被當成一個 php 文件進行執行。
  • IIS 會截斷分號進行解析

    • 如:abc.asp;xx.png 能繞事後綴名檢查,但在執行時,被當成一個 asp 文件進行執行。
  • HTTP PUT 方法容許將文件上傳到指定位置

    • 經過 HTTP MOVE 方法,還能修改上傳的文件名。
    • 經過兩者配合,就能先上傳一個正常的後綴名,而後改成一個惡意的後綴名。
  • PHP CGI 路徑問題

    • 執行 http://abc.com/test.png/xxx.php 時,會把 test.png 當作 php 文件去解析。
    • 若是用戶正好是把一段惡意的 php 腳本當作一張圖片進行上傳,就會觸發這個攻擊。
文件上傳漏洞防護

防護文件上傳漏洞,能夠從如下幾點考慮:

  • 將文件上傳的目錄設置爲不可執行。
  • 判斷文件類型

    • 檢查 MIME Type,配置白名單。
    • 檢查後綴名,配置白名單。
  • 使用隨機數改寫文件名和文件路徑

    • 上傳文件後,隨機修改文件名,讓攻擊者沒法執行攻擊。
  • 單獨設置文件服務器的域名

    • 單獨作一個文件服務器,並使用單獨的域名,利用同源策略,規避客戶端攻擊。
    • 一般作法是將靜態資源存放在 CDN 上。

登陸認證攻擊

登陸認證攻擊能夠理解爲一種破解登陸的方法。攻擊者一般採用如下幾種方式進行破解:

  • 彩虹表

    • 攻擊者經過蒐集大量明文和 MD5 的對應關係,用於破解 MD5 密文找出原文。
    • 對於彩虹表中的 MD5 密碼,咱們能夠加鹽,進行二次加密,避免被破解。
  • Session Fixation 攻擊

    • 利用應用系統在服務器的 SessionID 固定不變機制,藉助他人用相同的 SessionID 獲取認證和受權。
    • 攻擊者登陸失敗後,後端返回了 SessionID,攻擊者將 SessionID 交給正經常使用戶去登陸,登陸成功後,攻擊者就能使用這個 SessionID 冒充正經常使用戶登陸了。
    • 若是瀏覽器每一次登陸都刷新 SessionID 能夠避免這個問題。
  • Session 保持攻擊

    • 有些時候,後端出於用戶體驗考慮,只要這個用戶還活着,就不會讓這個用戶的 Session 失效。
    • 攻擊者能夠經過不停發起請求,可讓這個 Session 一直活下去。
登陸認證防護方式
  • 多因素認證

    • 密碼做爲第一道防護,但在密碼驗證成功後,咱們還能夠繼續驗證:動態口令,數字證書,短信驗證碼等,以保證用戶安全。
    • 因爲短信和網頁徹底是 2 套獨立的系統,攻擊者很難獲取到短信驗證碼,也就沒法進行攻擊。

除此以外,前端登陸認證還有多種方式,若是你對此感興趣,能夠參考我以前寫的 前端登陸,這一篇就夠了

應用層拒絕服務攻擊

應用層拒絕服務攻擊,又叫 DDOS 攻擊,它指的是利用大量的請求形成資源過載,致使服務器不可用。

一般有如下幾種 DDOS 攻擊方式:

  • SYN Flood 洪水攻擊

    • 利用 HTTP 3 次握手機制,消耗服務器鏈接資源。
    • 如:攻擊者發起大量的 HTTP 請求,但並不完成 3 次握手,而是隻握手 2 次,這時服務器端會繼續等待直至超時。這時的服務器會一直忙於處理大量的垃圾請求,而無暇顧及正常請求。
  • Slowloris 攻擊

    • 以很是低的速度發送 HTTP 請求頭,消耗服務器鏈接資源。
    • 如:攻擊者發送大量 HTTP 請求,但每一個請求頭都發的很慢,每隔 10s 發送一個字符,服務器爲了等待數據,不得始終保持鏈接,這樣一來,服務器鏈接數很快就被佔光了。
  • HTTP POST DOS

    • 發送 HTTP 時,指定一個很是大的 Content-Length 而後以很長的間隔發送,消耗服務器鏈接資源。
  • CC 攻擊

    • 針對一些很是消耗資源的頁面,不斷髮起請求。
    • 如:頁面中的某些頁面,須要後端作大量的運算,或者須要作很是耗時的數據庫查詢。在大量的請求下,服務器的 CPU、內存等資源可能就被佔光了。
  • Server Limit DOS

    • 經過 XSS 注入一段超長的 Cookie,致使超出 Web 服務器所能承受的 Request Header 長度,服務器端就會拒絕此服務。
  • ReDOS

    • 針對一些缺陷的正則表達式,發起大量請求,耗光系統資源。
應用層拒絕服務攻擊防護

對於應用層拒絕服務攻擊,目前也沒有特別完美的解決方案,不過咱們仍是能夠進行一些優化。

  • 應用代碼作好性能優化

    • 合理使用 Redis、Memcache 等緩存方案,減小 CPU 資源使用率。
  • 網絡架構上作好優化

    • 後端搭建負載均衡。
    • 靜態資源使用 CDN 進行管理。
  • 限制請求頻率

    • 服務器計算全部 IP 地址的請求頻率,篩選出異常的 IP 進行禁用。
    • 可使用 LRU 算法,緩存前 1000 條請求的 IP,若是有 IP 請求頻率太高,就進行禁用。

其實,處理 DDOS 核心思路就是禁用不可信任的用戶,確保資源都是被正常的用戶所使用。

WebServer 配置安全

咱們在部署 web 應用的時候,常常會用到 Nginx、Apache、IIS、Tomcat、Jboss 等 Web 服務器,這些服務器自己也存在一些安全隱患,若是配置不當,很容易收到攻擊。

在配置 Web 服務器時,能夠參考如下幾點:

  • 以用戶權限運行 Web 服務器

    • 遵照最小權限原則,以最小權限身份運行 Web 服務器,限制被入侵後的權限。
  • 刪除可視化後臺

    • 運行 Tomcat、Jboss 等 Web 服務器時,默認會開啓一個可視化的運營後臺,運行在 8080 端口,而且第一次訪問是沒有認證的。
    • 攻擊者能夠利用可視化後臺,遠程加載一段 war 包或者上傳木馬文件,進行控制。
  • 及時更新版本

    • 主流的 Web 服務器,每隔一段時間就會修復一些漏洞,因此記得及時更新版本。

總結與思考

本文介紹了 Web 安全的基本概念,以及大量的攻防技巧,其實這只是 Web 安全中的冰山一角,若是你對此感興趣,不妨在安全領域繼續深耕學習,必定能看到更廣闊一片天。

對於一個開發者來講,咱們應該在寫代碼時就將安全考慮其中,造成本身的一套安全開發體系,作到心中有安全,時時考慮安全,就能無形之中化解不法分子的攻擊。

最後,若是你對此有任何想法,歡迎留言評論!

相關文章
相關標籤/搜索