這是第 24 屆駭客年會 (24C3) 上的一段 session,這一篇只是幫投影片作一些 brief..
前幾天看到一篇文章,裡面有提到在駭客年會上有個議程談論了 Ruby on Rails 的安全問題,我讀了一遍投影片,做出了以下的心得整理:
-
避免別人一下就拆穿你伺服器的架構
(這是我的心得)用 open source 的 framework 是兩面刃,你可以從程式碼中學到一些設計理念,覺得它不夠好的地方行有餘力還可以自行修改,不過,若是這個 framework 有一些漏洞,那有心人士一樣可以參考程式碼來進行攻擊,所以要嘛就勤奮地作 patch,不然就是要學會一點隱匿方法。
投影片中提到,由於 Rails 提供了「漂亮的 URL」,像是
/project/show/12
,/user/new
之類的,一下就讓人家猜出應該是用 Ruby on Rails 開發的,就像過去看到http://xxxxx/yyyyy.do
也會猜測應該就是 Struts。如果你不想在網址上就被人家猜出來是用 RoR 的話,就認真改一下url.conf
吧。再來就是 Rails project 的
public
目錄下有太多的範本,如400.html
或500.html
,如果看到這樣的畫面:很難說這不是 Rails web 吧 XD!
再來就是,很多人的 Rails web 都會用 FastCGI 或是 Mongrel 當作 application server ,一次開很多個 AS,前端再用個 reverse proxy 之類的東西來作 load balance。不過投影片的作者提到,http request 時,server 端的回應會有
Server
的欄位,這時候就會說出你用了mod_fastcgi
還是Mongrel
,甚至連版本資訊都有,比方說我們來試驗一下最近爆紅的 VeryXD:…
Connected to g.veryxd.net.
Escape character is ‘^]’.
GET / HTTP/1.0
Host: g.veryxd.net
HTTP/1.1 200 OK
Date: Fri, 11 Jan 2008 01:00:50 GMT
Server: Mongrel 1.1.3
Status: 200 OK
…所以我們知道了 VeryXD 是用 Mongrel 1.1.3 的版本來架設的。如果要避免被人家知道 Server 資訊的話,可以在 httpd.conf 之類裡去把 Server 欄位給 unset 掉。
再來就是很多人在部署(deploy) Rails web 時,多半會使用 Capistrano 之類的工具,或是自己手動用版本控制工具(如:svn),這樣都會在 server 上留下
.svn/
的目錄,要是有心人士去 access 這些目錄,你的 web 就被看光光啦!所以可以在 .htaccess 或其它存取控制的設定中,把.svn/
這個目錄給 deny 掉。 -
Cookie Session storage
這個部份其實是告訴你,Rails 預設處理 session 的方式沒有很安全,所以重要的資訊千萬不可以放在 session 裡面,也因為大家都可以從 Rails source 中看出 session 是怎麼算出來的,而且 Rails 2.0 預設又是把 session 存在 cookie 裡面,有心的人就可以偽裝 session data 來進行攻擊。
所以,要嘛就在
application.rb
設一個強度較強的 secret_key,不然就是每個一段時間就 invalidate session 資料,再不然就是使用別的方式來處理 session。 -
Cross-Site Scripting(XSS)
這個應該已經是老梗了,不過講者還是提醒大家要記得用
h()
來過濾掉使用者輸入的 HTML code。如果你容易忘掉使用h()
的話,那就為你的 Rails web 安裝一個safe_erb
的 plugin 吧!它會在你沒有把 HTML 內容 escape 掉時丟出 exception。如果你非得讓使用者輸入一些格式化的內容(比方說文字編輯),那就使用
sanitize()
來作黑名單或白名單吧 -
Session Fixation
這裡是要提醒你,當使用者登入或登出時,別忘了使用
reset_session
以避免有不同的使用者用到了相同的 session id。 -
Cross-Site Request Forgery (CSRF)
這個攻擊主要是偽造 request 來進行攻擊,不過從 Rails 2.0 開始增加了
protect_from_forgery
的選項,也就是會針對每個 request 作 auth_token 的檢查,只有依循「正常管道」的 request 才會被接受處理。不過這個防護只保護 POST request,所以你得自己確保 GET request 不會有威脅。(可以用 request.post? 來檢查) -
SQL injection, JavaScript hijacking
都很老梗,不用多介紹了。
-
Mass Assignment
這部份是說,Rails 裡用 ActiveRecord 的 instance 來表示一筆資料庫 record,而對這個 obj 成員變數作 assignment 就相當於去改變這個 record 的值,不過這些成員變數預設都是 public accessible 的,如果裡面有一些重要的欄位,可能會不小心被人家修改到。如:你提供了一個
/user/update
的 action,然後被攻擊者偷帶一些參數試圖修改,這就不太妙了。所以講者希望在使用 AR 時,能利用
attr_protected
來對成員變數的存取控制做一些管理。 - 另外講者還有提到 DoS (Denial of Service) 攻擊的問題,不過這個與 Rails 本身不太有關係,所以留給大家自己去看囉 :p
good suggestion… 😀
Really good! 🙂