2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
攻撃者の視点から見た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.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.09
国内の有名ホテルでは、マグロ丼がなんと1杯「24,000円」 「良いものをより安く」を追いすぎた日本にとって値上げが重要な理由
2024.12.09
10点満点中7点の部下に言うべきこと 部下を育成できない上司の特徴トップ5
2024.11.29
「明日までにお願いできますか?」ちょっとカチンとくる一言 頭がいい人に見える上品な言い方に変えるコツ
2024.12.04
いつも遅刻や自慢話…自分勝手な人にイラっとした時の切り返し 不平等な関係を打開する「相手の期待」を裏切る技
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.12.06
嫌いな相手の行動が気になって仕方ない… 臨床心理士が教える、人間関係のストレスを軽くする知恵
2024.12.03
職場の同僚にイライラ…ストレスを最小限に抑える方法 臨床心理士が語る、「いい人でいなきゃ」と自分を追い込むタイプへの処方箋
2024.12.05
「今日こそやろう」と決めたのに…自己嫌悪でイライラする日々を変えるには
PR | 2024.12.04
攻撃者はVPNを狙っている ゼロトラストならランサムウェア攻撃を防げる理由と仕組み