about 5 years ago

Essntial Rails Pattern 這本書已經進入排版階段。

各位已經購買的讀者,近期信箱應該會開始一直收到本書的 update。

感謝你們一直以來的耐心等候。

這本書絕對不會讓你們失望。

===

樣章
線上預覽

目錄

線上預覽

如果有任何書籍內容錯誤,和 Billing 上的問題,請透過聯絡表單 通知我,協助我改善產品。

如果你有任何學習 Rails 上的問題,請不要害羞,直接上 Ruby Taiwan Group 詢問。

 
about 5 years ago

第 5 件事:Close Alpha Test、Close Open Test

終於談到跟這個系列標題比較吻合的內容了!最後一個月上線前該做些什麼事?

在 本系列(一) ,我提到了無論如何最後一個月是測試期。這一個月又分成

  • close alpha
  • close beta

Close Alpha 內測 (一週)

close alpha 的對象是開發組以及營運組人員。也就是與核心較為相關的組別。此時針對的測試目標是這個 project 業務上應該被「實作」的 functionalty。比如說是食譜網站,就應該可以

  • 上傳食物照片
  • 新增烹飪步驟
  • 站方精選
  • 有熱門食譜、新進食譜
  • 分享到社群網路 ...etc

如果是討論區,要應該可以

  • 可以發表文章
  • 可以回應文章
  • 可以貼圖
  • 可以收藏
  • 可以搜尋
  • 編輯器運作正常 ...etc.

另外測試時要擬定使用「未登入會員」、「登入會員」、「營運權限」、「Admin 權限」各測過一次。

因為開發組成員在撰寫功能時,為了方便,幾乎都是以 admin 帳號在開發,如果不制定測試步驟和角色,很容易沒測到死角。

此時的修復重點放在 feature complete ( 或取捨 ) 以及 functionaly 是否正常運作。

** 請不要在此時進行任何 UI 動線調整 **。

Close Beta 半公測 (二週+)

close beta 的對象是全公司所有人,公司員工的親朋好友,可以信賴的死忠會員等等...etc. 此時針對的測試目標是這個 project 的 UI 動線。

如果是討論區:

  • 發表的動線是否順暢
  • 是否 UI 的暗示容易讓使用者 miss 掉上傳照片步驟
  • 回應文章的動線是否流暢
  • 網站新訊息的流動是否不夠快速,容易造成網站看起來一片死城。

此時已經是視同準上線了(所以 Close Alpha 階段的資料會清掉),所有營運組的人必須視同營運狀態一樣運營站務,以避免正式開站遇到狀況時手忙腳亂。

(這一招是從參訪壹電視時學到的。當時壹電視快開台時有受邀去內部參訪,當時聽到他們已經內部試 run 報新聞 run 了一年時,震撼非常...XD)

此時的修復重點放在 UI 動線的調整,以及運營方針、步驟的調整,避免開站之後網站就變成死城。

Performance Tuning 與 Website Optimized (一週)

我在開發階段時,最常向 RD 宣導的事情是:我不想管你這個功能怎麼寫出來,但我要你準時交出來。(但最少要符合內部寫程式規範,有辦法讀懂)

原因是:網站最重要的是 Deliver 上線。而不是站上的 feature 用了多屌的技術,用了多棒的 best practices,沒有用戶會在意這件事。而「貪玩」「遲交」會砸了一切。

直到 Open Beta 期,Optimized 這件事都不會被提到。因為在網站稍微 stable 之前,所有的 optimized 都毫無意義,做了也是白作。因為會發生效能瓶頸的地方,永遠在你設計時意想不到的地方。

Backend Performance Tuning

如何作 Performance Tuning?

  • 抓出最慢的地方 Refactor 掉

幸運的是,我的專案都是 Rails Project,有New Relic 這套軟體可以用。它可以幫你找出你的網站哪一段 Ruby Code 特別沒效率,哪一段 code 製造出來的 SQL query 特別 slow。

其他技巧請看:Rapid development with Rails P.54- P.59

這是其他題目了。有空我會再整理 update 一篇 Rails Performance Tuning 的文章。

  • 找出最常造訪的頁面壓力測試

既然已經進入 Open Beta 期了,這時候手上應該可以拿到這個網站最常造訪和效率最差的頁面。

可以使用 ab 去對網站進行壓力測試。

再決定是要 refactor slow code 或者是先上 cache 檔著先。

Frotend Performance Tuning

影響網站使用者感受最大的其實不是 backend 的效率,而是 Browser side 的效率。上線前我會

其他技巧請看:

  1. Rapid development with Rails P.42- P.53
  2. Scaling Rais Site by default
Website Optimized

以上說的都只是 Performance。但是這跟實際運營沒有那麼大的正關係。我擅長開發的是「內容網站」以及「社群網站」,這一類的網站重點其實是 SEO 以及社群穿透力。

  • SEO 以及 Facebook OpenGraph

比如說:這是在 T 客邦累積出來的兩套 gem。

網站的每一個頁面都會確保分享至社群網站是正常的。

  • Advertising

靠廣告賺錢,所以要調整廣告板位

  • RSS / Email Subscribe / 粉絲團活動經營操作

跟 user 的互動...etc.

開站

這些都確認沒什麼問題了,然後才是開站。然而開站不是這一切的結束,還有其他事情需要作...

====

系列文章:

 
about 5 years ago

第 4 件事:架設一套 issue tracking system

你用什麼工具來管理軟體專案的進度呢?我曾經一度認為使用 issue tracking 管理專案進度,是一件天經地義的事。大家都是這麼做的,所以這個題目沒什麼好談的。
後來,我才發現這個印象大錯特錯...

** 絕大多數的人真的只用「mail」和「cc」來管專案,that's all。(註1) **

P.S. issue 真的太多的話,他們會改用 ...Excel!!

ZOMG...

What is issue tracking system ?

Issue Tracking system ,顧名思義就是紀錄追蹤 問題的系統。BugZillaTracRedmineJIRAlighthoustappBasecamp ...等等這幾套軟體,都是知名的 Issue Tracking system。

一套合格的 Issue Tracking system 的 Issue 至少要可以紀錄這些內容:

  • Issue 的主題
  • Issue 的內容
  • Issue 現在的狀態 (新建立、已指派、已解決、已回應、已結束、已擱置...etc)
  • Issue 優先權 (正常、重要、緊急、輕微、會擋路...etc.)
  • Issue 發生日期
  • Issue 希望解決日期
  • Issue 實際解決日期
  • Issue 被分派給誰
  • Issue 的附件
  • Isuue 的觀察者有誰

為什麼 email 不管用?

常人使用的 email 管理法其實會有幾個很大的缺點:

喪失時間感、無確切完成日期

專案中最珍貴的資源無非是「時間」。僅使用 email 往來,會造成一個嚴重的假象:大家都一直有信件往來,所以整件事其實是有進度的。但其實,專案進行的速度卻是牛步...

後面的原因其實是因為:「回信」是一個「順序」執行動作,當一方回了,下一方才能決定要做什麼、要回什麼。「什麼時候」再回(有空回,做完回?)其實沒有人知道。通常一個來回就要搞掉一個上午,甚至是一個整天。但其實整件事沒什麼進展。

這麼浪費效率,逼得某些 PM 還得自己用 TODO list + email tracking label 才可以勉強控制這種局面。

無確切執行人

有的 email,cc 者一大堆:A 先指派了 B 作這個工作,但 B 做到一半覺得需要 C 的火力支援,於是把 C 加入這個討論串裡面。C 做到一半覺得不妥,請示長官 D 要如何配合這個專案。往往一整個 mail 牽扯了一大堆人進去,大家討論來討論去,好不熱烈。

但是呢...誰需要去執行,哪些事需要被執行,什麼時候這些事需要被執行完畢?在這一整個串裡面完全被模糊掉了。

洩密

cc 者一大堆。怎麼分得清楚誰有權知道、誰無權知道這一串信裡面提到的執行事項?

優先權的分配

一個專案可能同時間有幾十上百條待處理事項需要被執行。請問哪一條需要先被執行?它們的優先權又是用什麼標準決定的呢?

處理事項目前的執行狀態

一個較具規模的專案,可能不只一個人參與(多個 RD 和多個美術)。到底誰正在執行什麼項目,會不會相撞(項目、執行者)?什麼項目其實已經完工了,需要被 archive 起來?資訊有沒有 outdate 問題?

Email + Excel 其實很不夠用...

What you need : Project Management Tool

其實由這一連串的問題整理下來,可以清楚的發現,一個專案需要的是什麼?這也是 Project Management Tool 可以提供給你的東西。

與其說 RedmineJIRABasecamp 是 Issue Tracking System,更精確的來說,它們應該被稱為「專案管理工具」。

要能夠的讓專案項目有計畫且順利的被執行,需要:

  • 一個地方可以透明的列出所有需要被執行的項目 (Issue List)
  • 一個地方可以列出階段內需要被執行的項目 ( Issue Milestone )
  • 一個可以記載 內容,狀態、優先權、日期、分派者、觀察者,且具有「permalink」、「權限控管」,且讓大家可以討論執行項目細節的地方。(Issue Ticket)
  • 可以 cross reference 或具有子票功能
  • 一個地方可以整理統合專案現在所有的相關資訊。( Wiki 功能)
  • 一個地方可以看到自己今天需要 Focus 進行哪些項目(Issue Personal Dashboard)
  • 一個地方能讓 Manager 可以看到自己的 Employee 正在進行哪些項目,這些項目目前的狀態是什麼。(Issue Query)

至於我個人一直以來偏好的系統,就是 Redmine。尤其是近一兩年的版本,Issue Query 的加強和 子票 / 相關票的功能被開發出來, 讓我在專案管理上更加的得心應手(註2)。

簡單歸納

專案往往會搞到失火,或是時間不夠用。問題往往出在整個專案之間的「不透明」。

  • 搞不清楚總共有多少事需要完成
  • 搞不清楚目前這件事的進行狀態
  • 搞不清楚今天要進行哪些事
  • 搞不清楚現在正在做的事,是否跟「目前」的全局有強大的正關聯
  • 搞不清楚哪些事必須在何時就需要「確切」的被完成,否則就會產生重大風險

要讓專案順利上線,一套好的 issue tracking system 是不能少的啊。

  • 註 1: 我一直以為裝個 issue tracking system 是常識。為什麼會寫這種「常識」等級的東西?因為我後來發現這完全不是「常識」,特別對 「PM」 來說不是「常識」(顛覆了我的認知...orz)!之前在某社服務時,就發現他們竟然沒有這種東西,提議要部門內架設還被當作是異類。接著所有高階主管討論了超過一個月才勉強決定要裝 issue tracking。接著又花了兩個月的時間討論要裝哪一套 issue tracking,再花了一個月才把決定好的 issue tracking 架起來。真是嘆為觀止!...實在受不了種種的低效率,最後早早 say bye。

  • 註 2: 切票示範 (已取得授權)

====

系列文章:

 
about 5 years ago

第 3 件事:制定 Art / RD 都遵守的開發 convention

在傳統的開發過程中,作法多半都是:規劃 => UI / 畫面設計 => 程式設計。

其實若專案規劃階段結束的早(也就是實作類似最低可行產品產品的概念),並非需要等待 UI / 畫面設計 完工,才可以進行到「套版」(程式設計)的階段。

一直以來,我都認為「套版」是一個非常不好的說法,造成了偏差的印象。因為一個網站實際上是「一整套」的「軟體」,並非是「畫面」設計的出來,程式就配合寫的出來。雙方必須都要是可以執行實作的部分才行。

程式一定要實際的「美術畫面」被設計出來才能夠被接著實作嗎?其實不是這樣的:只要有 wireframe,RD 往往就可以先行動工。

但問題來了:若雙方各自進行自己的部分,那最後要怎麼組起來?

這其實還不是最大的問題。

最大的問題,其實是 Art 切出來的「版」,多半是不能夠被「套」的。

畫面不是切得出來就能「套」

這個問題其實不能夠怪 Art,它們有的是藝術細胞,並非邏輯細胞。而:

  • 能夠熟練 Photoshop,並 不代表 能夠寫出良好結構的 HTML 與 CSS code。

    • 這需要一定的經驗以及技術實力。
  • 能夠切出 HTML 與 CSS,並 不代表 這一份原始碼,可以被實際使用。

    • 有一些 Art 只懂得 PSD to table,整個畫面毫無結構可言,讓人頭痛萬分。
    • 有一些 Art 專精製作單頁的活動頁面,但 application 需要整套的 DOM 能夠重複利用,CSS 一旦被重疊使用時大爆炸。

在傳統的專案進行到「套版」階段,程式開發進度會難以掌控的其中一個原因。也是因為:RD 面對著一套爛 HTML,完全不知從何下手「套」進去。不改結構無法讓程式運作,或者程式運作效率會很低;但一改結構,就別肖想 Art 再幫你調整細部 style 和追加細節了。(東西被改的不爽情緒或原始結構被改變)

「套版」這個過程中無端被追加浪費了大量時間,這也是一個上線前的隱藏變因。

解決方法:製作一套 HTML / CSS 設計準則

多數的 application 有固定結構的 DOM。差異在於 <div id="content"> </div> 內的不同。
至於

  • header
  • sidebar
  • warning
  • form
  • footer
  • etc...

其實多半是相同的。

與其抱怨 Art 切出來的東西不能被套,不如設計一套 general 的實際準則可以被大家遵守學習。

不僅僅是 HTML 設計規則,其實開發當中會花掉很多時間的,還包含一些常見的 CSS hack / IE hack。這些也可以被整理起來,節省開發時間(當然,現在你只要學 compass 就好)。

平行開發互動:解決多人團隊的偏好歧異問題

剛剛有一個問題我們沒有回答到:就是個人偏好如何「組合」?

比如說美術的版裡面有這樣的 DOM <div class="article"> </div>,class 是 article

但是 RD 實際的程式碼卻是 post 這樣的物件名稱。

<% @posts.each do |post| %>
  <%= post.title %>
<% end %>

這樣「套」起來不是很有問題嗎?如何實現所謂我說的「平行開發」?

其實 Art / RD 雙軌平行開發,才可以有效的為專案爭取到時間。

其實之前的所謂「套」,因為有完工的時間壓力,DOM 往往不能夠被更改。但是不改 DOM 又不能讓專案繼續被執行下去。

若是雙方平行開發,又有一個 deployable 的 application 讓進度透明,所有的修改和溝通調整,只是一下子的功夫(article 與 post 的不同,可以在很早期就被抓出來修掉),不但不會打亂開發節奏,反而會加速專案的進行。

====

系列文章:

 
about 5 years ago

第 2 件事:application deployable from day 1

在進入開發階段後,我會做的第一件事: ** make application deployable**

也就是:專案開始第一天,就必須要有個 production 直接可運行(可以鎖密碼,當作測試 server)才行。(我在 Rails 101 這本書最後一章,加入 capistano 與裝機為必練技能,就是這個緣故。)

為什麼專案需要 deployable?

提前控制風險:開發環境與線上環境的不同

在一般的經驗中,往往在在專案進行到尾聲快上線之時,才會注意到一個可能使專案時程大爆炸的事情:** 開發端與線上端的環境通通不一樣 **。

在開發過程中,所有人只專注在自己的機器上能不能動,這是常態。專注在實現功能,東西有缺就先在 local 上塞假資料。在最短時間內將 feature 盡可能寫完絕對是第一要務。

但很可惜的,寫完並 不等於 放到正式環境上可以動。

網站上其實非常多功能需要實際被「真人」測試,才會知道到底有沒有問題。有一些設定,甚至開發環境與上線完完全全不一樣。(以 Rails 來說,其實就差很多。比如說程式 class 會不會被 cache,asset 有沒有 optimize,上傳路徑以及與第三方接軌的設定等等...)

如果拖到最後一個月才作 deploy 的這件事,因為「到底有多少東西不一樣」,變成了一個完全的未知數。原本夠用的一個月測試期,被這樣一壓縮可能完完全全就不夠用了。而且因為專案截止日已進,隨之而來的壓力更加大了犯錯的可能性。

一個透明的已知進度

Day1 就有一個可以直接實際測試的站台,還有一個很大的好處,能夠確保專案中所有人都知道現在進度,與規格書上的東西到底差多少。如果有重大瑕疵,或者是絕對不可行的功能,就可以早早會提出修改,下架等等。節省大家寶貴的開發精力。

如果專案截止日最後十五天,大家才知道很多東西原來根本是作不出來的,或者是跟原本想像差太多的,這時候鐵定陷入交相指責,一遍慌亂的狀況。

絕對注意:捍衛進度

不過這一招的使用,專案經理或者是 RD 主管要特別注意。因為 Day 1 就有一個直接可以看的站台,不少完全不懂「技術」的專案參與者(通常是企劃或老闆),會對網站的「裸站」狀態感到極度的恐慌,他們會挑剔 UI,會不滿 implement 細節,進而想要實際插手進度修改內容。請務必堅持住,堅持到進入最後一個階段:測試修飾期才可以讓他們修改(通常進入準完工階段,裸站狀態其實也消失了,當初挑剔的東西幾乎在這個階段不復存在,故也沒有修改的必要。)

P.S. 可以架設一個 issue tracking system,把他們提出的修改事項先通通記起來,但通通不實作。等到接近測試期,再來看看這些當初的「建議」到底還有哪些實際需要被執行。

只有「完全不合實際應用」的東西,或者是「變更會讓實作方式更合理」的東西可以在整個開發期,被丟入排程中。

否則,他們的驚慌,會害這個專案完全結不了案。

====

系列文章:

 
about 5 years ago

很多人知道如何實作網站功能。但是卻不知道如何將網站成功的完工,並且如期上線。往往明明專案開始之初有不少的工期,有不錯結果的卻很少。上線前後總是一團慌亂。

其實「上線」這件事情完全是可以被掌控的。這當中有不少眉角,只是多半被疏於控制,導致風險橫生。

在回答別人幾次這樣的問題之後,我決定把我的經驗分享整理出來:

第 1 件事:界定時程

這是我認為在專案管理過程中,最重要的一件事。累積參與過幾十個專案下來的經驗之後,我發現上線前手忙腳亂的原因,幾乎都是時程的安排不當。時程混亂冒出的很多風險又沒有被妥善的管理,最後才大失火...

傳統瀑布式專案進行法:寶貴的時間被大量的浪費

一般的專案進行方式,雖然都會有確切的完工期,但專案進行的方式往往會形成相當的浪費而最後造成大量的風險。

比如說一個需要 6 個月工期的案子進度通常是這樣的:

  • 花了 3 - 4 個月無盡的訪談需求
  • 花了 1 個月請美術設計視覺與介面,以及反覆修改
  • 最後剩下不到 1 個月請 RD 寫程式

=> 完全來不及寫完程式 => 半成品上線

上線後一個月:

  • 到處都是 Bug
  • 發包方抱怨
  • 使用者抱怨

上線後第二個月:

  • 終於寫完當初規劃的程式
  • 終於修完大部分的 Bug
  • 使用者早已認定這是個未完工的網站,不再來訪

上限後第三個月:

  • 因為網站規劃不良,使用者對這個網站不感興趣
  • 因為網站規劃不良,預計的成效沒有出來
  • 還有資源 => 繼續籌畫下六個月的改版
  • 已無資源 => 死城

「規劃」從來不是最重要的事

「規劃」其實絕對不是開發一個網站的最重頭項目。「施工」和「調整」才是。

傳統的專案進行方式往往會掉進一個陷阱:六個月看似非常長,於是就大膽的將大部分的時間都丟入「規劃」這個一階段,因為沒有時間壓力,於是會議也通常沒有結論,或者是 feature 發散。等到驚覺時間已大幅燃燒殆盡,再不進行開發絕對完蛋,才匆匆結束。

「規劃」畢竟是個空想產物,等到實際請美術設計頁面,又會發現很多畫面以及 UI 實際上不可能完成。

於是在這一個月,團隊又會大幅的來回修改刪除功能:直到一個勉強接受的範圍,等到視覺完工再轉交給程式設計師「套版」。

在上一個階段,粗估的一個月往往是不夠用的。因為還牽扯到往來的修改時間。而這時交出的產品 scope,也僅只限於「UI」部分有辦法被完成。

「UI」部分有辦法被完成 不等於 「功能」有辦法被完成。有時候畫面上一個小小的按鍵功能,背後的基礎開發工時可能要花上三個月。

最終的上線版本,因為不夠時間了,通常最後只有寫完當初規劃出的功能的 10 - 30% 。而且 Bug 還很多。(因為時間關係,只有辦法完成勉強達到 UI 操作的目的,細部細節根本來不及實作)

最後成效不彰,檢討會議上大家互相指責。但無論如何怎麼檢討來檢討去,完全沒有人會把最根本的問題朝向「規劃時間太長」,只會輕描淡寫的用「必要之惡」一筆代過。

我的方法:從後面倒回來推算時程

我的作法完全相反。如果一個工期是六個月。我會這樣分:

  1. 什麼時候要上線:上線前 1 個月前要 Feature Complete,留足夠的時間進行各樣測試和修復 bug。(剩下 5 個月可以用)
  2. 寫程式要花多久時間:寫程式要花多久時間是不一定的事,但是可以粗估不出包的時間大概是 2 - 3 個月,可以粗抓 2.5 個月。(剩下 2.5 個月)
  3. 視覺設計要花多久時間:畫面設計要花多久的時間也是不一定的事,,但是可以粗估不出包的時間大概是 1 - 2 個月,可以粗抓 1.5 個月。(剩下 1 個月)
  4. 是的。只剩下 1 個月時間可以開會、規劃、畫草圖。請不要浪費時間。

只有 1 個月,是否不夠時間詳細規劃功能?

完全不會。

我會在以後其他的專案管理文章解釋為什麼。

====

系列文章:

 
about 5 years ago

Hi, 各位讀者好。

因為 Apple 一直在改變 XCode 的編譯套件位置,所以 Rails 101 內附的裝機實務已經過期了。

我最近正在籌劃下一次的改版,已經進行的差不多了。將會直接 support 到 Rails 3.2.2。

不過因為裝機實務這個步驟比較會卡到大家,所以我先放這個章節: Rails on Mac 安裝最佳實務 出來給大家使用。

若您在裝機上還碰到什麼問題,請至 Ruby Taiwan Group 上面回報。

 
about 5 years ago

一兩個禮拜之前因為太累,我回家時忘記把 iPhone 4S 從牛仔褲掏出來。洗完澡之後就恍神直接把髒衣服拿去洗衣機直接洗了。

一兩個小時,等我回神過來之後,要幫手機充電,才發現手機已經躺在洗衣機裡面被洗得亮晶晶了。這還不夠,手機還是在開機狀態進去洗的,跟一般只是掉到馬桶進水的狀況不一樣。

Anyway,朋友建議我拿去 忠孝新生站 3 號出口的 麥克愛愛 碰運氣修看看。傳說中這是一間服務非常棒的水果商,他們也「兼修」iPhone 這樣....

賭賭運拿去麥克愛愛修幾天後,幾天店員回電說檢修後發現主機版、螢幕和無線網路模組都炸光光了。維修費用應該會是 ㊙(遠低於我的預算,反正在一萬以內),不過他想他還是可以幫我修看看。

今天被通知修好了,所以就過去拿了。除了香噴噴(咦?)亮晶晶以外(開玩笑,我都用熊寶貝幫他洗澡了...),手機也跟新的一樣活跳跳的回到我手上了。

感謝 麥克愛愛 幫我修好手機,所以特此寫這一篇文章推薦他們。如果你有蘋果電腦或者是 iPhone 手機的問題,歡迎找他們。服務真的相當專業到位。

電話與聯絡方式在 麥克愛愛的臉書專頁 有,出發之前請先電話預約洽詢。

 
about 5 years ago

關於 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 欄位直接結合,節省不少開發者撰寫表單的時間,是一個很聰明的作法。

<%= 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 裡。

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 傳進來的值,只開放你想讓使用填寫的欄位。

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

 
about 5 years ago

我創業了。從 2012/03/01 開始,我跟我的好友:國內頂尖的視覺設計師 @evenwu 合組了一間新公司 RocoDev

我們專營:

  • Ruby on Rails Web Application 設計
  • HTML5 / Responsive Design 視覺與網頁設計
  • 網站體質優化 ( SEO / HTML5 semantic / Alexa ranking)

有興趣的朋友可以歡迎找我們洽談服務。

至於我創業的原因,寫在這裡:「我為什麼想創業」。

這也是我另外的一個小部落格,我對於人生的感觸和一些沒有那麼硬的短文會放在這裡。