pixiv insideは移転しました! ≫ https://inside.pixiv.blog/

pixivの事例で考える、脆弱性報奨金制度との上手な付き合い方

新CTOの@edvakfです。

今年のピクシブ株式会社アドベントカレンダーも無事最終日を迎えることができました。

http://qiita.com/advent-calendar/2016/pixiv

脆弱性報奨金というものがありまして、日本だとCybozuさんとかLINEさんの事例が有名です。

今回はピクシブで脆弱性報奨金の導入事例を元に、脆弱性報奨金とどう付き合っていくのが良いかを考えていきます。

忙しい人向けのまとめ

  • BugBounty.jpを利用して脆弱性報奨金制度を導入した
  • セキュリティ部署を作らなくてもミニマルに始められて良い
  • 会社の規模に合わせて報告件数をコントロールしながら報奨金額を設定しよう

BugBounty.jp

f:id:edvakf:20161218042623p:plain

CybozuさんやLINEさんは自前で脆弱性報奨金の窓口を運営されていますが、ピクシブではBugBounty.jpというサービスを利用しています。(pixivの報奨金プログラム詳細

このサービスの良いところは、

  • 日本以外のホワイトハッカー達も報告してくれる
  • 報奨金の支払いにまつわる面倒を丸投げできる(海外送金とか消費税)
  • 報告された脆弱性について運営さんに質問できる「トリアージサービス」

などがあります。

なぜ脆弱性報奨金制度を導入したか

ウェブサービスの脆弱性は皆無であることが当然望ましいですが、皆無であることを証明するのは不可能です。悪魔証明のようなもので、どれだけコストをかけてセキュリティ対策をしても、100%脆弱性が無いとは言い切れません。

そのため、セキュリティにどの程度予算を割けば十分か(脆弱性が無いと言い切れるか)という議論のはあまり意味がなく、それぞれの会社が規模や扱っている情報の内容によって、現実的な範囲でセキュリティに予算を割くべきものと考えています。

ピクシブでは(よくある)脆弱性が起こりやすいプログラムをそもそも書けないようにフレームワークを育ててきたりしましたが、セキュリティを専門とする部署は持っていません。多くのスタートアップ企業も同様の状況だと思います。

セキュリティ部署を持たない会社がミニマルでセキュリティ対策をやり始めるには脆弱性報奨金制度はとても良いです。もし脆弱性が報告されなければ1円も払うことはありませんから。

報奨金額の設定

BugBounty.jpに登録したのは2016年の4月でした。当時は様子見で上限価格を5万円としていましたが、現在は上限価格を10万円としています。

報奨金の額は、一概にXSSなら◯円、CSRFなら◯円と決められるものではありません。先述のように、その脆弱性のもたらす問題の規模によって決まってくるもので、会社によってもバラバラでしょう。

個人的には「需要と供給」の考え方で決めるべきと思っています。報奨金を低く設定すれば報告は来にくくなりますし、いたずらに報奨金を高く設定すれば脆弱性報告が来すぎてしまって、すべてを精査することができなくなってしまい、本末転倒です。

ピクシブではおおよそ次のような基準で報奨金額を設定しています。

  • サーバーに侵入可能 10万円
  • サーバー上のファイルが閲覧可能 10万円
  • リモートで不特定多数に攻撃が可能 3万円
  • 課金を迂回可能 3万
  • 同じネットワーク内で攻撃が可能 1万
  • 難しいが理論的には不特定多数に攻撃が可能 5千
  • 危ない設計 5千
  • 端末にアクセスすれば攻撃が可能 除外

これまでに10万円を支払ったことは1回だけあります。

この基準は内部的な目安で、随時アップデートしていっていますが、報奨金プログラムに反映させられていないのが現在の課題です。きちんと報奨金目安や対象外とする条件などはアップデートしていくべきと思っています。

報告が少なくなってきたら金額を上げる予定です。このように様子を見ながら報奨金額を上げていけるのは良いところです。

報告が来たときの対応

報告が来ると、自分ともう一人が精査して返信しています。脆弱性であると判断したものはissue化して、数日以内に対策することがほとんどです。設計レベルから対策が必要なものは残りがちになりますが、これはどうしても仕方ないですね。

報告の件数は今のところ週に数件程度です。脆弱性報告の精査にあてる時間を週に1時間ぐらい確保すればまわるぐらいなので、なんとか他の業務を圧迫せずにやっていけています。

脆弱性報告の精査に当てられる人数を増やせばもっと金額を上げてどんどん報告を受け付けられるのですが、際どいケースを脆弱性と扱うかどうかは会社のポリシーに関わってきますので、誰でもできる仕事というわけではありません。このあたりの社内体制をどうしていくかも今後の課題です。(BugBounty.jpで有償の「トリアージサービス」を使えば良いかもしれません)

BugBounty.jpでは半分ぐらいの報告は英語です。英語でやり取りできる人が一時精査担当になるとスムーズに応対できますが、引き継ぎコストは多少上がります。これも「トリアージサービス」で英語の応対も頼むことができますので、そちらを検討しても良いかもしれません。

どのような報告が来るか

報告の半分以上はよく知られたソフトウェアの脆弱性を応用したものです。

  • HTTPやDOMで特定のAPIを使えば対策できる脆弱性
  • WordPressの脆弱性(たいていバージョンアップで直る)
  • ImageMagickの脆弱性

などです。本来は利用しているすべてのソフトウェアのアップデートをきちんとチェックしていれば回避できるものですが、現代のソフトウェア開発ではオープンソースソフトを多数利用していたりするので、全部をチェックするのは現実的ではありません。そういった部分に対して目を向けるというか、気を引き締めることができるのは、脆弱性報奨金制度をやっていて良かったことです。

明らかな脆弱性ではない報告をどう扱うかは悩ましいところです。無下に却下してしまっては、せっかく時間をかけて報告してくれた人のモチベーションを削ぐことになってしまいますので、どう伝えるかは悩ましいです。「我々の基準では脆弱性ではないと考えるけれど、設計を変えたほうがいいね。報告ありがとう」といって報奨金を払うこともたまにあります。

おわりに

色々な課題もありますが、ピクシブでは脆弱性報奨金制度とうまく付き合えていますので、今後の利用も拡大していきたいです。

我々の今の規模では週に数件という件数が精一杯ですが、徐々に体制を整えていき、週に10件以上処理できるようになっていきたいところです。重ね重ねになりますが、このようにミニマルで初めて進化させていけるのがBugBounty.jpの良いところとです。

pixivの脆弱性に興味のある方は是非報告をお願いします!

bugbounty.jp

みなさんはSwift3ですか?

この記事は ピクシブ株式会社 Advent Calendar 2016、24日目の記事です。

こんにちは、 @FromAtom です。pixiv SketchとpixivコミックのiOSアプリ開発を担当しています。

さて、世間はクリスマスだなんだと浮かれていますが、我々エンジニアにとっては年末調整とSwift3対応の季節です。みなさんはSwift3ですか? 今回はpixivコミックアプリのSwift3対応をした際のあれこれについて、書いていきたいと思います。

Swift3対応を始める前に

Swift3対応を開始する日を決めておきましょう。Swift3対応のブランチが切られてからは、メインのブランチには致命的なクラッシュ対応以外はマージしないほうが良いです。既存のコードをSwift3化するだけでも大変なのに、新しくマージされたコードもSwift3化していくと、無限に対応が終わらず担当者が疲弊します。

つまり、Swift3対応をしている間は新機能追加やバグフィックスができなくなります。ユーザに価値が届けられない時間が結構長く続くので、「なぜSwift3対応をしないといけないのか?」をチームメンバーにしっかりと共有し、いつからコードをフリーズしても良いかをしっかりと調整しておくことが大切です。

人数

1人でやりました。Swift3にconvertすると大量のエラーが出るのですが、Xcodeが途中でビルドを諦めてしまうため「ファイル毎に担当者を決めてエラーを潰していく」ということが難しいです。複数人で手分けしてやるのは厳しいので、担当者を1人決めてえいやっと終わらせるか、ペアプロでやると良いと思います。

日数

僕がやった時には2週間かかりました。利用しているライブラリの数やコードの規模にもよりますが、テスト期間を含めて2〜3週間程度を見ておくと良いでしょう。

ライブラリ

僕がSwift3対応を始めた9月に比べて、いまでは多くのライブラリがSwift3対応をしているかと思います。現時点でSwift3対応していないライブラリは、メンテがされていないライブラリなので、使うのをやめましょう。他のライブラリを探すか、自分で作ってしまいましょう。

なお、CocoaPodsやCarthageは最新版を利用しておけば大丈夫です。Carthageは場合によっては --no-use-binaries が必要になりますのでご注意ください。

その他細かいハマりどころ

NSがなくなった

NSURLNSNotification などから NS のprefixがなくなりました。詳しくは下記リンクにまとまっています。

これらは、Xcodeのconvert機能で変換されます。しかし、自分で URLNotification という名前のクラスや構造体を作っている場合、名前がかち合ってしまいます。この場合 Foundation の URLNotificationFoundation.URLFoundation.Notification として変換されます。

正しく動作はするのですが、コードが煩雑になりますし、将来的に「ここのNotificationはどっちのNotificationだ?」となるので、自動変換をするまえに名前を変えておくことをおすすめします。

@noescape が非推奨になり @escaping が追加された

こちらの記事がよくまとまっています。

completionHandler などを実装している時に警告されると思います。Xcodeの言うとおりに何も考えず @escaping をつけていくと想定外の挙動をしたり、循環参照になったりするので注意が必要です。

Abolish ImplicitlyUnwrappedOptional type の影響

詳しくはこちら

簡単にサンプルコードで説明すると

// swift 2.2

let hello: String! = "Hello"
let world: String! = "World"
print("\(hello)\(world)") // => "HelloWorld\n"

このように、String Interpolation を利用して変数を展開することは多いと思います。Swift2.2では意図したとおりに変数が展開されていますが、このコードをSwift3.0以降で実行すると、

// swift3.0

let hello: String! = "Hello"
let world: String! = "World"
print("\(hello)\(world)") // => Optional("Hello")Optional("World")\n 

となります。謎の Optional が含まれていますね。これは、ImplicitlyUnwrappedOptionalの挙動が変わったことに起因しているのですが、String Interpolationした場合にはコンパイルエラーや実行時エラーにならないのでとても厄介です。。例えば。URLを

let searchWord: String!
let url = "https://example.com/search/?q=\(searchWord)"

のようにString Interpolationを利用して組み立てている場合、エラーにはなりませんが望んだ挙動をしなくなります。とにかくエラーにもクラッシュにもならないのが厄介で、「Swift3化してコンパイルエラーにならないのに、なぜかアクセスが失敗する。」というときはこれが原因のときが多いです。

望まない動作を防ぐためにも文字列は(デバッグ時以外は)String InterPolationを利用せず + で結合したほうが良いでしょう。そもそも例示したURLを組み立てる事例では、 URLComponentsURLQueryItem を使っていくのが良いでしょう。ちなみに、 UILabelなどに文字を流し込むときにも同様な問題があるので、画面上に大量の Optional("hoge") が表示されないように、しっかりと置き換えとテストをしていくことが必要です。

まとめ

ここに示したのは大量に表示されるエラーの一例です。Swift3対応はとても大変な作業ですが、Swift2.3はXcode8.2までしかサポートされないので、ぐっと力をこめて移行してしまいましょう。Swift3->Swift4は少し楽になるはず(はず)ですので、今が頑張りどころです。

また、Swift3.0対応ではライブラリの整理ができる良い機会です。この機会にいらないライブラリを消したり、自作したりしちゃいましょう。

それでは、みなさまがSwift3と共によき新年を迎えられますよう。