2020-7-28 seo達人
Web 安全是互聯網中不可或缺的一個領域,這個領域中誕生了大量的黑帽子與白帽子,他們都是安全領域的王者,在平時里,他們利用各種巧妙的技術互相博弈,時不時就會掀起一場 Web 安全浪潮,真可謂神仙打架,各顯神通。
本文從一個吃瓜群眾的角度,聊一聊 Web 安全的一些有趣故事。
安全世界觀
安全攻防案例
總結與思考
安全世界觀
在互聯網發展之初,IE 瀏覽器壟斷的時期,大家上網的目的都很單純,主要通過瀏覽器分享信息,獲取新聞。但隨著互聯網的不斷發展發展,一個網頁能做的事情越來越多,除了看新聞,我們還可以看視頻、玩游戲、購物、聊天等,這些功能都大大豐富了我們的生活。
隨著網頁功能的逐漸增多,就開始出現了一些黑帽子,他們試圖通過一些技術手段來牟取利益。在我小的時候,印象最深的就是木馬病毒,它可以監控你的鍵盤,將你在鍵盤上敲打的內容發送到黑客的機器上,黑客通過分析這些內容,很容易就能得到你的游戲賬號和密碼。
在這之后,就誕生出了一些殺毒軟件,致力于解決網絡上的各種病毒,隨著不斷地發展,殺毒軟件已經成為一臺電腦必不可少的軟件。
為什么會出現這樣的安全問題?
安全歸根到底是信任的問題,如果所有人都按照正常的流程去上網,不去謀取私利,也就沒有安全問題可談了。
安全的根本在于信任,但要讓所有人互相信任談何容易。在當前階段,我們可以做到:持續做好安全防護,讓漏洞越來越少,非法攻擊越來越困難,這樣就能逐漸減少黑帽子的數量,讓病毒制造者越來越少。
如何做好安全
要做好安全,首先得理解安全問題的屬性,前人通過無數實踐,最后將安全的屬性總結為安全三要素,分別為:機密性、完整性、可用性。
機密性
保護數據內容不被泄露。
通常使用加密的方法。
完整性
保護數據內容是完整的、沒有被篡改。
通常使用數字簽名的方法。
可用性
數據隨時都能夠使用。
通常是在防御 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)跨站請求偽造,是一種利用用戶身份,執行一些用戶非本意的操作。
如圖所示:
用戶先登錄了服務器 B,然后去訪問服務器 C。
服務器 C 通過惡意腳本,冒充 A 去調用服務器 B 上的某個功能,
對于服務器 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 安全中的冰山一角,如果你對此感興趣,不妨在安全領域繼續深耕學習,一定能看到更廣闊一片天。
對于一個開發者來說,我們應該在寫代碼時就將安全考慮其中,形成自己的一套安全開發體系,做到心中有安全,時時考慮安全,就能無形之中化解不法分子的攻擊。
藍藍設計( ssll180.com )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務