2024.10.01
自社の社内情報を未来の“ゴミ”にしないための備え 「情報量が多すぎる」時代がもたらす課題とは?
攻撃者の視点から見たGraphQLのセキュリティ(全1記事)
リンクをコピー
記事をブックマーク
kuzushiki氏:それでは、発表を始めていきたいと思います。
まず簡単に自己紹介をさせてください。私は、kuzushikiと申します。現在、とあるセキュリティベンダーで診断員をやっていて、主にWebアプリケーションの脆弱性診断をしています。最近、バグバウンティに興味を持って、そういうものをちょっとやってみています。
今回は「GraphQL」について話しますが、その前に、もうGraphQLを知っているよという方は、どのぐらいいるでしょうか?
(会場挙手)
ありがとうございます。けっこうな方が知っているということでですね、それではざっくりと説明したいなと思います。
GraphQLは簡単に一言で言うと、Facebook(現「Meta」)が開発したAPIのためのクエリ言語というところで、その特徴は、なんといってもデベロッパーフレンドリーというところで、こういった機能があります。
この画像はGraphQLの構造を示していて、GraphQLの「Graph」という名前から、ノードとエッジといった構造を取っています。
この例は、Shopノードに関連するProductノードを列挙するという操作で、特定のショップで取り扱っている商品を列挙することができます。こんな感じのクエリを送ります。
実際に、GraphQLのやりとりを見ていきましょう。こちらが、GraphQLのクエリとなっていて、users、id、usernameといったフィールドがあります。
usersには、このidという引数を渡していて、これは、idが1となるユーザーのIDとユーザー名を取得するという操作です。(スライドを示して)実際にこのようにレスポンスにもidとusernameが入っています。
これでGraphQLの基本は以上にして、GraphQLには、デベロッパーフレンドリーな機能が本当にたくさんあります。その機能と悪用方法をセットで紹介していきたいなと思います。
まず、Introspectionですね。これはクエリに_schemaというようなフィールドを入れることによって、GraphQLサーバーで、どんなフィールドが有効かを取得できるものです。
実際にこういったクエリを送ると、このようにフィールドとしてpastesやpasteが得られます。
これはGraphQLのクライアントで、ドキュメントを表示するといったことに使えます。非常に便利な機能ではありますが、これは攻撃者にも実行できて、情報収集に使われてしまいます。
仮にフィールドを列挙した際に、systemUpdateのように明らかに管理用の操作がバレると、それを実行されてしまうおそれもあります。
この対策ですが、そもそもAPIの仕様を公開したくない場合は、この機能を無効にしておきましょう。一部、この機能を無効化できないサービスもあるので、そういった場合は、先ほどの特徴的なフィールド名である_schemaを、ブロックするのがよいのかなと思います。
では次にいきます。次は、Aliasですね。先ほどのusersというフィールドを複数実行したい時に、Aliasをつけないと、このように「Fields "users" conflict」というエラーが出てきます。
このエラーを防ぐために、user1、user2というAliasをここでつけています。これをすることでuser1とuser2のユーザー名を、1回のクエリで取得できます。
ではこれをどう悪用するのでしょうか。これは、認証回避やDoSに悪用されるケースがあります。
ここではGraphQLにログインの処理があるのを想定しています。そうすると、Aliasを使うことでパスワードのリスト攻撃みたいなことができてしまう。そのまま、攻撃者はすべてのフィールドに対する応答を取得できるので、(スライドを示して)このsuccessがtrueとなっているところが正しいパスワードであることがわかります。
それ以外にも、何回も実行することによるサービス停止も考えられます。
この対策ですが、1回にクエリに使えるAliasの数に制限を設けましょう。あと、GraphQLにはコストを計算する機能があるので、それで制限を設けましょう。これは、APIの回数制限では防げないので注意が必要です。
次にいきます。次はFragmentですね。クエリ内で繰り返し使う部分を定義して使い回せるという機能で、この例でも、userInfoというFragmentを作っていて、それをスプレッド構文みたいな形式で使っています。これを実行することで、user1とuser2、それぞれのユーザー名とEメールを取得できます。
これをどうやって悪用するのかというと、こんな感じですね。Fragmentの中でFragmentが使えるケースがあります。
この例では、クエリ内でまず、AというFragmentを参照しているのですが、Fragment A内ではFragment Bを参照していて、BではまたAを参照しているので、ここで、無限ループに陥ってしまいます。これをCircular fragmentsと言います。
これは実は、すでに大半のGraphQLサーバーでは対策済みになっています。というのも、GraphQLの仕様でFragmentはサイクルを形成してはいけないと明記されているので、仕様どおりに実装できていればまったく問題ありません。
ただ、やはり一部脆弱な実装は存在していて、RubyのHTTPサーバーである「Agoo」でこの問題が発見されて、報告されています。現在は修正済みです。
続いて、Field Suggestionですね。これは、このようなクエリを送信した時に、エラーメッセージとして「Cannot query field "products" on type "Query". Did you mean "product"?」が出ます。
productsじゃなくてproductじゃないですかと、正しいフィールド名を提案してくれる非常にすばらしい機能なんですが、情報収集に使われてしまうよといったところで(お話しします)。
(スライドを示して)このように、攻撃者はそれっぽいフィールド名を……articles、documents、postsといったものを送信することで、エラーメッセージとして「Cannot query field "posts"」「Did you mean "pastes" or "paste"?」と返ってくるので「あぁ、じゃあ、これ使えるんだな」というのがわかってしまいます。
これは、Blind Introspectionと言うのですが、これを使った「Clairvoyance」というツールがあって、GraphQLサーバー側でIntrospectionが無効になっていても、このBlind Introspectionを使うことで、Introspectionと同様の情報を得ることができます。
この対策ですが、Introspectionをそもそも無効にするのであれば、Field Suggestionも、同様に無効化しておきましょう。
GraphQLのデベロッパーである、Lee Byron氏も「introspectionを無効にしたスキーマは、didYouMeanも無効になることを期待します。introspectionを無効にして、didYouMeanを有効にしたい理由やその逆は思いつかない」とコメントしています。自分もそのとおりだなと思います。
これまでに、たくさん悪用方法を紹介してきました。けっこういろいろな対策が必要だと思われた方もいると思います。ただ、1ついい方法があって、究極の対策と言われている、Persisted Queriesというものがあります。
本来攻撃者は、GraphQLサーバーにそのままそのクエリを送信できるのですが、このPersisted Queriesを使うと、攻撃者はそのクエリに対応するIDを送信することになります。その後GraphQLサーバー側のミドルウェアで、IDに対応するクエリを参照して、それを実行するということになるので、攻撃者が、自由にクエリを作ることができなくなります。
なので、これまでに紹介した攻撃をすべて防げます。これはもともとはネットワークの帯域節約のために考えられた技術なのですが、セキュリティにも有効ということで今回紹介しました。
「おわりに」ということで、GraphQL特有の機能における悪用方法を紹介しました。GraphQLはデベロッパーにとって、とてもフレンドリーなのですが、それは裏を返すと、ハッカーにとってもフレンドリーということです。不要な機能は無効化しておくことを推奨します。
というところで、参考文献を紹介しておきます。『Black Hat GraphQL』という本から今回紹介しました。約7,000円と、少しお高めですが、GraphQLの攻撃手法を体系的に学ぶことができるので、非常におすすめです。自分も学んだ結果、300ドルの賞金をもらうことができたので、実質プラスとなりました。
(会場笑)
その他の学習リソースもここで紹介しておきます。以上で発表を終了します。ありがとうございました。
(会場拍手)
関連タグ:
2024.10.29
5〜10万円の低単価案件の受注をやめたら労働生産性が劇的に向上 相見積もり案件には提案書を出さないことで見えた“意外な効果”
2024.10.24
パワポ資料の「手戻り」が多すぎる問題の解消法 資料作成のプロが語る、修正の無限ループから抜け出す4つのコツ
2024.10.28
スキル重視の採用を続けた結果、早期離職が増え社員が1人に… 下半期の退職者ゼロを達成した「関係の質」向上の取り組み
2024.10.22
気づかぬうちに評価を下げる「ダメな口癖」3選 デキる人はやっている、上司の指摘に対する上手な返し方
2024.10.24
リスクを取らない人が多い日本は、むしろ稼ぐチャンス? 日本のGDP4位転落の今、個人に必要なマインドとは
2024.10.23
「初任給40万円時代」が、比較的早いうちにやってくる? これから淘汰される会社・生き残る会社の分かれ目
2024.10.23
「どうしてもあなたから買いたい」と言われる営業になるには 『無敗営業』著者が教える、納得感を高める商談の進め方
2024.10.28
“力を抜くこと”がリーダーにとって重要な理由 「人間の達人」タモリさんから学んだ自然体の大切さ
2024.10.29
「テスラの何がすごいのか」がわからない学生たち 起業率2年連続日本一の大学で「Appleのフレームワーク」を教えるわけ
2024.10.30
職場にいる「困った部下」への対処法 上司・部下間で生まれる“常識のズレ”を解消するには