Ruby 程式語言的安全性原則,主要聚焦於 Ruby on Rails Web 框架。
跨站請求偽造(CSRF)
預設情況下,Rails包括一個指令碼,它包含了一個名為X-CSRF-Token的標頭,其安全代碼(Token)對應於每個非GET Ajax呼叫。
當使用另一個函式庫進行Ajax呼叫時,有必要將安全代碼(Token)加入為函式庫中Ajax呼叫的預設標頭。
可於HTML中查看代碼(Token),應為<%=csrf_meta_tags%>對應的<meta name='csrf-token'content='THE-TOKEN'>標籤。
弱密碼簽名
Ruby gem具有適當的簽名機制,但不是必需的,且缺乏對簽名金鑰的信任鏈。
函式庫
參考資料
避免將用戶輸入與呼叫合併
Ruby on Rails支持許多呼叫,這些呼叫可能包含一些潛在漏洞。
- Eval("程式範圍")
- Instance_eval()
- Class_eval()
- Kernel.exec("OS範圍")
- System("os範圍")
- Popen
- open("os範圍")
- DRb.start_server()
- ls -al
(引號執行系統命令)
- Find_by_sql()
- %X()
- send()
- send()
- public_send()
- try()
- render()
修正方式
避免使用未經過濾的用戶輸入形成系統或Ruby命令。
如果需要用戶輸入來通知該命令,則可以做一些過濾來最大程度地減少暴露。
在將用戶輸入傳遞給命令執行功能之前,將用戶輸入與白名單進行比較是驗證輸入的有效方法。
為了使用用戶輸入執行系統命令,可 使用Terrapin將參數傳遞給run()方法的內容進行轉義。
風險等級
高
參考資料
使用正確的正則表達式(REGEX)字符串符號的開始和結束
Ruby使用與許多其他語言略有不同的方法來匹配字符串的結尾和開頭。
當使用REGEX驗證用戶輸入時,濫用這些符號可能會導致繞過通過REGEX驗證獲得惡意輸入的可能性。
`^`和`$`:匹配每行的開頭和結尾,而不是字符串的開頭和結尾。
`\A`和`\z`:用以代替"^"和" $"。
``
問題範例
排除無效的URL。
#正則表達式
/^https?:\/\/[^\n]+$/i
```
修正方式
排除無效的URL。
正則表達式
\Ahttps?:\/\/[^\n]+\z/i
``
風險等級
高
參考資料
確保動態內容已編碼
預設情況下,資料的輸出應進行編碼來防止跨站點指令碼(XSS)。
Ruby on Rails中卻有幾種方法可以讓開發人員繞過預設的XSS保護。
XSS可用於執行經過身份驗證的用戶有權存取的任何操作,包括透過同一身份驗證提供程式處理身份驗證的其他服務。
在這裡,@user.website值可以以javascript:標記開頭,執行其後的所有JavaScript。
%=raw @product.name%>
%=@product.name.html_safe%>
%=content_tag @product.name%>
%=link_to"網址",@user.website%>
``
修正方式
這些方法僅應用於信任非用戶提供的不包含用戶輸入內容的內容。
風險等級
高
參考資料
- https://www.owasp.org/index.php/Ruby_on_Rails_Cheatsheet#Cross-site_Scripting_.28XSS.29
大量賦值的利用
批量賦值功能在較舊的版本中可能會成為問題,因為它允許攻擊者通過操縱傳遞給模型的new()方法的雜湊來設置任何模型的屬性。
為避免這種情況,應在全域範圍內使用"Strong Parameters"在所有模型中強制將屬性列入白名單。
"Strong Parameters"要求您每次檢索參數時都必需指定和允許的參數。
從安全角度來看,與資料儲存區的交互通常是Web應用程式中最敏感的區域之一。
確保用戶不能利用這些交互來提升特權或獲得對資料的未經賦值的存取對於整體應用程式安全至關重要。
預設啟用:Strong Parameters
onfig.active_record.whitelist_attributes = true
``
角色存取的白名單:
``
attr_accessible:name
attr_accessible:name,:is_admin,:as =>:admin
``
問題範例
如果您使用批量賦值建立新使用者,並依靠用戶記錄來管理存取權限,則有可能成為管理員:
批量賦值建立新使用者:
def signup
params[:user]
@user = User.new(params [:user])
end
```
加強HTTPS和嚴格的傳輸安全性
AppSec建議所有Web應用程式在用作Session管理時都強制執行傳輸加密(HTTPS)並利用嚴格傳輸安全性來保護Session cookie。
嚴格的傳輸安全性告訴瀏覽器僅通過加密的通道存取Web應用程式。
用戶與Web伺服器之間的流量的強加密在保護用戶的身份驗證Session以及與伺服器交換的資料方面起著關鍵作用。
onfig.force_ssl = true
``
防止記錄敏感訊息
預設情況下,Rails記錄對Web應用程式發出的所有請求。
但是日誌文件可能是一個巨大的安全問題,因為它們可能包含登錄憑證,信用卡卡號等。
記錄敏感的用戶訊息會使該資料受到威脅的風險更高。這也是GDPR問題。
修正方式
在設計Rail應用程式時,請確保指定不應記錄的請求參數。
這些應該附加到Rails配置中的過濾參數列表中:
onfig.filter_parameters <<:cc_number
``
風險等級
中
參考資料
避免禁用deep_munge
由於Active Record解釋參數的方式與Rack解析查詢參數的方式相結合,因此可以使用IS NULL where子句發出意外的資料庫查詢。
為了解決該安全問題,引入了deep_munge()方法作為預設情況下保持Rails安全的解決方案。
啟用此參數可避免遭受SQL注入攻擊的風險。
修正方式
請啟用deep_munge()。
風險等級
中
參考
將Rails主金鑰儲存在環境變量
Rails將儲存一個主要金鑰,該金鑰生成到版本控制中被忽略的config/master.key文件中。
但是,Rails還將在ENV["RAILS_MASTER_KEY"]中尋找該鍵值。
保護機密的一部分是使它們脫離版本控制。
AppSec建議使用Infrastructure Engineering的Vault實例進行機密管理。
另外,從環境變量中儲存和檢索秘密是更好的選擇。
修正方式
建議從config/master.key文件中刪除金鑰,並將其放置在生產環境中的RAILS_MASTER_KEY環境變量中。
風險等級
低
參考資料
不允許用戶輸入確定要渲染的網頁
Rails的render()方法通過提供要渲染的模板名稱來實現動態渲染。
如果Rails應用程式包含僅限於某些用戶角色的網頁,則這可能使攻擊者能夠規避那些存取控制並以較低特權用戶身份存取受限制的網頁。
修正方式
避免在某些頁面受到限制時使用用戶輸入來選擇要渲染的頁面。
風險等級
低
Session固定攻擊
Session固定攻擊是用於將預先認證Session代碼(Token)用作認證後Session代碼(Token)的術語。
換句話說,認證後未設置新的Session代碼(Token)。
如果正在使用基於標頭的身份驗證,這不是問題。
一旦知道了瀏覽器中當前Session代碼(Token)的設置,攻擊者就可以劫持用戶登錄的經過身份驗證的Session。
修正方式
用戶成功通過身份驗證後,請使用reset_session()函數在其瀏覽器中設置新的Session cookie。
風險等級
低
參考資料