Web应用程序安全性:战斗自己或寻找理智的边缘
Web應用程序應有多安全? 好吧,對于我們許多Web開發人員來說,這個問題沒有多大意義。 “應用程序必須盡可能地安全。 它越安全,就越好?!?但這不是一個確定的答案。 形成項目的安全策略無濟于事。 此外,僅遵循該單一指令(“越安全越好”)可能被證明是一種不良服務。 為什么? 這就是我將在本文中討論的內容。
安全性通常會使可用性變差
過多的安全檢查無疑會使應用程序更煩人。 通常,對于應用程序的兩個部分來說,它都是正確的:身份驗證和忘記密碼功能。
除密碼外,多階段身份驗證還包括SMS驗證和其他保護字段,使用戶體驗更加安全,但樂趣更少。 如果您的所有服務都允許與其他用戶交換有趣的圖片,那么用戶當然不會欣賞您嘗試使自己的體驗更加安全的嘗試。
最佳安全做法建議在身份驗證錯誤的情況下顯示盡可能少的信息,以防止入侵者收集用戶列表。 根據此建議,如果用戶經歷了33個驗證階段并在一個字段中輸入了錯誤,則最好的解決方案是顯示一條消息,例如:“對不起,出了點問題。 請再試一遍”。 在這種情況下,用戶不太可能會感受到對開發人員的感激和對他們為使用戶體驗盡可能安全所付出的努力的真誠欽佩。
您必須完全意識到,在這種情況下,用戶體驗會變得更糟,并確定在您的特定情況下這是否可以接受。
安全性使應用程序難以開發和支持
應用程序擁有的防御機制越多,它的復雜性就越高。 創建應用程序某些部分所需的時間可能會增加幾倍,以包括較小的安全性改進。
僅使入侵者的生活更令人沮喪,而不是解決實際的安全問題,就需要花費很多精力。 例如,項目可以選擇在其REST API中混淆方法名稱和參數名稱。
通常,開發人員會花費大量時間來阻止入侵者通過登錄表單,注冊表單和忘記密碼的表單來獲取用戶名列表。
有一些方法,當應用程序將用戶標記為入侵者,但不泄露它。 所有用戶請求都將被忽略。
如果多階段身份驗證過程包含一個秘密問題(對于每個用戶而言都是唯一的),那么我們仍然可以為條目中不存在的用戶名顯示一個問題。 而且,應用程序可以在會話或數據庫中存儲此用戶名和顯示的問題,以始終要求相同的信息。
還有許多其他方法可以使入侵者感到困惑。 但是可以肯定的是,它們都需要時間來實施。 即使編寫得很好并且有注釋,這種邏輯即使對于其作者來說也可能是錯綜復雜的。 但是最重??要的是,它實際上并沒有解決任何安全問題,只是阻止了發現此類問題。
將“精心設計且真正安全的功能”與“具有假想的黑客的狂野游戲”區分開來,并不總是那么容易。 尤其是因為這兩個極端之間的優勢不是絕對的,并且很大程度上取決于您的應用程序對潛在黑客有多大吸引力。
安全性使應用程序更難測試
我們所有的安全邏輯都必須經過測試。 單元測試,集成測試或手動測試–我們應該為我們擁有的每個安全機制選擇一種合適的方法。
我們不能僅僅放棄測試我們的防御邏輯,因為錯誤往往會出現在我們的工作中。 即使我們一開始就能正確編寫所有內容,也總是有機會在維護,支持和重構期間添加錯誤。 沒有人通過編寫遺留代碼來啟動項目。 該代碼隨著時間的流逝而成為傳統。
全面測試所有業務邏輯是不明智的,但是同時假設我們的安全機制是完美,絕對和無錯誤的。
如果將對安全性邏輯進行手動測試,則存在一個問題,即必須多久執行一次。 如果我們的應用程序或多或少復雜,那么可能會有數十個(如果不是數百個)身份驗證失敗的地方。 例如,如果在某些請求中某些ID參數被更改,則服務器將返回我們不可訪問的信息。 檢查每個類似的可能情況都需要大量工作。 我們是否應該在每個主要版本之前檢查它? 我們應該為此任務分配一個人嗎? 還是我們應該為此組成整個團隊?
這些問題很重要。 破碎的身份驗證可以輕松地引入到項目中。 在對模型進行任何微小更改并添加新的REST方法時,我們必須保持警惕。 這個問題沒有簡單通用的答案。 但是有些方法可以在整個項目中始終如一地處理問題。 例如,在CUBA平臺中,我們使用角色和訪問組 。 它們允許配置哪些實體可供哪些用戶訪問。 配置這些規則仍有一些工作,但是規則本身是統一且一致的。
除了身份驗證損壞之外,還應該測試許多安全問題。 在實施新的機制或邏輯時,我們必須考慮如何對其進行測試。 未經測試的事物會隨著時間的流逝而破裂。 而且,我們不僅在安全方面遇到問題,而且對一切都會好起來也抱有一種錯誤的信心。
造成最大麻煩的安全性機制有兩種:僅在產品環境中起作用的機制和代表第二層(第三層,第四層)安全性的機制。
僅在生產中起作用的防御機制。 假設有一個會話令牌cookie,它必須具有“安全”標志。 但是,如果我們在測試環境中到處使用HTTP,則意味著測試和生產有單獨的配置。 因此,我們不完全測試將要發布的產品。 在遷移和各種更改期間,“安全”標志可能會丟失。 而且,我們甚至都不會注意到。 我們如何處理這個問題? 我們是否應該引入另一個可以用作預生產的環境? 如果是這樣,那么應該在此環境中測試我們功能的哪一部分?
多層防御機制。 有安全問題經驗的人傾向于創建一個安全邏輯,只有在關閉其他安全機制后才能對其進行測試。 這實際上是有道理的。 即使入侵者設法在安全屏障的第一層中找到漏洞,他也將被困在第二層。 但是應該如何測試呢? 這種方法的典型示例是為應用程序的不同用戶使用不同的數據庫用戶。 即使我們的REST API包含損壞的身份驗證,黑客也將無法編輯或刪除任何信息,因為db用戶沒有執行這些操作的權限。 但是,顯然,如果維護和測試不當,此類配置往往會過時和破壞。
許多安全機制使我們的應用程序不太安全
我們擁有的防御檢查越多,應用程序就越復雜。 應用程序越復雜,出錯的可能性就越高。 出錯的可能性越高,我們的應用程序的安全性就越差。
再次讓我們考慮一個登錄表單。 使用兩個字段來實現登錄表單非常簡單:用戶名和密碼。 我們需要做的就是檢查系統中是否有用戶使用提供的名稱,以及是否正確輸入了密碼。 嗯,也建議檢查我們的應用程序沒有顯示在哪個字段中犯了錯誤,以防止入侵者獲取用戶名,盡管某些應用程序可以犧牲這種做法來獲得更好的用戶體驗。 無論如何,我們還必須實施某種蠻力防御機制。 當然,那不應該包含故障開放漏洞。 最好不要向入侵者透露我們知道他是入侵者,這也是一個好主意。 我們可以無視他的要求。 讓他認為他正在繼續入侵我們。 要檢查的另一件事是,我們不記錄用戶密碼。 好吧,實際上還有很多不那么重要的事情要考慮。 總而言之,標準的登錄表單是小菜一碟,不是嗎?
多階段身份驗證是完全不同的事情。 可以將某種令牌發送到電子郵件地址或通過SMS發送。 或者可以有幾個步驟,涉及輸入越來越多的信息。 這一切都是相當復雜的。 從理論上講,這種方法應減少用戶帳戶被黑客入侵的可能性。 如果功能實現正確,那么情況就是如此。 仍然有可能被黑客入侵(也不會發送短信,電子郵件,也不會給我們100%的保證),但是通過這種方式,它會減少。 但是已經很復雜的身份驗證邏輯變得更加復雜。 并且犯錯的可能性增加。 而且,與僅是一個具有2個字段的簡單表格相比,單個錯誤的存在將證明我們的新模型不那么安全。
而且,侵入性和不便的安全措施可能迫使用戶以較低的安全性來存儲其敏感數據。 例如,如果在公司網絡中需要每月更改一次密碼,則不了解這種煩人措施的用戶可能會開始將他們的密碼寫在貼紙上并放在屏幕上。 “如果用戶犯下此類愚蠢行為,這完全是用戶的錯”,您可以反對。 也許。 但這絕對也是您的問題。 歸根結底,作為開發人員的最終目標不是滿足用戶需求嗎?
那你在暗示什么?
我建議從一開始就決定我們準備走多遠的路來阻止入侵者。 我們是否準備好優化登錄表單,以使登錄請求的響應時間不會顯示是否存在具有該名稱的用戶? 我們是否準備好實施如此可靠的檢查,以至于甚至坐在受害者手機旁的受害者的密友也無法訪問應用程序? 為了使入侵者的生活更加痛苦,我們是否準備好使開發復雜化數倍,增加預算并犧牲良好的用戶體驗?
我們可以無休止地致力于安全性,建立新的保護層,改善監視和用戶行為分析,阻礙信息的獲取。 但是,我們應該劃清界限,將我們必須做的事情與我們不應做的事情區分開。 當然,在項目發展過程中,可以重新考慮和移動這條線。
在最壞的情況下,項目可能會花費大量資源來構建對一種攻擊的強大防御,而在其他地方卻存在巨大的安全漏洞。
在做出選擇時,如果我們要實現某種安全性機制或要建立另一層安全性,則必須考慮許多事項:
- 利用漏洞有多容易? 破損的身份驗證很容易被利用。 而且它不需要任何認真的技術背景。 因此,該問題很重要,應相應處理。
- 漏洞有多嚴重? 如果入侵者能夠獲取有關其他用戶的敏感信息,或者更糟的是可以對其進行編輯,那么這將是一個非常嚴重的問題。 如果入侵者可以收集我們系統某些產品的ID,而又不能將這些ID用于任何特別有趣的事情,那么問題就不那么嚴重了。
- 如果實現此功能,應用程序將有多少安全性? 如果我們正在談論附加的安全層(例如,檢查輸出中的XSS問題,或者已經實現了一種很好的輸入清理機制),或者我們只是試圖使入侵者的生活更艱難(例如,嘗試掩蓋我們將他標記為黑客的事實),那么這些更改的優先級就不高。 也許它們可能根本沒有實現。
- 需要多少時間?
- 它要花多少錢?
- 用戶體驗會惡化多少?
- 維護和測試功能有多困難? 通常的做法是從不嘗試訪問受限資源時就返回403代碼,而總是返回404代碼。 這將使收集資源標識符變得更加困難。 盡管該解決方案使獲取有關系統的信息更加困難,但同時使測試和生產錯誤分析變得復雜。 而且它甚至可能被證明對用戶體驗有害,因為盡管存在這種資源,但用戶由于某種原因而變得不可訪問,因此用戶可能會收到一個混亂的消息,即沒有這種資源,這對用戶體驗是有害的。
好吧,可以肯定的是,在您的特定情況下,可能需要多階段身份驗證機制。 但是,您必須完全了解它以何種方式阻礙開發并降低用戶對應用程序的興趣。
您正在證明對安全采取疏忽大意的方法
好吧,我不是。 當然會有一些安全敏感的應用程序,這些應用程序將從其他安全措施中受益。 即使這些措施增加了費用并破壞了用戶體驗。
而且,當然,無論多么小,許多漏洞都不會出現在任何應用程序中。 CSRF是此類漏洞的典型示例。 捍衛它不會使用戶體驗惡化,也不會花費很多。 許多服務器端框架(例如Spring MVC)和前端框架(例如Angular)允許開箱即用地支持CSRF令牌。 此外,借助Spring MVC,我們可以快速添加任何必需的安全標頭:Access-Control- *標頭,Content-Security-Policy等。
不允許在我們的應用程序中使用斷開的身份驗證,XSS,SQL注入和其他一些漏洞。 對它們的防御很容易掌握,并且在各種書籍和文章中都有很好的解釋。 我們還可以添加到此列表中,在URL參數內傳遞敏感信息,并存儲弱散列密碼和其他不良安全做法。
最好以最佳方式在項目中包含清單,該清單描述該項目的安全策略并回答以下問題:
- 我們遵循哪些安全規范?
- 我們的密碼政策是什么?
- 我們測試什么以及多久測試一次?
- 等等
對于不同的項目,此宣言將有所不同。 如果程序在OS命令中插入了用戶輸入,則安全策略必須包含有關如何安全執行此操作的說明。 如果項目可以將文件(例如頭像)上載到服務器,則安全策略必須枚舉可能的安全問題以及如何處理它們。
當然,創建和支持這樣的宣言并非易事。 但是,期望團隊中的每個成員(包括質量保證和支持)記住并堅持他必須執行的每個安全實踐,這是一種幼稚的做法。 此外,存在一個問題,對于許多漏洞,有幾種方法可以處理它們。 而且,如果對此事沒有明確的政策,則可能發生在某些地方,開發人員使用一種做法(例如,他們驗證輸入信息),而在其他地方,他們做的事情完全不同(例如,對輸出進行消毒)。 。 即使代碼是好的和純凈的,它仍然是不一致的。 不一致是錯誤,支持問題和錯誤期望的理想之地。
對于具有恒定技術負責人的小命令,代碼審查可能足以避免上述問題,即使沒有宣言。
摘要:
- 在安全性方面,我們應該考慮我們的應用程序如何對安全性敏感。 銀行應用程序和共享有趣故事的應用程序需要不同的方法。
- 在安全性方面,我們應該考慮對用戶體驗的危害。
- 在安全性方面,我們應該考慮它將使代碼復雜化并增加維護難度。
- 安全機制應進行測試。
- 建議教團隊成員如何處理安全問題和/或對項目中的每次提交進行徹底的代碼審查。
- 每個應用程序都必須消除某些漏洞:XSS,XSRF,注入(包括SQL注入),破壞的身份驗證等。
翻譯自: https://www.javacodegeeks.com/2018/07/web-application-security.html
總結
以上是生活随笔為你收集整理的Web应用程序安全性:战斗自己或寻找理智的边缘的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小米米家智能窗帘新品上架:轨道可自由调节
- 下一篇: 华硕推出 VG249QL3A 游戏显示器