Ruby の脆弱性を見つけた話

こんにちは、技術部の遠藤(@mametter)です。フルタイム Ruby コミッタとして、クックパッドにあたらしく入社しました。よろしくお願いします。

最近、Ruby や RubyGems の脆弱性を発見して、その結果セキュリティリリースにつながるということを経験しました。どういう動機でどのように脆弱性を発見したか、どのように通報したか、などについてまとめてみます。Ruby の脆弱性を見つけたけどどうしよう、という人の参考になれば幸いです。

HackerOne について

HackerOne という脆弱性情報の通報と公開のためのプラットフォームをご存知でしょうか。

OSS にとって脆弱性情報の管理は面倒なものです。脆弱性の通報を秘密裏に受け付け、関係者だけで議論しなければなりません。そのため、通常のバグトラッカとは別のコミュニケーションチャンネルを用意する必要があります。

そこで HackerOne が使えます。HackerOne は簡単に言えば、脆弱性情報の管理に特化した非公開のバグトラッカサービスです。登録されたOSSプロジェクトに対して誰でも脆弱性情報を通報できます。また、プロジェクトメンバ間や報告者の間で非公開の議論もできます。問題が解決された際には議論の内容が公開されます。

さらに、Internet Bug Bounty (IBB) program がインターネットを維持するために特に重要なソフトウェアと指定している一部のプロジェクトについては、通報されたバグが開発者によって脆弱性と認定された場合、IBB から報告者に報奨金が支払われます。

ただ、報奨金が出るのは良し悪しです。良い通報をしてくれた人が報われるのは当然良いことなのですが、報奨金目当ての雑な指摘がたくさん来るという副作用があります。完全に見当違いな例を上げると、「SVN が公開状態だぞ!」とか、「バグトラッカの issue 一覧が丸見えだぞ!」とか 1 。もちろん有益な通報も来るのですが、通報を受ける側としては、もうちょっとノイズが減るといいなあ、と思っています。

そこで、 Ruby ユーザの方々に HackerOne を紹介したいと思い、そのために一回、私自身が通報者としてのプロセスを経験してみました。

ターゲットの選定

自分が一番慣れている OSS プロジェクトは Ruby なので、Ruby のソースコードから脆弱性を探すことにしました 2 。Ruby に標準添付されたライブラリの中で、「脆弱性といえば WEBrick」。という直観にもとづき、そのへんをターゲットにしました。

探す脆弱性の選定

「Ruby の脆弱性」に明確な定義はありません。ある Rails アプリに任意コード実行(外部から攻撃コードを送り込んで実行させられる)があれば、どこかに脆弱性があることは確かですが、Ruby の脆弱性かもしれないし、Rails(またはサードパーティ)の脆弱性かもしれないし、はたまたユーザの書いたプログラムの脆弱性かもしれません。極端な例では、system("ls " + user_input) みたいなプログラムがあると OS コマンドインジェクションができますが、これを Ruby の system のせいだと言われても困ります。Ruby 本体かユーザプログラムかの切り分けは、わりと揉めやすいところです。

今回はここで揉めないよう、言い逃れしにくい脆弱性を探すことにしました。それは、そのプロジェクト自身が過去に脆弱性と認めたバグに近いバグを見つけることです。

WEBrick の過去の脆弱性を探したら、『WEBrick にエスケープシーケンス挿入の脆弱性』が見つかりました。要するに、ログにエスケープシーケンスを紛れ込ませることができたら脆弱性のようです。個人的には「このくらいで脆弱性なんだ」という驚きがありますが、一部のターミナルエミュレータはエスケープシーケンスで危うい挙動を起こせることがあるそうです。詳しくはリンク先を読んで下さい。

脆弱性の発見

実際に脆弱性を探します。過去の脆弱性の修正コミットを手がかりに WEBrick のログ出力まわりを読解すると、WEBrick::AccessLog.escape というメソッドでエスケープシーケンスを除去(サニタイズ)し、WEBrick::BasicLog#error#warn などのメソッドで実際にログを書き出すらしいことがわかります。ここで、AccessLog.escapeWEBrick::HTTPStatus::Status#initialize の中でしか呼ばれていないことに気づきました。つまり、この例外経由でしかサニタイズがされないらしいということです。

そこで、#error#warn を直接呼び出すところを探したところ、WEBrick::HTTPAuth::BasicAuth#initialize に見つかりました。不正なユーザ ID で BASIC 認証すると、そのユーザ ID がサニタイズなしでログに流れ出るようです。

(あっさり見つけたように書いてますが、実際にはいろいろ探したり試行錯誤したりしながらだったので 2 晩くらいはかかったと思います)

脆弱性の確認

この脆弱性が実際に exploit 可能であることを確かめます。WEBrick の BASIC 認証のコードを Web 検索しながら書きます。

require "webrick"
require "webrick/httpauth"

srv = WEBrick::HTTPServer.new({ Port: 34567 })
db = WEBrick::HTTPAuth::Htpasswd.new("dot.htpasswd")
authenticator = WEBrick::HTTPAuth::BasicAuth.new(UserDB: db, Realm: "realm")
srv.mount_proc("/") do |req, res|
  authenticator.authenticate(req, res)
    res.body = "foobar"
  end
srv.start

↓サーバを起動した様子 f:id:ku-ma-me:20171004180721p:plain

このサーバに対して、エスケープシーケンスを混入した不正なユーザ ID でログインを試みます。ここでは、"\e]2;BOOM!\a" というエスケープシーケンスで実験しました。これは、端末のタイトルを BOOM! という文字列に変える命令です。

require "open-uri"

open("http://localhost:34567/login",
  http_basic_authentication: [
  "ESCAPE SEQUENCE HERE->\e]2;BOOM!\a<-SEE WINDOW TITLE",
  "passwd"
]).read

↓クライアントを起動する様子 f:id:ku-ma-me:20171004180728p:plain

この結果、WEBrick サーバを動かしている端末のタイトルが、BOOM! に変わることが確認できました。

↓攻撃成功した様子(タイトルバーが "BOOM!" になっているところがポイント) f:id:ku-ma-me:20171004180738p:plain

脆弱性の報告

めでたく(?)脆弱性を確認できたので、HackerOne に投稿します。Weakness や Severity は該当すると思うものを選ぶだけですが、よくわからなかったら空欄でもよさそうです。重要なのは Proof of Concept です。といっても、普通のバグ報告と同じです。どういう問題であるかと、再現手順をきっちり書けば十分でしょう。問題の重大さを書くとさらに親切です。今回の脆弱性は過去の脆弱性の修正漏れなので重大さに議論の余地はないと考え、ほとんど再現手順だけを簡単に書きました

あとは普通のバグ報告と同じ対応です。よほど致命的な問題でない限り(あるいは致命的な問題であっても)、開発者はなかなか返事をしてくれないものです。パッチを書いて送ったり、ときどき催促したりしながら、気長に待ちます。今回は、4 月に報告して、セキュリティリリースは 9 月でした。

セキュリティリリース

普通の報告者ならここで終わりですが、今回は私が Ruby コミッタでもあるということで、セキュリティリリースに少しだけ参加しました。といっても私がやったのは、ブランチマネージャや公式サイト管理人たち(@unak さん、@nagachika さん、@hsbt さん)の指示の下、私が書いたパッチをコミットしただけです。あとは彼らが一生懸命 tar ball を作ってリリースするのを応援していました。

コミットしてからリリースアナウンスを出すまでの時間を最小化するため、リアルタイムのコミュニケーションを取りながら進める必要があります。Ruby のブランチマネージャたちは、セキュリティリリースのたびに命を燃やして頑張っています。敬礼。

報奨金の獲得

無事セキュリティリリースがなされたということで、IBB から報奨金として $500 をいただきました。このプロセスも簡単に説明しておきます。

まず、初めて報奨金をもらう場合、税務上の書類 W-8BEN を作成して提出します 3 。すべてオンラインの手続きなので難しいことはありませんでした。

それから支払いの受取方法を登録します。PayPal 、Bitcoin via Coinbase 、銀行間振替がサポートされていました。私は銀行間振替を選んだので、口座情報を入力するだけでした。4

RubyGems の脆弱性

同じようなプロセスで、RubyGems にも通報をしました。

詳細は割愛しますが、CVE-2015-3900 という過去の脆弱性が適切に修正されていないというものでした。ただ、こちらはすでに他の人が通報済みだったので、Duplicate でクローズされました。

ただ、コードを読んでいるうちに次の 3 つの問題を新規発見しました。こちらの方の通報は認められたようです。

これらの通報に対する修正は、RubyGems 2.6.13 としてリリースされています。特に 3 つめの問題は、WEBrick の問題よりもう少し重大だと思うので、バージョンアップすることをおすすめします。なお、Ruby 2.4.2 は RubyGems 2.6.13 の修正を含んでいるので、Ruby 2.4.2 にするのでも大丈夫です。

まとめと所感

Ruby の脆弱性を探して HackerOne に通報した事例を紹介しました。

セキュリティ報告をすると、多くの場合、公式サイトでクレジットに載せてもらえるので、承認欲求が満たされますし、HackerOne ならちょっとした報奨金までもらえます 5

最初に触れたとおり、今のところ HackerOne 経由で Ruby にくる通報は、雑な通報が多くて Ruby 開発者的にはノイズが多いと感じられています。この記事を見た人が、(Ruby に限らず)有意義な通報を増やしてくれるといいなと思います。

最後になりましたが、クックパッドでは脆弱性のない Rails アプリを作れる Web アプリケーションエンジニアを募集しています。詳しくは募集要項ページをご覧ください。


  1. Ruby はオープンソースプロジェクトなので、もちろん意図的に公開しています。

  2. IBB の FAQ によると、プロジェクトの開発者自身でも、(1) そのプロジェクトで収入を得ていないこと、(2) 問題のコミットに関わった人間でないこと、の条件を満たせば報奨金がもらえます。私はフルタイムコミッタになったので、もう無資格のようですが、今回の通報は入社前にやりました。

  3. 米国非居住者が米国の人から支払いを受け取るときに、源泉徴収の金額を低減してもらうための書類。

  4. 正確には、海外からの送金を受け取るために、銀行にマイナンバーの登録をする手続きもありました。

  5. エスケープシーケンスインジェクションでは大した金額にはなりませんでしたが、もっと重大な脆弱性ならそれなりに高額になるはずです。たとえば有名な Shellshock だと $20,000 も支払われたそうです。

料理の追体験を実現する「タイムライン」のデザイン

こんにちは、サービス開発部のデザイナー若月(id:puzzeljp)です。

すでにご利用していただいている方もいらっしゃると思いますが、iOS / Android アプリにタイムラインという機能が登場しました。

f:id:puzzeljp:20170929172254p:plain

先日そのタイムラインのデザインについての登壇しました。 (イベントレポートはこちら)
今回はその時話しきれなかったこと、タイムラインの開発時のデザインの工夫や苦労についてご紹介します。

タイムラインとは

フォローしているユーザーさんやすべてのユーザーさんの新しいレシピ投稿やつくれぽが見られるようになりました。 レシピ検索では出会えなかった料理に出会うことができ、実際にレシピが見られるので料理をすることができます。

どんな使い方があるかと言うと例えば「Aさんがパエリアを作っている!私作ったことないけど、Aさんが作っているなら私でも作れそう。作ってみよ!」のような料理の追体験ができるようになります。

f:id:puzzeljp:20170929172351p:plain

新しい見え方

タイムラインを開くと、「レシピのカード」と「つくれぽのカード」があります。検索結果と比べて料理の写真を大きく見やすく表示しています。ユーザーさんのアイコンや名前がカードに表示されているので、誰がどんな料理をしているかわかるようになりました。

f:id:puzzeljp:20170929172408p:plain

登壇資料

当日の登壇資料については、以下で見ることができます。

デザインアプローチ〜工夫と苦労〜

つくれぽカードのデザイン

タイムラインでは、「つくれぽのカード」で料理の追体験ができるような様々な工夫をしています。

工夫した点

つくれぽとレシピ投稿を比較すると、つくれぽは気軽に投稿できます。そのため、タイムラインを見ると「つくれぽのカード」の方が多く存在します。もう1つに、つくれぽは作った直後に送るため、今日何の料理を作ったこともわかるようになります。 そのため、レシピ投稿と違い「誰のレシピを作ったのか」「何のレシピを作ったのか」が必要となります。

「誰のレシピを作ったのか」「何のレシピを作ったのか」がタイムライン上でより伝わる物は何かをWebプロトタイピングで検証をしました。Webプロトタイピングのメリットして、以下があげられます。

  1. 実データを利用できること
  2. アプリよりもより高速に検証できること
  3. デザインプロトタイピングよりも正確に検証できること

実際に検討したレイアウトについてご説明します。

A案
作者名やレシピ名を同じ文章として扱いました。文字の大きさは同じですが、色はそれぞれ分けています。1文として見えるので文章としては見やすくしました。
B案
A案と似ていますが、レシピ名を目立たせるために、作者名を小さくすることでバランスを取りました。1文というのは同じですが、文章内で優先度がつきました。

f:id:puzzeljp:20170929172428p:plain

他にもレイアウトを考えましたが、最終的には以下のレイアウトになりました。
理由としては、タイムラインでカードが並んでいる場所に、文章があっても読まないのでは?という仮説がありました。それを解決するために、写真の上に「誰のレシピなのか」、写真の中に「何のレシピなのか」というレイアウトにしました。このレイアウトにしたことにより、適度な文章量と写真も目立つように、カードの高さも少なくなりました。

f:id:puzzeljp:20170929172450p:plain

苦労した点

今回のWebプロトタイピングは、メリットを活かした検証ができました。 問題点として、細かいデザインはアプリと異なるため、実際のアプリに実装してみたらイメージと異なったことやWebプロトタイピングも実装の時間がかかり、アプリの実装にも時間がかかってしまうことでしたが、デザインのプロトタイピングよりは検証は正確にできる点はやはりメリットだと感じました。

誰が作ったがわかる機能

フォローユーザーさんが既につくれぽを送ったレシピに対して、自分自身がつくれぽを送ると、送ったつくれぽが、フォローユーザーさんの「つくれぽのカード」に表示されるようになります。他のフォローユーザーさん同士でも同じレシピにつくれぽを送っていても「つくれぽのカード」に表示されます。

工夫した点

表示される内容は、「誰が作ったかわかる見出し」、それぞれのアイコン・名前とつくれぽの写真です。 例えば見出しには、「○○さんと△△さん他n人が作りました」や「○○さんがn回リピートしています」等と表示され、「誰が作っているか」「誰が何回作っているのか」「自分自身が何回作ってるか」がわかるような文言を20パターンほど用意しています。パターンが多いことで、より正確に「誰が作っているか」「誰が何回作っているのか」「自分自身が何回作ってるか」がわかるようになりました。

f:id:puzzeljp:20170929172510p:plain

苦労した点

見出しの部分が一番苦労しました。まず起こりうる組み合わせを考え、その後実際に表示される文言を考えましたが、「カード投稿者が他人の場合は他人をテキスト内に含めない」や「テキストがカード投稿者が自分の場合と異なる」などのカードの見た目は共通しているものの表示される文言が違うと複雑になってしまいました。 複雑になってしまったことで、テストケースを回した時に、その起こりうる組み合わせを出すことが難しく、専用のアカウントを作成し、ログインし確認を行う作業を20回以上しました。
もし次回こういった文言を考える時には、ユーザーさんに最低限伝わる文章を考えようと思いました。ユーザーさんにわかりやすいものをと思いましたが、開発が遅くなってしまいユーザーさんに届くのが遅くなってしまうよりも早くリリースを行い、検証をしたほうが良いためです。

まとめ

タイムラインは、時間をかけて開発を行ってきました。新しい機能のため、実装に時間がかかるのはもちろんですが、デザイン的にも様々な工夫を行ったためです。 そんなにデザインを工夫する必要があるの?…といった部分があるかもしれませんが、「タイムラインを見て料理がしたくなる」「タイムラインを見ていて、料理をしたくなったらレシピを見たら料理ができる。」そんな体験が自然とできるようにと開発を行いました。
タイムラインがリリースされたことによって、みんながどんな料理をしていることがわかるようになりました。 気になった作者さんをフォローをすると、よりタイムラインが楽しく、料理がしたくなるようになると思います。ぜひタイムラインを使ってみてください!

Cookpad Ruby Hack Challenge 開催報告

f:id:koichi-sasada:20170929111101j:plain

技術部の笹田です。Ruby インタプリタの開発をしています。先日、RubyKaigi 2017 のために、広島に行ってきました(その話はまた別途)。

本記事では、2017/08/30, 31 に弊社で開催した Cookpad Ruby Hack Challenge (RHC) の模様についてご紹介します。

短いまとめ:

RHC の概要

Cookpad Ruby Hack Challenge は、Ruby インタプリタ(MRI: Matz Ruby Interpreter)に対して機能を追加したり、性能向上させたりする方法、つまり Ruby インタプリタを Hack する方法を、二日間かけてお伝えするイベントでした。細かい中身の話はせずに、最低限必要となる手順を一通り体験してもらう一日目と、自由にハックを行う二日目にわけて行いました。

イベント申し込みページ にて6月末から7月末まで募集をしたところ、10人の定員に100名近くのご応募を頂きました。急遽、定員を5名追加し、15名定員としました。加えて、記事を執筆いただくために池澤あやかさんにご参加いただき、また弊社から4名の希望者が(サポート要員をかねて)参加しました。当日欠席は1名のみで、19名+私、という体制で行いました。

参加者とのコミュニケーションは Gitter を用いました。https://gitter.im/rubyhackchallenge/Lobby という場所で連絡を行ったり、質問を受け付けたりしました。また、Ruby コミッタの集まる場所を https://gitter.im/ruby/ruby にも作り、Ruby の質問ができる状態にしましたが、遠慮したためか、参加者からの質問は、あまりありませんでした。

イベントの流れ

初日は基礎編、二日目は応用編という流れでした。

一日目は基本的に座学で、資料に沿って進めて頂きました。 解散が 17:00 と早いのは、私が保育園へお迎えに行かなければならないからでした。

二日目に、好きなテーマに挑戦してもらいました。また、その間にサブイベントとして、「まつもとゆきひろ氏 特別講演」「Ruby開発者との Q&A」を行いました。これらを開催するために、毎月行っているRuby開発者会議 を、裏番組として同時開催してもらいました。

8/30 (水) 一日目

  • 10:00 オープニング
  • 10:30 ハックに必要となる事前知識の講義
  • 12:00 ランチ
  • 13:00 共通課題
  • 16:00 発展課題の紹介と割り振り
  • 17:00 解散

8/31 (木) 二日目

  • 10:00 発展課題の開始
  • 11:30 まつもとゆきひろ氏 特別講演
  • 12:00 Ruby開発者を交えてのランチ
  • 13:00 Ruby開発者との Q&A セッション
  • 14:00 発展課題の再開
  • 18:30 打ち上げパーティー

一日目 基礎編

f:id:koichi-sasada:20170929111031j:plain

https://github.com/ko1/rubyhackchallenge にある資料をもとに、説明を聞いてもらい、演習を行ってもらう、というように進めました。

資料をざっとご紹介します。

  • (1) MRI 開発文化の紹介
    • MRI の開発は、誰がどのように行っているのか、大雑把に説明しています。
    • バグ報告の仕方など、一般的な知識も含んでいます。
  • (2). MRI ソースコードの構造
    • MRI のソースコードの構造を紹介し、演習として、MRI をビルドしてもらいました。
    • 演習といっても、実際に行う手順は書いてあるため、その通りに手を動かしてもらう、というものになっています。ここで扱った演習一覧を抜き出します。
      • 演習: MRI のソースコードを clone
      • 演習: MRI のビルド、およびインストール
      • 演習:ビルドした Ruby でプログラムを実行してみよう
      • 演習:バージョン表記の修正(改造)
  • (3) 演習:メソッドの追加
    • 実際に、MRI に機能を追加していきます。
    • 次のようなメソッドを、演習として追加してもらいました(手順はすべて記述してあります)。
      • Array#second
      • String#palindrome?
      • Integer#add(n)
      • Time#day_before(n=1)
    • また、拡張ライブラリの作り方や、デバッグに関する Tips を補足しています。
  • (4) バグの修正
    • バグの修正方法と、バグの報告の方法について紹介しています。
    • 次の二つのケースについて、具体的な話を紹介しています。バグ発見の技術的な方法に加え、心構えみたいなことも書いているので、そこそこ実践的な内容だと思いますが、どうでしょうか。
      • 他の人のバグ報告を見る場合(Kernel#hello(name) という架空のメソッドを例に)
      • バグを自分で発見してしまった場合(Integer#add(n) という架空のメソッドを例に)
  • (5) 性能向上
    • 性能向上についての諸々の話を書いています。
    • このあたりは、最後の方に書いたので、だいぶ雑になっています。演習もありません。

読むだけで進められるように書いたつもりなので、興味がある方は、読んで実際に手を動かしてみてください(読んでもわからない、という場合は、どの辺がわかりづらいか、こっそり教えてください)。

二日目 応用編

発展課題 として、いくつか課題の例をあげておきましたが、これに限らず好きなことに取り組んで頂きました。ただ、こちらにリストした内容を選んだ人が多かった印象です。取り組んで頂いたテーマは、GitHub の issue でまとめてもらいました https://github.com/ko1/rubyhackchallenge/issues

いくつかご紹介します。

Hash#find_as_hash の実装

Hash#find の返値が配列なので、Hash を返す版が欲しい、という新規メソッド開発の挑戦です。が、1要素の Hash を返しても使いづらい、ということに気づいたそうで、nice try! ということで、終わりました。

フレームスタックの可視化

VM の状態を可視化するために、各フレームの状態を JSON で出力する仕組みを作り、そしてそれを表示するビューア https://github.com/kenju/vm_stackexplorer を作ってくださいました。懇親会でデモまで行ってくださいました。一日でここまでできるとは。

help に --dump オプションを追加

ruby -h で出てくるメッセージに不足があったので、足しましょう、という提案です。この挑戦を行ったのは Ruby コミッタの sonots さんで、さすが手堅い、実際に困ったんだろうな、という提案です。

なお、参加者に Ruby コミッタの sonots さんも混ざっているのは、サポート役としてお願いしたためです。後で伺ったら、曖昧にしていたことが多く、得るものは多かったということです。

Procに関数合成を実装

Proc#compose という、二つの Proc を合成する、いわゆる関数合成を行うためのメソッドを提案されました。一度試したことがあったそうで、C で書き直し、似たような提案のチケットにコメントとして追記してくださいました。コミッタを交えたパーティーでは、この仕様についていろいろと議論が盛り上がりました。

ビルドしたRubyでのGemのテスト

開発中の Ruby で、任意の gem のもつテストを行うことができる、という仕組みの提案です。私がほしーなー、と言っていたら、作ってくださいました。

最近の Ruby には bundled gem という仕組みで、いくつかの Gem をインストール時に同時にインストールする仕組みがあるのですが、それらの Gem のテストを簡単に行う方法がありませんでした。また、人気の Gem(例えば、Active Support とか)も、同様に試すには、一度インストールして、bundle して、... といくつかの手順を必要としていました。この提案では、これらのテストを、Ruby をインストールせずに make コマンド一発でできるようになります。MRI 開発者が(人気の)Gem を動かせなくなるような変更を入れる前に気づくことができるように(多分)なります。

サブイベント

二日目の途中に、Ruby 開発者会議で来ている Ruby コミッタに頼んで、下記のイベントを行いました。

まつもとさんゆきひろさんによる特別講演

f:id:koichi-sasada:20170929111037j:plain

大雑把に「30分でいい話をしてください」と依頼したら、いい話をしてくださいました。話の詳細は、池澤さんのレポート記事( Rubyのなかを覗いてみよう!「Cookpad Ruby Hack Challenge」に参加してみた )をご参照ください。

昼時だったので、発表を行ってもらった場所に隣接するキッチンで、社員の昼食を作っていました。料理しているところで発表するのは、多数の発表経験のあるまつもとさんでもさすがに初めての経験だったとのこと。

Ruby開発者との Q&A

f:id:koichi-sasada:20170929111044j:plain

Ruby 開発者を並べて、参加者および弊社社員を含めた質疑応答大会を行いました。RubyKaigi での企画 Ruby Committers vs the World の前哨戦でした。

パーティー

f:id:koichi-sasada:20170929111051j:plain

最後に、開発を終えた参加者の皆さんと、開発者会議を終えた Ruby コミッタが合流し、パーティーを行いました。

パーティーでは、二日目に行った挑戦を発表してもらいました。その場で、まつもとさんをはじめ Ruby 開発者と本気のディスカッションが発生していました。

まとめ

本記事では、2017/08/30, 31 に弊社で開催した Cookpad Ruby Hack Challenge (RHC) の模様についてご紹介しました。

参加者の皆様へのアンケートからは、良かったという感想を多く頂きました。 ただし、いくつか反省する点があり、次回以降で改善していきたいと思っています。

今回は(多分)成功したので、今後も続けて行ければと思っています。 初回だったので、まつもとさんに特別講演をお願いするなど、だいぶ力を入れてしまいました。 次回以降は、もうちょっと力を抜いていこうと思います。

参加したかったけど、定員オーバーで参加出来なかった方、そして、今回知って、興味を持たれた方、次回以降にぜひご期待ください。 調整次第ですが、出張して行うことも可能かと思います。 また、Ruby 以外にも広げられるといいですね。夢(だけ)は広がります。

本イベント開催にあたり、Ruby コミッタや、多くの弊社社員に助けて頂きました。 この場を借りて、御礼申し上げます。

最後にご案内です。フォローアップイベントとして、RHC もくもく会を弊社にて開催します(2017/10/11 (水) 18:30-、申し込みは Ruby hack Challenge もくもく会)。Ruby コミッタとして遠藤と笹田がサポートします。 RHC 参加者に限らず、Ruby のハックに興味のある方がいらっしゃいましたら、ぜひご参加ください。

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/