10 個最常見的網絡安全漏洞
已發表: 2022-03-11對於太多的公司來說,直到發生安全漏洞之後,Web 安全最佳實踐才成為優先事項。 在我作為 IT 安全專業人士的這些年裡,我一次又一次地看到 Web 開發安全問題對我的許多程序員同事來說是多麼晦澀難懂。
根據定義,應對網絡安全威脅的有效方法必須具有主動性和防禦性。 為此,這篇文章旨在激發一種安全心態,希望給讀者註入健康的偏執狂。
特別是,本指南重點介紹了需要注意的 10 個常見且重要的 Web 安全陷阱,包括有關如何緩解這些陷阱的建議。 重點關注由開放 Web 應用程序安全項目 (OWASP) 確定的十大 Web 漏洞,OWASP 是一個國際非營利組織,其目標是提高全球軟件安全性。
開始之前的一點網絡安全入門 - 身份驗證和授權
在與其他程序員和 IT 專業人員交談時,我經常會在授權和身份驗證之間的區別上遇到困惑。 當然,縮寫auth經常用於兩者的事實有助於加劇這種常見的混淆。 這種混淆非常普遍,也許這個問題應該作為“常見的 Web 漏洞零”包含在這篇文章中。
因此,在我們繼續之前,讓我們澄清這兩個術語之間的區別:
- 身份驗證:驗證一個人是(或至少看起來是)特定用戶,因為他/她已正確提供了他們的安全憑證(密碼、安全問題的答案、指紋掃描等)。
- 授權:確認特定用戶有權訪問特定資源或被授予執行特定操作的權限。
換句話說,身份驗證是知道實體是誰,而授權是知道給定實體可以做什麼。 考慮到這一點,讓我們進入十大互聯網安全問題。
常見的 Web 安全錯誤 #1:注入漏洞
注入缺陷是由於過濾不可信輸入的經典失敗造成的。 當您將未過濾的數據傳遞到 SQL 服務器(SQL 注入)、瀏覽器(XSS——我們稍後會討論)、LDAP 服務器(LDAP 注入)或其他任何地方時,就會發生這種情況。 這裡的問題是攻擊者可以向這些實體注入命令,從而導致數據丟失並劫持客戶端的瀏覽器。
您的應用程序從不受信任的來源收到的任何內容都必須進行過濾,最好根據白名單進行過濾。 您幾乎不應該使用黑名單,因為要做到這一點非常困難,而且通常很容易繞過。 防病毒軟件產品通常會提供失敗的黑名單示例。 模式匹配不起作用。
預防:好消息是,防止注入“簡單地”是正確過濾您的輸入並考慮輸入是否可以信任的問題。 但壞消息是所有輸入都需要適當過濾,除非它可以毫無疑問地被信任(但這裡確實想到了“永不言敗”的說法)。
例如,在具有 1,000 個輸入的系統中,成功過濾其中的 999 個是不夠的,因為這仍然會留下一個字段,可以作為阿喀琉斯治療來破壞您的系統。 您可能認為將 SQL 查詢結果放入另一個查詢是一個好主意,因為數據庫是受信任的,但如果外圍不是,則輸入間接來自有惡意的人。 如果您有興趣,這稱為二階 SQL 注入。
由於過濾很難做到正確(如加密),我通常建議依靠框架的過濾功能:它們被證明有效並且經過徹底審查。 如果你不使用框架,你真的需要認真思考在你的服務器安全環境中不使用它們是否真的有意義。 99% 的時間不會。
常見的 Web 安全錯誤 #2:身份驗證損壞
這是身份驗證失敗期間可能出現的多個問題的集合,但它們並非都源於相同的根本原因。
假設有人仍然想在 2014 年推出自己的驗證碼(你在想什麼??),我建議不要這樣做。 很難做到正確,並且有無數可能的陷阱,僅舉幾例:
- URL 可能包含會話 ID,並將其在引用標頭中洩漏給其他人。
- 密碼可能在存儲或傳輸過程中未加密。
- 會話 id 可能是可預測的,因此獲得訪問權限是微不足道的。
- 會話固定可能是可能的。
- 會話劫持可能是可能的,超時未正確實現或使用 HTTP(無 SSL 安全性)等......
預防:避免這種網絡安全漏洞的最直接方法是使用框架。 您可能能夠正確地實現這一點,但前者要容易得多。 如果您確實想編寫自己的代碼,請極度偏執並了解陷阱是什麼。 有不少。
常見的 Web 安全錯誤 #3:跨站點腳本 (XSS)
這是一個相當普遍的輸入清理失敗(本質上是常見錯誤 #1 的特例)。 攻擊者在輸入時為您的 Web 應用程序提供 JavaScript 標記。 當這個輸入未經過濾地返回給用戶時,用戶的瀏覽器將執行它。 它可以像製作一個鏈接並說服用戶點擊它一樣簡單,也可以是更險惡的東西。 在頁面加載時,腳本運行,例如,可用於將您的 cookie 發布給攻擊者。
預防:有一個簡單的網絡安全解決方案:不要將 HTML 標記返回給客戶端。 這具有防禦 HTML 注入的額外好處,這是一種類似的攻擊,攻擊者可以注入純 HTML 內容(例如圖像或響亮的不可見 Flash 播放器)——影響不大,但肯定很煩人(“請停止!”)。 通常,解決方法是簡單地轉換所有 HTML 實體,以便將<script>
作為<script>
返回。 . 另一種常用的清理方法是使用正則表達式去除 HTML 標籤,使用<
和>
上的正則表達式,但這很危險,因為許多瀏覽器會很好地解釋嚴重損壞的 HTML。 最好將所有字符轉換為轉義對應的字符。
常見的 Web 安全錯誤 #4:不安全的直接對象引用
這是信任用戶輸入並為由此產生的安全漏洞付出代價的經典案例。 直接對象引用意味著向用戶公開諸如文件或數據庫鍵之類的內部對象。 這樣做的問題是攻擊者可以提供此參考,並且如果未強制執行(或被破壞)授權,攻擊者可以訪問或執行他們應該被排除在外的事情。
例如,代碼有一個download.php
模塊,它讀取並讓用戶下載文件,使用 CGI 參數指定文件名(例如, download.php?file=something.txt
)。 由於錯誤或由於懶惰,開發人員在代碼中省略了授權。 攻擊者現在可以使用它來下載運行 PHP 的用戶可以訪問的任何系統文件,例如應用程序代碼本身或留在服務器上的其他數據,例如備份。 哦哦。
另一個常見的漏洞示例是密碼重置功能,它依賴於用戶輸入來確定我們正在重置誰的密碼。 點擊有效的 URL 後,攻擊者只需修改 URL 中的username
段,即可說出類似“admin”的內容。
順便說一句,這兩個例子都是我自己經常看到的“在野外”出現的東西。
預防:正確一致地執行用戶授權,並將選擇列入白名單。 不過,通常情況下,可以通過在內部存儲數據而不依賴於通過 CGI 參數從客戶端傳遞數據來避免整個問題。 大多數框架中的會話變量都非常適合此目的。
常見的 Web 安全錯誤 #5:安全配置錯誤
根據我的經驗,配置錯誤的 Web 服務器和應用程序比配置正確的 Web 服務器和應用程序更常見。 也許這是因為不乏搞砸的方法。 一些例子:
- 在生產中啟用調試運行應用程序。
- 在服務器上啟用目錄列表,這會洩露有價值的信息。
- 運行過時的軟件(想想 WordPress 插件,舊的 PhpMyAdmin)。
- 在機器上運行不必要的服務。
- 不更改默認密鑰和密碼。 (發生的頻率比你想像的要頻繁!)
- 向攻擊者揭示錯誤處理信息,例如堆棧跟踪。
預防:有一個好的(最好是自動化的)“構建和部署”過程,可以在部署時運行測試。 窮人的安全配置錯誤解決方案是提交後掛鉤,以防止代碼使用默認密碼和/或內置的開發內容退出。
常見的網絡安全錯誤 #6:敏感數據暴露
此網絡安全漏洞與加密和資源保護有關。 敏感數據應始終加密,包括傳輸中和靜止時。 沒有例外。 信用卡信息和用戶密碼不應在未加密的情況下傳播或存儲,並且應始終對密碼進行哈希處理。 顯然,加密/散列算法不能太弱——當有疑問時,網絡安全標準推薦使用 AES(256 位及以上)和 RSA(2048 位及以上)。

不用說,會話 ID 和敏感數據不應該在 URL 中傳輸,敏感 cookie 應該打開安全標誌,這非常重要,不能過分強調。
預防:
傳輸中:使用帶有適當證書和 PFS(完美前向保密)的 HTTPS。 不要通過非 HTTPS 連接接受任何內容。 在 cookie 上有安全標誌。
在存儲中:這更難。 首先,您需要降低曝光率。 如果您不需要敏感數據,請將其粉碎。 您沒有的數據不會被竊取。 永遠不要存儲信用卡信息,因為您可能不想處理與 PCI 兼容的問題。 使用 Stripe 或 Braintree 等支付處理器註冊。 其次,如果您有實際需要的敏感數據,請將其加密存儲並確保所有密碼都經過哈希處理。 對於散列,建議使用 bcrypt。 如果您不使用 bcrypt,請自學鹽漬和彩虹表。
並且冒著明顯的風險,不要將加密密鑰存儲在受保護的數據旁邊。 這就像將您的自行車存放在帶有鑰匙的鎖中。 通過加密保護您的備份,並使您的密鑰非常私密。 當然,不要丟失鑰匙!
常見的網絡安全錯誤 #7:缺少功能級別的訪問控制
這只是授權失敗。 這意味著當在服務器上調用一個函數時,沒有執行適當的授權。 很多時候,開發人員依賴於服務器端生成 UI 的事實,他們認為客戶端無法訪問服務器未提供的功能。 事情並非如此簡單,因為攻擊者總是可以偽造對“隱藏”功能的請求,並且不會因 UI 無法輕鬆訪問此功能而被嚇倒。 想像有一個/admin
面板,如果用戶實際上是管理員,則該按鈕僅出現在 UI 中。 如果缺少授權,沒有什麼可以阻止攻擊者發現此功能並濫用它。
預防:在服務器端,必須始終進行授權。 是的,總是。 任何異常或漏洞都不會導致嚴重的問題。
常見的 Web 安全錯誤 #8:跨站請求偽造 (CSRF)
這是混淆代理攻擊的一個很好的例子,瀏覽器被其他方欺騙以濫用其權限。 例如,第 3 方站點可以使用戶的瀏覽器濫用其權限為攻擊者做某事。
對於 CSRF,第 3 方站點使用您的瀏覽器和您的 cookie/會話向目標站點(例如,您的銀行)發出請求。 例如,如果您在銀行主頁上的一個選項卡上登錄,並且他們很容易受到這種攻擊,那麼另一個選項卡可以使您的瀏覽器代表攻擊者濫用其憑據,從而導致混淆代理問題。 代理是瀏覽器濫用其權限(會話 cookie)來執行攻擊者指示它執行的操作。
考慮這個例子:
攻擊者愛麗絲想通過將他的一些錢轉移給她來減輕目標托德的錢包。 Todd 的銀行容易受到 CSRF 的攻擊。 要匯款,Todd 必須訪問以下 URL:
http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243
打開此 URL 後,將向 Todd 顯示一個成功頁面,並且傳輸完成。 Alice 還知道,Todd 經常訪問她控制的網站 blog.aliceisawesome.com,她在其中放置了以下代碼段:
<img src=http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243 width=0 height=0 />
訪問 Alice 的網站時,Todd 的瀏覽器認為 Alice 鏈接到了一張圖片,並自動發出 HTTP GET 請求來獲取圖片,但這實際上是指示 Todd 的銀行向 Alice 轉賬 1500 美元。
順便說一句,除了演示 CSRF 漏洞之外,這個示例還演示了使用冪等 HTTP GET 請求更改服務器狀態,這本身就是一個嚴重的漏洞。 HTTP GET 請求必須是冪等的(安全的),這意味著它們不能更改訪問的資源。 永遠不要使用冪等方法來更改服務器狀態。
有趣的事實:CSRF 也是人們過去用來填充 cookie 的方法,直到會員變得更聰明為止。
預防:將秘密令牌存儲在第三方站點無法訪問的隱藏表單字段中。 當然,您總是必須驗證這個隱藏字段。 有些網站在修改敏感設置(例如您的密碼提醒電子郵件)時也會詢問您的密碼,儘管我懷疑這是為了防止濫用您放棄的會話(例如在網吧中)。
常見的 Web 安全錯誤 #9:使用具有已知漏洞的組件
標題說明了一切。 我再次將其歸類為更多的維護/部署問題。 在合併新代碼之前,做一些研究,可能是一些審計。 使用從 GitHub 或某個論壇上隨機獲得的代碼可能非常方便,但並非沒有嚴重的網絡安全漏洞風險。
我見過很多例子,例如,網站被擁有(即,外部人員獲得對系統的管理訪問權),不是因為程序員很愚蠢,而是因為第 3 方軟件在生產中多年未打補丁。 例如,WordPress 插件一直在發生這種情況。 如果您認為他們不會找到您隱藏的phpmyadmin
安裝,讓我向您介紹 dirbuster。
這裡的教訓是,軟件開發不會在應用程序部署後結束。 必須有關於如何維護和保持更新的文檔、測試和計劃,尤其是當它包含第 3 方或開源組件時。
預防:
謹慎行事。 除了在使用此類組件時顯然要小心之外,不要成為複制粘貼編碼器。 仔細檢查您將要放入軟件中的代碼,因為它可能會被破壞而無法修復(或者在某些情況下,是故意惡意的——網絡安全攻擊有時會以這種方式在不知不覺中受到邀請)。
保持最新。 確保您使用的是您信任的所有內容的最新版本,併計劃定期更新它們。 至少訂閱有關產品的新安全漏洞的時事通訊。
常見的 Web 安全錯誤 #10:未經驗證的重定向和轉發
這又是一個輸入過濾問題。 假設目標站點有一個將 URL 作為GET
參數的redirect.php
模塊。 操作該參數可以在targetsite.com
上創建一個 URL,該 URL 將瀏覽器重定向到malwareinstall.com
。 當用戶看到該鏈接時,他們將看到用戶認為受信任且可以安全點擊的targetsite.com/blahblahblah
。 他們幾乎不知道這實際上會將它們轉移到惡意軟件放置(或任何其他惡意)頁面上。 或者,攻擊者可能會將瀏覽器重定向到targetsite.com/deleteprofile?confirm=1
。
值得一提的是,將未經過濾的用戶定義輸入填充到 HTTP 標頭中可能會導致標頭注入,這是非常糟糕的。
預防:選項包括:
- 根本不要進行重定向(它們很少需要)。
- 具有要重定向到的有效位置的靜態列表。
- 將用戶定義的參數列入白名單,但這可能很棘手。
結語
我希望我已經設法用這篇文章讓你的大腦有點癢癢,並介紹一種健康的偏執狂和網站安全漏洞意識。
這裡的核心要點是,古老的軟件實踐存在是有原因的,並且在當時適用於緩衝區溢出的做法,今天仍然適用於 Python 中的醃製字符串。 安全協議可幫助您編寫(更多)正確的程序,這是所有程序員都應該追求的。
請負責任地使用這些知識,未經許可請勿測試頁面!
有關更多信息和更具體的服務器端攻擊,請查看:https://www.owasp.org/index.php/Category:Attack。
歡迎和讚賞對這篇文章及其緩解建議的反饋。 計劃在未來發布相關帖子,特別是關於分佈式拒絕服務 (DDoS) 和老式(非 Web)IT 安全漏洞的問題。 如果您對撰寫哪種網絡保護有具體要求,請隨時通過 [email protected] 直接與我聯繫。
這是網站安全! 乾杯。
- JSON Web Token 教程:Laravel 和 AngularJS 中的示例
- 性能和效率:使用 HTTP/3