京都大学情報学研究科 修士1回の 髙嶋一樹 と言います。
今回、技術職就業型コースのインターンシップとして、セキュリティセンター配下の Security Assessment Team に 10/3 から 11/11 まで参加させていただきました。
こちらでは自分が行った業務の内容紹介とそこで見つけた課題、その解決策と実際に行ったことについて述べたいと思います。(タイトルでオチていますが……)
業務内容について
今回配属されたチームである Security Assessment Team(旧 Application Security Team)は、セキュリティセンターの改組を受けて生まれた組織です。
組織の業務内容としては大きくは変わらず、 過去のブログにも書かれているように開発されたアプリケーションのリスクアセスメントや LINE Bug Bounty Program の運営などを行っています。
このインターンでは、過去に見つかったアプリケーションの脆弱性を検証してみたり、開発されたアプリケーションのリスクアセスメント業務を行いました。
その業務の中で、とあるアプリケーションで GraphQL を用いた DoS 攻撃ができることがメンターさんの指摘でわかりました。
過去の記録を調べてみると、別のアプリケーションでも似たような DoS 攻撃が可能だったこともあり、今回のテーマである検知・可視化ツールの開発に繋がりました。
次節では攻撃の概説と作成したツールについて説明します。
GraphQL を用いた DoS 攻撃とその対策ツールについて
GraphQL とは
GraphQL は API 向けのクエリ言語として近年盛んに使われています。
これを使うと何が嬉しいかというと、例えば、REST API だと同時に複数の関連するデータが欲しい際には「一つのテーマごとにクエリを投げる」か「その一部または全てを包含するようなクエリを投げる」のですが、前者ではリクエストが大量に発生しかねませんし(過小な取得)、後者では適切なサイズを返す API を作らなければ余計なデータも取ってくる(過大な取得)ことになります。他方、GraphQL では関連したデータを特有の schema で扱っているため、一つの適切なサイズなクエリで完結することができ、それにより通信のボトルネックを抑えることができます。
他にも、それぞれのオブジェクトが型付けられていたり、様々な言語のライブラリでサポートされているため移植性が高いといったメリットがあります。
しかしその一方で、GraphQL には実装上の罠があり、開発者によってはその罠を踏んでしまうことがあります。
いくつかは GraphQL診断ガイドライン に載せられていて、その中の一つに GraphQL による DoS 攻撃 というテーマがあります。
GraphQL ではクエリをネストさせることで複数の関連するデータを持ってくることができるのですが、型定義に循環があった場合には無限に(高々有限ですが)深くネストを組むことができます。
これにはメジャーな対策とされるものがあります。
例えば、循環を止めるためにネストの深さを制限することを考えますが、これでは浅いネストでもそれぞれの層のオブジェクトの数が多ければ DoS を回避できません。
(他にも、そうした問題を包括的に解決するための Query Complexity という概念を用いたり、そもそも計算の打ち切り時間を早くすることで解決を望んだりすることは考えられますが、これらは adhoc な制限になるので上手くやるのは難しいですね。)
こういった理由で、データ構造としては型を辿っていった際に木構造になることが望ましいと言えます。
作成したツールについて
型定義を循環させないために使えるツールの一つとして、GraphQL には GraphQL Voyager という型の visualizer や GraphQL Editor という編集ソフト があります。
前者は GraphQL の Introspection というシステムを用いて内部の型構造をグラフィカルに表示できるツールです。
後者は GraphQL ファイルを、型の対応をグラフィカルに表示させながら読み書きできます。
しかし残念なことに一般的な開発状況ではこれらが使えるとは限りません。
一番望ましいのは GraphQL ファイルを直接処理できることですが、権限周りの制約のために GraphQL の introspection query の情報が書かれた schema.json しか見えないこともあります。
また、 LINE さんの開発環境でも様々な言語で異なるライブラリがプロジェクトごとに使われているため、ただ GraphQL ファイルを読むだけでは難しいことがわかりました。
以上のことから、今回、以下のような機能を持つツールを作成しました。
- GraphQL, schema.json が読める
- 読んだファイル達から schema 定義を取り出してグラフとして表示させる
- グラフに閉路がある場合はそれを表示させる
このツールを使うことで上で述べた脆弱性の早期発見が見込まれます。
作成したツールの適用例
LINE さんで展開されているサービスの実装に対してこのツールを適用してみたところ、いくつかのプロジェクトで見つかりました。
例えば、あるサービスでは画像のように型を辿ることでDoS攻撃が可能でした。(もちろんこれは alias を行ったものですが、サービスに対して決して意図的に攻撃しないでください。犯罪行為として処罰の対象になり得ます。)
最後に
私はこのインターンシップが始まるまで6週間は流石に長すぎると思っていたのですが、実際に業務に就いてみるとあっという間でむしろ時間が足りないくらいでした。
また、値段的に高くて使えないツールや良い開発環境があり、エンジニアとしても楽しませていただきました。
どの組織にも入ってみてわかる面白さはあると思うので、ぜひこれを読まれている方も是非インターンシップに参加されることをお薦めします。
最後にバチバチにブラウンにピントがあった写真と、チームの皆さんとオンラインでご飯を頂いた際のワードクラウドで締めようと思います。
ここまでお読みいただきありがとうございました。