2019年12月1日 | ブログ記事

traP部内サービス「booQ」で発見した脆弱性でOSSコントリビュートした話

nagatech

この記事はtraPアドベントカレンダー2019の32日目の記事です。一般的なアドベントカレンダーだと今日が1日目の記事なんですけどね。


おひさしぶりです。ながてち(@nagatech)です。

今年も残すところあと1ヶ月ですけど、みなさん、卒論の進捗どうですか?
僕はこの記事を書きながら明日(12/2)発表の卒論構想発表の発表資料を作っています。助けてください
なぜこの日に書けると思ってしまったのか...
(追記: 卒論構想発表は無事に終わりました)

それは置いておいて、今回は最近traP部員に向けてリリースした部内サービスの紹介と、その開発中に見つけた脆弱性でVue.js製のライブラリ「Vuetify」にコントリビュートした話を書きたいと思います。

部内サービス「booQ」

booQロゴ
ブックと読みます。ロゴは「booq」と小文字なので部内の表記揺れが激しいです。

どのようなサービスかをざっくり言うと、サークルの備品管理ツールであり、書籍の知見共有ツールであり、部員の貸し借り支援ツールであるような部内向けサービスです。

実際にどういう仕上がりになっているかはbooQ開発チームメンバーの一人の@ryohaくんが書いてくれた記事をみてもらえると嬉しいです。

部内の備品・書籍管理サービスbooQの新規開発 | 東京工業大学デジタル創作同好会traP

余談ですが、この部内サービスの開発にあたってのGitHubの活用法について、技術書典6で本を書いたので、興味のある方は読んでくださると嬉しいです。
BOOTHで電子書籍版が今すぐ買えます(ダイマ)。

traP SysAd TechBook | traP SysAd班

本当は工大祭前リリースに向けてチームメンバー全員でデスマーチした話とか、リリース直後に使用できないレベルのバグを引き起こした話とか、そもそも工大祭が開催されずにbooQが使われなくて悲しい思いで突発的にラジオ配信した話とかを書きたかったのですが、卒論がやばいのでまた別の機会に書きたいなとか思っています。

booQ開発中に脆弱性を見つけた話

今回はこれをメインに書きます。

実際にどういう脆弱性かを説明する前に、booQのカレンダー機能の説明をしたいと思います。

booQのカレンダー機能

2019-11-30-17.34.03

これは実際にリリースされている本番環境のスクリーンショットです。
booQでは別な人から物品(本など)を借りる際に、返却期限を指定することができます。返却期限を指定した場合、画像のようにダッシュボードにカレンダーが表示されて、どのような物品を借りたのか、いつ返せばいいのか、返却期限がすぎていないかなどの確認ができます。

今回見つけた脆弱性はこのカレンダーに関連したものになります。
前提として、booQプロジェクトはクライアントサイド(Vue.js)のCSSフレームワークとして、「Vuetify」を使用しています。

見つけたVuetifyの脆弱性

まずはこちらのスクリーンショットをご覧ください。
image

これはbooQのダッシュボードにアクセスした瞬間の画像です。ページの色が大変なことになっています。

これは何が起こっているのかというと、物品の名前をHTMLタグで囲むことで、HTMLが解釈されて実行されています。スクリーンショットはカレンダーに表示されている物品の<style>body{filter:invert(1)}</style>が実行された状態になります。

上の画像にはカレンダーが写ってないのでカレンダー単体で見ると、カレンダーの名前の部分でHTMLが解釈されていることが分かります。これは物品名が<b>bold</b>です。

CleanShot-2019-10-17-at-13.30.40@2x

booQでは部内限定のサービスでありながら、この脆弱性を放置できない理由がありました。それは、traP部員であることの認証のために部内SNSであるtraQのAPIへのアクセスのためのトークンをクライアント側で保持している設計なので、アクセストークンが取得できれば部員の誰でも別な部員に成り済ますことができるというXSS脆弱性の問題がありました。

そのため、Vuetifyのカレンダーの実装を書き換える必要がありました。

実際に行ったこと

コードの修正

ざっとVuetifyのカレンダーのコードを読んだところ、原因はカレンダーのイベント名を代入するところで、<&ltなどにエスケープされてないことでした。カレンダー以外の実装でエスケープされてる部分あるやろ〜とか思ったら本当にescapeHTMLなる関数が実装されていたのでそれをカレンダーに適用することですんなり問題は解決しました。なので、実際のコード変更は1行だけです。

検証環境の作成

VuetifyのContributeのドキュメントを読みながら検証環境を用意しました。
すんなり環境が用意できて、自分のコードがちゃんと動くことを確認できました。ここらへんのエコシステムがしっかりしてるからOSSとして成功しているんだろうなあ...。

プルリクエスト作成

今回はマジで変更を取り込んで欲しかったので、変更のモチベーションについて解説したり、比較画像を用意したり、いろいろ頑張りました(もちろん英語です)。ここに一番時間がかかったかもしれないです。

実際に作成したプルリクエストがこちらになります。

マージされました🎉

一週間くらい待ったらいきなりマージされました。
その次の日には変更が取り入れられたバージョンがリリースされました。

すぐさま最新バージョンにアップデートすることで、問題は解決されました。
下のスクリーンショットは色がおかしくなる<style>body{filter:invert(1)}</style>がカレンダーに表示されてもなにも起こらなくなった図です。

image--9-

おわりに

この記事では最近リリースした部内サービスの簡単な紹介と、その開発を通してOSSコントリビュートすることができたことを書きました。
OSSにプルリクエストを出してマージされるくらいエンジニアとして成長できたんだなあと一人でしみじみ思っています。
ただ、これは自分一人だけの力で行ったことではなく、SysAd班の人たちにいろいろ助けてもらいながらできたことだと思っています。脆弱性について開発チーム外にもかかわらずいろいろ検証してくれた人たち(特に@spa@sappi_red)には感謝申し上げます。


本当はもっといろいろ書きたかったのですが、12月1日が終わりそうだったのと、ゼミ発表の12月2日が近づいて来てるので締めさせていただきます。(発表資料完成してないよどうしよう...)

明日12月2日の担当は@azulene_c10h8さんと@shirodoniさんです。
お楽しみに!

この記事を書いた人
nagatech

ながてちです Rubyが好きです 最近興味がWeb寄り

この記事をシェア

このエントリーをはてなブックマークに追加

関連する記事

2019年12月4日
部内製チャットサービス「traQ」UIのこれまで 【AdC2019 35日目】
spa
2019年12月1日
「traPに入ってから半年が経ちました。」【AdC2019 31日目】
temma
2019年11月26日
部内製チャットサービス「traQ」とPaaS基盤「Showcase」の障害対応の話【AdC2019 25日目】
to-hutohu
2019年11月2日
traQのmarkdownのパースをWeb Workerでやるようにした話【アドベントカレンダー2019 3日目】
sappi_red
2019年12月11日
円周率が無理数であることの証明【AdC2019 42日目】
Tarara
2019年12月11日
ぷよぷよってナンですか?【AdC2019 42日目】
arahi10

活動の紹介

カテゴリ

タグ