據說現在一臺pc(Windows系統)上網的時候,如果沒有任何防毒軟體防火牆,那麼十分鐘之內就會被淪陷為病毒之城。為什麼會如此呢?因為你上網的時候,可能有的網站會被植入病毒,植入***什麼的,網站的使用者只要一登陸,如果沒有任何防護措施,那麼你的機器肯定會馬上被攻陷了。當然了,網站也不是故意要掛病毒和***給使用者的,主要是有些站點在開發之初或上線之後都沒有考慮過web安全的問題,以致於存在很多安全隱患,導致被惡意的Hacker所控制,從而發生上述一幕。那麼該如何防範呢?

     廣告之後更精彩:
            趨勢科技, 讓Hacker病毒們,去死!

     第一,對於普通使用者來說,可以下載一些著名的安全軟體來使用,比如趨勢科技的WTP, 網站管理員也可以使用趨勢的防毒牆。但是我覺得,要解決根本,還是從站點開發之初來防範這些漏洞。 當然,漏洞也是變化的,上線以後還是部署個趨勢的防毒牆更保險。
=。=

身為一名Rails開發者,就說一下web安全十大漏洞和rails開發中該如何防範這些漏洞。

A1 – Cross Site Scripting (XSS)
這是***者利用在網站裡嵌入javascript來進行獲取受害人的cookie資訊。
     Rails2.0對XSS***的防範也得到增強,TextHelper#sanitize由黑名單改為了白名單實現。具體***方法在這裡:[url]http://www.rorsecurity.info/2007/05/01/cross-[/url] site-scripting-user-agent-injection-attack-methods/
   有助於我們檢測自己的專案。
   rails策略:
       1.在view里加入h方法,safeERB外掛的作用ms不是為了幫助我們免除這一步。
       2.用whitelist,剛才所說的rails2。0開啟了這個方法TextHelper#sanitize.
       3.在使用BlueCloth和RedCloth的時候,應該聯合WhiteList來用,避免引發安全問題。
      4。在Rails1.2.3版本之前,不要使用to_json方法,小心殆害!

A2 – Injection Flaws

注入***有很多種,SQL,LDAP,XPath,XSTL,HTML,XML,OS COMMAND等等,但主要是SQL隱碼攻擊比較突出,我們這裡只關注SQL隱碼攻擊的解決方法。

Don`t use Project.find(:all, :conditions => “name = `#{params[:name]}`”)
           Do use Project.find(:all, :conditions => [“name = ?”, params[:name]])
           sql注入是指***者從客戶端手動輸入引數,使引數傳到資料庫伺服器,混入到sql查詢語句裡把一些資訊返回到客戶端,即瀏覽器顯示。
         Project.find(:all, :conditions => “name = `” + params[:name] + “`”)
        Project.find(:all, :conditions => “name = `#{params[:name]}`”)
         比如這兩個例子,將會受到sql注入的***:
         ***者只要輸入:` or 1 -, 這個時候rails生成的sql語句就變成了:
     select * from projects  where name = “ or 1 –`
     因為在mysql裡的boolean值是1,這個 – 符號(# 和 /*也是註釋)是sql的註釋,後面所有的一切都會被忽略,所以我們這個sql句相當於
      select * from projects
 利用sql 注入如何繞過許可權驗證:
   User.find(:first, “login = `#{params[:name]}` AND password =  `#{params[:password]}`”)

     params[:name] = ` OR `1`=`1
     params[:password] = ` OR `2`>`1
     params[:name] = ` OR login LIKE `%a%
     params[:password] = ` OR ISNULL(1/0) #
   Unauthorized Reading
   參見:[url]http://www.rorsecurity.info/2007/05/19/sql-injection/[/url]

   rails的解決辦法就是:
   1。用佔位符號
      User.find(:first, :conditions => [“login = ? AND password = ?”, params[:name],
params[:password]])
  2。用hash(rails版本是在1.2以上)
     User.find(:first, :conditions => {:login => params[:name],
:password => params[:password]})
   3。在保證上述兩點的基礎上,把查詢方法放在model裡。這樣會更加安全。
   4. 所有rails根據model屬性自己生成的find_by_xxx方法是很安全的,比如:
      find_by_name, 等。
  5. find_by_sql 也是很安全的。

A3 – Malicious File Execution
這個安全隱患在Rails1.1.6就已經解決了,1.1.6以下的專案需要打個補丁,但是rails2.0出來了,還是升級吧
相關:
Working with files
這是關於檔案上傳的安全策略:
[url]http://www.rorsecurity.info/2007/03/27/working-with-files-in-rails/[/url]
參見:Agile 開發之道2nd,610頁。

A4 – Insecure Direct Object Reference
在rails裡,只要注意不要把內部的controller方法暴露出來,即,不要把private方法誤寫到publice方法裡就行,對一些action和controller做一個全域性的異常處理,就不會被***者把你應用程式***的腸子都流出來了。

A5 – Cross Site Request Forgery (CSRF)

傳說中的跨站偽裝請求***(通常也叫one click attack”或者session riding,通常縮寫為CSRF或者XSRF)
聽起來有點像css/xss跨站指令碼***有點類似,但實質不同,CSRF比起css/xss來更加危險,因為這種***難以防範(主要是因為不大流行,所以防範資源比較缺乏)。XSS利用站點內的信任使用者,而CSRF則通過偽裝來自受信任使用者的請求來利用受信任的網站。網網這兩種***方法是買一送一的關係。利用XSS偽裝受信任使用者,利用這個受信任使用者來進行CSRF***來利用網站。

例子:一個網站使用者Bob可能正在瀏覽聊天論壇,而同時另一 個使用者Alice也在此論壇中,並且後剛剛釋出了一個具有Bob銀行連結的圖片訊息。設想一下,Alice編寫了一個在Bob的銀行站點上進行取款的form提交的連結,並將此連結作為圖片tag。如果Bob的銀行在cookie中儲存他的授權資訊,並且此cookie沒有過期,那麼當Bob的瀏覽器嘗試裝載圖片時將提交這個取款form和他的cookie,這樣在沒經Bob同意的情況下便授權了這次事務。

   CSRF是一種依賴web瀏覽器的、被混淆過的代理人***(deputy attack)。在上面銀行示例中的代理人是Bob的web瀏覽器,它被混淆後誤將Bob的授權直接交給了Alice使用。
下面是CSRF的常見特性:
依靠使用者標識危害網站
利用網站對使用者標識的信任
欺騙使用者的瀏覽器傳送HTTP請求給目標站點

  CSRF***依賴下面的假定:
***者瞭解受害者所在的站點
***者的目標站點具有持久化授權cookie或者受害者具有當前會話cookie
目標站點沒有對使用者在網站行為的第二授權
       防範措施
在form中包含祕密資訊、使用者指定的代號作為cookie之外的驗證。那些導致對安全產生”副作用”的請求應該總使用Post方式傳送。Post方式不會在web伺服器和代理伺服器日誌中留下資料尾巴,然而Get方式卻會留下資料尾巴

   Rails的策略:

      1。慎用get請求,也就是上面所說的, 那些導致對安全產生”副作用”的請求應該總使用Post方式傳送。
      2。Use the Csrf_killer plugin to include a security token in forms.(外掛方式過期,但是使用rails2.0y一下版本的專案需要注意)
      在Rails2.0中,通過在form中增加特殊欄位來防止CRSF***,這一功能在新應用中預設是開啟的。

A6 – Information Leakage and Improper Error Handling
一些重要的資訊洩露一般是通過程式裡的異常資訊透露給***者的,如果異常資訊太詳細,那麼就很危險了,所以和上面一條一樣,要進行異常處理。全域性的異常處理。
def rescue_action_in_public(exception)
case exception.class.name
when `ActiveRecord::RecordNotFound`,`::ActionController::UnknownAction`,`::ActionController::RoutingError`
RAILS_DEFAULT_LOGGER.error(“404 displayed”)
render(:file => “#{RAILS_ROOT}/public/404.html”, :status => “404 Error”)
else
RAILS_DEFAULT_LOGGER.error(“500 displayed”)
render(:file => “#{RAILS_ROOT}/public/500.html”, :status => “500 Error”)
end
end

A7 – Broken Authentication and Session Management

1.session hijacking(session劫持).

      session劫持,是被非法使用者拿到整個session資訊(cookie).然後讓你的所有資訊暴露。
     
      how: 是通過網路監聽來獲取。有些sniffer軟體,等等。。。
      Countermeasures:
       對策1: Encrypt the traffic using SSL
             雖然ssl比較慢,但是還是很安全的,需要在environment.rb中加入:
             ActionController::Base.session_options[:session_secure] = true
      對策2 : Include additional information (user agent, IP address, …) in the cookie
              我們在session里加上一些額外的資訊,在每一次請求都去驗證它。
      對策3 : Create a new session when someone successfully logs in.
              用reset_session,但是你不得不把老的session裡的資料copy過來。比如user_id.
      對策4 : 在使用者登出以後讓session無效。設定session過期時間。

    2.Session fixation(Session定製***)

         how:***者通過得到使用者合法的session id,並強迫瀏覽器使用這個session_id 來進行***。在php裡,session管理器接受任何的session id,即便這個id不存在,但是ruby on rails裡是不可能的,ruby on rails只接受已經生成的session id,所以***者會訪問這個rails站點來獲取合法的session id,然後傳遞給第三方使用者,如果使用這個session id可以登入成功,那麼其他的session id也一樣不安全。
在得到session id之後,就會用html 標籤<META>來對瀏覽器注入session id強迫瀏覽器使用這個session id來登入站點。
<meta http-equiv=Set-Cookie content=”_session_id=4cf69dc5fee46251bdc1f99ef55f52b6″>
這是危險的!

    對策:
           目前最好的對策是: 用reset_session,也就是上面所說的.

   3.設定cookie過期時間( Expiration of cookies )
        1).Client side  客戶端可以指定一個固定的時間。e.g :
            ActionController::Base.session_options[:session_expires] = Time.local(2007,”jan”)
            但是記住使用者可以改變這個過期時間
        2). Server side
            Remove old sessions  from your hard disk or database  Rails預設不會清除session,我們來自己指定。
           class SessionCleaner
        def self.remove_stale_sessions
          CGI::Session::ActiveRecordStore::Session.
          destroy_all( [`updated_on <?`, 20.minutes.ago] )
        end
     end
     And then invoke the remove_stale_sessions method every 10 minutes via;
     */10 * * * * ruby /full/path/to/script/runner
     -e production “SessionCleaner.remove_stale_sessions”

        這是防止***者是通過寫一個指令碼來使用被劫持的session持續***。但是我們需要另一個session 儲存器,像外掛SQLSessionStore ,或者an update of the ActiveRecordStore migration so it has a created_at field.

      3) 動態設定session過期時間。這裡有個外掛:
       [url]http://blog.codahale.com/2006/04/08/dynamic-session-expiration-times-with-rails/[/url]
      rails2。0裡可能不適用了,我們可以參照這個外掛來應用到rails2。0裡。

A8 – Insecure Cryptographic Storage

      1.用一個good password .參見:[url]http://www.rorsecurity.info/2007/06/05/use-good-passwords/[/url]
      2.Filter passwords from the log file:
         filter_parameter_logging “password”
         可以參考railscasts第9集.
      3.  清除mysql或bash history可能包含password的地方:
         cat /dev/null > ~/.mysql_history and ~/.bash_history
      4. 永遠不要以明文儲存密碼。
         Signup
         self.salt = Digest::SHA1.hexdigest(“–#{Time.now.to_s}–#{login}–”)
         self.crypted_password = Digest::SHA1.hexdigest(“–#{salt}–#{password}–”)
        Login
        self.crypted_password == Digest::SHA1.hexdigest(“–#{self.salt}– #{user_entered_password}–”)

A9 – Insecure Communications
不 安全通訊,解決這個問題需要用SSL來保護一些敏感的資料。IE 7.0 provides a green bar for high trust SSL certificates,but this is not a suitable control to prove safe use of cryptography alone.  所以企業裡用IE一般是不安全的。在安全這方面,我們可以說服企業使用者去用firefox
1。採用SSL保護敏感資料。
2。確保這些基礎設施之間的通訊,比如資料庫和web servers之間的通訊,是建立在一個安全的傳輸層或是一個有高度加密的信用協議的基礎上。
3。必須遵循PCI 安全標準。比如你需要保護信用卡持有者的資訊。

具體,這些敏感的資料是不能儲存到資料庫的。要儲存也需要經過加密以後儲存。
Ruby開啟ssl
http = Net::HTTP.new(PANEL,PORT)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

請參考PCI安全標準。

A10 – Failure to Restrict URL Access
一般來說加上異常處理,許可權設定就很安全了.
  許可權外掛使用的安全考證

    目前有好多許可權外掛,比如LoginGenerator和      Restful_authentication
     但是我們使用前最好考證一下這些外掛的安全性,可以去參考這個站點:
     [url]http://www.rorsecurity.info/[/url]
具體待補充。

A11-  其他安全隱患及解決辦法:

Validation

一般放到model裡,有時候需要放到controller的話,可能你需要一個外掛:ActiveForm plugin

Regular Expressions
參見
[url]http://www.rorsecurity.info/2007/04/16/ruby-regular-expression-fun/[/url]

Securing your MySQL setup
Web application security depends on the security of all layers. Start securing your MySQL setup here, then go on here.
here: [url]http://www.rorsecurity.info/2007/02/25/securing-mysql/[/url]
go on here:[url]http://www.rorsecurity.info/2007/02/27/rails%e2%80%99-friends-securing-mysql-continued/[/url]

The mass-assignment problem
When @user = User.new(params[:user]) may become a problem. Read it here:
[url]http://manuals.rubyonrails.com/read/chapter/47[/url]

   ***可以在網路中通過多種方式***、***使用者的終端,其中最常見,也是使用者最容易重招的也正是通過Web站點的間接***,作為網路管理員,能夠保護企業內網中使用者的上網安全是職責所在,我們可以通過安全閘道器、防病毒牆等產品對網路中資料的通訊進行統一管理,也可以結合在終端安裝像上網無憂電子眼這種工具來進行防護的方式來實現終端的安全。上網無憂電子眼是趨勢科技推出的免費Web威脅防禦工具,通過特有的Web信譽服務與殭屍防禦功能,能夠有效的抵禦來自網路的侵襲,使企業使用者能夠對自身的終端做到合理的防護,從而杜絕殭屍程式、廣播病毒等威脅的擴散傳播,有效的營造了安全的企業網路環境。

參考:
  [url]http://www.tutorialized.com/view/tutorial/Ruby-on-Rails-Security-cheatsheet/29267[/url]
  [url]http://www.rorsecurity.info/2007/04/15/session-fixation-in-rails/[/url]
  [url]http://weblog.rubyonrails.org/2007/9/30/rails-2-0-0-preview-release[/url]
  [url]http://www.quarkruby.com/2007/9/20/ruby-on-rails-security-guide[/url]
  [url]http://www.owasp.org/index.php/Top_10_2007[/url]