Upgrade to Pro — share decks privately, control downloads, hide ads and more …

攻撃者の視点から見たGraphQLのセキュリティ

kuzushiki
September 04, 2023

 攻撃者の視点から見たGraphQLのセキュリティ

Security․Tokyo #2の発表スライドです。
https://security-tokyo.connpass.com/event/290373/

kuzushiki

September 04, 2023
Tweet

More Decks by kuzushiki

Other Decks in Technology

Transcript

  1. Security․Tokyo #2 GraphQLのやりとりをみてみよう GraphQLクエリ レスポンス 1 query { 2 users(id:

    1) { 3 id 4 username 5 } 6 } 1 { 2 "data": { 3 "users": [ 4 { 5 "id": "1", 6 "username": "admin" 7 } 8 ] 9 } 10 } 5 / 23
  2. Security․Tokyo #2 Introspection クライアントにAPI がどのような操作を許可しているかを伝える機能 GraphQLクライアントでのドキュメント表示やフィールド名の自動補完に用いられる 1 query { 2

    __schema { 3 types { 4 fields { 5 name 6 } 7 } 8 } 9 } 1 { 2 "data": { 3 "__schema": { 4 "types": [ 5 { 6 "fields": [ 7 { 8 "name": "pastes" 9 }, 10 { 11 "name": "paste" 12 }, 13 ... 7 / 23
  3. Security․Tokyo #2 Introspectionを用いた情報収集 攻撃者にもAPI がどのような操作を許可しているかが伝わってしまう… 管理用の操作を実行される恐れ 1 { 2 "data":

    { 3 "__schema": { 4 "types": [ 5 { 6 "fields": [ 7 ... 8 { 9 "name": "systemUpdate" 10 }, 11 { 12 "name": "systemDebug" 13 }, 14 ... 8 / 23
  4. Security․Tokyo #2 Alias 名前の衝突を避け、同じフィールド名を複数問い合わせられる機能 Aliasなしだと以下のエラーとなる Fields "users" conflict because they

    have differing arguments. ` ` 1 query { 2 user1: users(id: 1) { 3 username 4 } 5 user2: users(id: 2) { 6 username 7 } 8 } 1 { 2 "data": { 3 "user1": [ 4 { 5 "username": "admin" 6 } 7 ], 8 "user2": [ 9 { 10 "username": "operator" 11 } 12 ... 10 / 23
  5. Security․Tokyo #2 Aliasを用いた認証回避・DoS 攻撃者は1度のクエリで同一フィールドを複数要求可能に… 総当りやパスワードリスト攻撃による認証の突破 重いフィールドを何度も要求することによるDoS 1 query { 2

    admin: login(user: "admin", pass: "admin") { 3 success 4 } 5 test: login(user: "admin", pass: "test") { 6 success 7 } 8 ... 9 } 1 { 2 "data": { 3 ... 4 "truepassword": [ 5 { 6 "success": true 7 } 8 ] 9 ... 10 } 11 } 11 / 23
  6. Security․Tokyo #2 Fragment クエリ内で繰り返し使用する部分を定義し、使い回せる機能 1 query { 2 user1: users(id:

    1) { 3 ...userInfo 4 } 5 user2: users(id: 2) { 6 ...userInfo 7 } 8 } 9 10 fragment userInfo on User { 11 username 12 email 13 } 13 / 23
  7. Security․Tokyo #2 Field Suggestionを用いた情報収集 それっぽいフィールド名を大量に送り、有効なフィールド名を列挙 (Blind Introspection) clairvoyance というツールを使うと、Introspection Queryの応答に近い情報が得られる

    1 query { 2 articles 3 documents 4 posts 5 ... 6 } 1 { 2 "errors": [ 3 ... 4 { 5 "message": "Cannot query field \"posts\" on type \"Query\". Did you mean \"pastes\" or \" 6 ... 17 / 23
  8. Security․Tokyo #2 Field Suggestionを用いた情報収集の対策 Introspectionを無効にする場合は、Field Suggestionも同様に無効化すべき GraphQL開発者Lee Byron氏のコメント ” I

    would expect that a schema with introspection disabled would also disable didYouMean. I can’t think of a reason why you would want to disable introspection but enable didYouMean or vice versa. https://github.com/graphql/graphql-js/issues/2247#issuecomment-815430294 ” introspectionを無効にしたスキーマはdidYouMeanも無効になることを期待します。 introspectionを無効にしてdidYouMeanを有効にしたい理由や、その逆は思いつかない。 18 / 23
  9. Security․Tokyo #2 究極の対策: Persisted Queries 通常の方法 Persisted Queries https://www.apollographql.com/blog/apollo-client/persisted- graphql-queries/

    より引用 GraphQLの柔軟性は失われるものの、攻撃者 は自由にクエリを作れなくなる 今までに紹介した攻撃はすべて防げる 本番環境で固定のクエリしか実行しないのであ れば検討する余地あり 本来は帯域節約のために考えられた技術 20 / 23