從 Github 被 hack,談 Rails 的安全性( mass-assignment )

标签: github hack rails | 发表时间:2012-03-05 10:51 | 作者:
出处:http://blog.xdite.net/

關於 Github 被入侵這件事,目前在國外開發圈傳的沸沸揚揚。看來中文圈還沒有消息,我來報導一下到底發生了什麼事好了。順便宣導一下開發 Rails 程式碼需要注意的其中一個觀念..

到底發生了什麼事

Rails 的 master 被某個 hacker 塞上這一段 commit。以證明 Github 是可以被入侵的。

為什麼會發生這件事(糾紛起源)

有個俄羅斯 Hacker : homakov 到 Rails 的 Github issue 頁,report 了一個 issue

聲稱他發現很多「中等程度以下的」Rails 開發者開發任何網站,都沒有在 model 內作上任何 attr_accessible 的防護,這樣會引起很多安全性的問題。

Rails 官方應該設計一個機制強迫大家一定得「使用」 attr_accessible

因為寫 code 要塞 attr_accessible 被多數開發者認為是根本是一個「常識」。所以這個 issue 很快就被 Rails core team 關掉了。他的意見是這不是 Rails 的問題,而是開發者的問題。(正常人都會做出這樣的反應)

這個 Hacker 覺得他好心來報告,但是卻被忽視,感到很生氣。

於是!他 Hack 了 Github 證明這件事情是真的。

他不僅利用這個漏洞在 rails/rails 中塞了 commit ,連當初被關掉的 issue ,也用同樣方法打開了。

所以這下就鬧到舉世震驚了!…XDDDDD

為什麼會發生這件事(剖析 Rails )

從 Rails 表單機制談起

Rails 秉持著 Don’t Repeat Yourself 的精神,將 Form 表單 Helper 直接與 Model 欄位直接結合,節省不少開發者撰寫表單的時間,是一個很聰明的作法。

1
2
3
4
5
      <%= form_for @post do |f| %>
  <%= f.text_field :title %>
  <%= f.text_area :content %>
  <%= f.sumbit "Submit" %>
<% end %>

當表單送出後,會被壓縮成一個 params[:post] 這樣的 Hash。controller 裡面透過 massive-assignment 的技巧直接 mapping 進 Model 裡。

1
2
3
4
5
6
7
8
9
10
      class PostController < ApplicationController
  def create
     @post = current_user.posts.build(params[:post])
     if @post.save
       # do something
     else
       # do another thing
     end
  end
end

這是一個自 Rails 誕生以來就有的機制了,十分便手。

有些不了解的 Rails 的其他 Developer 批評這是一個不安全設計,並因此拒絕使用 Rails。欄位暴露在外被人知道,讓他們感到非常不自在。

萬一被人猜到 user 權限是用 user.is_admin 作為 boolean 值,這樣豈不是很危險嗎?在修改個人資訊頁時,假造 DOM 就不是可以把自己提升為 admin 了嗎?

Rails 內建的安全防禦措施

Rails 也不是沒有針對這件事設計出防禦措施,有兩組 model API : attr_accessibleattr_protected。其實也就是 白名單、黑名單設計。

attr_accessible 加在 model 裡,可以擋掉所有 massive assignement 傳進來的值,只開放你想讓使用填寫的欄位。

1
2
3
      class Post < ActiveRecord::Base
  attr_accessible :title, :content
end

attr_protected 是完全相反地機制。

知名認證 Plugin 皆內建 attr_accessible

也因為 user.is_admin 幾乎是所有懶惰開發者會寫出來的 code。因此長久的歷史演變下來,許多知名認證 plugin,如 devise ,restful-authentication 等等…,在 User model 裡都會加上 attr_accessible(你可能沒有察覺到,因為可能是透過 include Module 塞進來的功能)。

因為是隱藏的內建防禦,很多不夠經驗的開發者,反而會被這道自動防禦整到,在設計修改使用者資訊這個功能時,常常表單明明沒問題,但就是修改不了除了密碼和 email 以外的欄位 XDDD

User model 自動防禦,那其他 model 呢?

好問題!這就是這次 Github 發生的問題。嚴格來說,根本不是 rails/rails 的錯, 而是 Github 內某個被罵 mid/junior level 的 developer 的錯。他根本沒有對其他 model 作上保護,才被 hacker 有機可趁。

Hacker 也是想要證明連 Github 都會犯這種錯,才會鬧出這種事件

看到 Github 的事件,我該做什麼?

請回家讀這兩組 model API : attr_accessibleattr_protected 的作用。

並檢查你的 project 內是否有類似問題:一般來說,容易被攻擊的點都跟 relation 比較有關係。也就是 xxxxx_id 的部分都要清查。

Scoped Mass Assignment

這是 Rails 3.1 加入的新 feature : scoped mass assignment, http://enlightsolutions.com/articles/whats-new-in-edge-scoped-mass-assignment-in-rails-3-1

我也建議你閱讀。

Rails core team 目前的解法

大師 Yahuda Katz (wycats) 目前起草了一份新的 proposal,並且丟在 Hacker News 讓鄉民討論。應該可能近期就會近 Rails core 或以 plugin 的方式釋出。

我個人的感想

其實昨晚睡前看到一堆人說 Github 被 Hacked 掉,然後追了幾篇討論串之後,覺得真的是沒什麼,因為就我來說,的確應該就是這個 hacker 覺得有必要提醒大家,但這對多數的 Rails Developer 來說,根本是超小的小事,不值得這麼大驚小怪。

結果憤怒的 Hacker 攻擊了 Github,Github 真的還因為某個 developer 犯了低級錯誤中招。但我還是覺得沒什麼…

XSS V.S. Massive Assignment

後來睡醒以後才發現不對,其實這東西應該要被拿來跟 auto escape 相比:XSS 是一般設計 Web Application 最容易中招的攻擊。

XSS 的原因肇因是讓開發者開放讓使用者自行輸入內容,然後無保護的讀出來,Hacker 會利用這種漏洞,寫進有害的 JavaScript 讓使用者中招。正確的方式應該是:內容讀出來之後,都要利用 html_escape 濾掉。

問題是,html_escape 濾不勝濾,沒有開發者能夠那麼神,寫任何一段 code 都會自律的加上 h(content)。最後 Rails core 痛定思痛,在 Rails 3.0 後效法 Django 的設計,在讀出 content 時,一律先 escape。除非有必要,才另行設定不需 escape。

我想這次的 massive assignment 問題應該也要比照辦理才對…

延伸閱讀:

國外鄉民懶人包: GitHub and Rails: You have let us all down.

DHH 給出的 37Signals 的作法: https://gist.github.com/1975644

相关 [github hack rails] 推荐:

從 Github 被 hack,談 Rails 的安全性( mass-assignment )

- - Blog.XDite.net
關於 Github 被入侵這件事,目前在國外開發圈傳的沸沸揚揚. 看來中文圈還沒有消息,我來報導一下到底發生了什麼事好了. 順便宣導一下開發 Rails 程式碼需要注意的其中一個觀念... Rails 的 master 被某個 hacker 塞上這一段 commit. 以證明 Github 是可以被入侵的.

安装rails(ruby on rails)

- - BlogJava_首页
  记得两年前使用ror做网站,自动生成功能记忆犹新,只是当时网络知识实在缺乏,体会不到其中的乐趣. 现在了解的很多了,书也有两本,一直想重新体验最新版做个网站. 安装这个过程实在有点坑爹,查找网上若干ror的书包括2012年版的书,按照上面的步骤都没法安装完成,搞得我一会在linux下试验,一会在windows下试验,都没成功,只好放下.

Ruby On Rails 4 hello world,Ruby On Rails上手

- - CSDN博客Web前端推荐文章
有机会再试一试Rails了,只是原来接触的是2,现在已然变成了4,似乎现在的安装比原来会快些. 似乎这就是当前的最新版本. 似乎这就是诸如Django、Rails这类对于轻量级网站的数据库要求. 其他可以看情况安装,如openSUSE. 可以直接用rails生成. 这样的话打开  http://localhost:3000 就可以看到,Rails的欢迎界面Welcome aboard,有点类似于Django-CMS的小马哥~~.

CSS的Hack大搜集

- - CSDN博客Web前端推荐文章
  Hack在CSS的编写中是经常被用到的一种技术. 之所以出现了Hack,是因为各个浏览器的解析有专属于自己的写法的. 不过,Hack虽然是如此的好用,作为前端写代码的我们来说,用它绝对是快准狠的解决了问题,但是不太推荐大家用Hack.   Hack的技术是针对不同浏览器写不同的样式,让浏览器达到不同的渲染效果.

淺談 Rails 3.1 Asset Pipeline

- gnepud - Blog.XDite.net
前幾天,我新開了一個網站 Upgrade2Rails31. 專門放置我更新 Rails 3.1 的一些實戰心得文章. 在社群交流聚會中,我常發現人們對於 Rails 3.1 的 Asset Pipeline,還有它引進的一些新穎機制不是很瞭解. Asset Pipeline 是什麼. Asset Pipeline 對於提昇網站速度,架構上有什麼貢獻?.

为什么 Facebook 发明新语言“Hack”

- - 开源中国社区最新新闻
为什么Facebook发明新语言“Hack”.  (注:Hack是一种PHP的派生语言). 为了替换掉那些有年头的老代码,Facebook创建了一个新的语言. 这个故事来自Facebook工程师Julien Verlaguet和Ed Smith的一次访谈. 2004年2月,扎克伯格(Mark Zuckerberg)的哈佛同学们第一次登陆Facebook,服务器里运行着PHP.

iOS客户端hack的两种姿势

- - WooYun知识库
分析某商城漏洞,在漏洞验证时采用了两种iOS上的hack工具:cycript和reveal,各有风情,均能攻城拔寨,实乃我辈日常居家、杀人越货之利刃,现与诸君共享之. 该商城的iOS版app为用户提供了找回密码的功能,用户需通过三个步骤找回密码:. 输入一个本地的图形辨识验证码(多余. 提供用户手机号,输入一个短信验证码.

Powerful 的 Rails 速成後台 : RailsAdmin

- babaru - Blog.XDite.net
前幾個禮拜幫自己的書刻官網,那時候已經有點精神不濟了,實在相當懶得自己手刻 CRUD 後台 以及實作 Authentication. 當下就決定使用硬幹法…(雖然我手刻一個 CRUD 不需要 5 分鐘,但是那天真的累了). 基本上在網站上面看到的 view 和 route 都是我徒手硬寫的,沒有任何 model …..

Groupon收购Ruby on Rails开发公司Obtiva

- bill - cnBeta.COM
据国外媒体报道,团购网站Groupon当地时间周四宣布该公司已经收购了Ruby on Rails开发公司Obtiva. Ruby on Rails是一种可以使用户开发、部署和维护web应用程序变得更为简单的框架. Groupon发表博文称,Obtiva是芝加哥地区最大的Ruby on Rails开发公司.

推荐一些 Ruby on Rails 学习资料

- dylan - Reincarnation
开始之前应该看看 Ruby 官方网站 上的 About Ruby、Ruby in Twenty Minutes 和 Ruby From Other Languages 得到初步的印象和感性认识. 在页面底部可以选择语言查看中文版. 经验比较丰富的开发者可以通过 Ruby User’s Guide [注1] 快速入门 Ruby,之后应该准备一本 The Ruby Programming Language 作为日常参考.