Вступ до безпеки GraphQL API

У світі, де домінує REST, GraphQL представляє зовсім інший підхід до проєктування та запитів до API. GraphQL був розроблений в Facebook у 2012 році як спеціалізований інтерфейс для не SQL баз даних, він являє собою перехід від запитів, що керуються операціями, до запитів, що керуються даними. Порівняно з роботою з REST API, можливість запитувати та отримувати лише певний набір даних є фундаментальною зміною, так само як і робота з одним API інтерфейсом.

Типовий REST API надає окремий інтерфейс для кожної операції, яку він виконує, і його користувачі обмежуються викликом однієї з доступних інтерфейсів з підтримуваними параметрами та роботою з будь-якими даними, які вона повертає. Якщо інтерфейс, який би точно відповідав потребам відсутній, доведеться витягувати інформацію з доступних результатів. Це може призвести до збільшення накладних витрат з погляду продуктивності та пропускної здатності, оскільки програма буде змушена отримувати більше даних, ніж їй потрібно, лише для того, щоб відкинути частину з них.

З іншого боку, звернення до інтерфейсу GraphQL схоже на виконання запиту до бази даних: вказується, які дані потрібні зі схеми, а потім отримуються лише відповідні результати. Окрім очевидної переваги отримання даних, готових до роботи, така точність також може значно зменшити вимоги до пропускної здатності. Дефініції схем додають можливості валідації та перевірки типів, щоб мінімізувати помилки в даних. А оскільки інтерфейс GraphQL просто передає запити resolver функція і повертає результати, не потрібно змінювати API щоразу, коли необхідні інші дані або є потреба модифікувати бекенд сервіс.

Визначення та використання GraphQL API

В той час як специфікація REST API – це список інтерфейсів, GraphQL API має лише один інтерфейс з визначеною схемою даних. Подібно до схеми бази даних, схема GraphQL визначає імена, типи та структуру полів даних, які надає API. Якщо REST API повідомляє, які операції доступні, то GraphQL API повідомляє, які дані доступні.

Оскільки необхідно визначити схему і підтримувати її в актуальному стані, API само документується, що є великою перевагою для розробників, особливо в поєднанні з автоматичною перевіркою типів як даних, так і аргументів.

Запозичивши приклад з документації Apollo (Apollo є популярною платформою GraphQL), проста схема для каталогу книг може бути такою:

type Book {
  title: String
  author: Author
}

type Author {
  name: String
  books: [Book]
}

Отже, маємо книги та авторів як кастомні типи. Кожна книга має одну назву (String) і одного автора (об’єкт Author), а кожен автор має одне ім’я (String) і будь-яку кількість книг (об’єкти Book). REST API, що надає таку інформацію, ймовірно, матиме два окремі інтерфейси з різними URL-адресами для повернення списку книг і списку авторів. У GraphQL всі запити надсилаються на одну URL-адресу, а результати залежать лише від структури запиту. Крім того, можливо надавати вхідні дані та аргументи, щоб отримати саме ті дані, які потрібні програмі.

Мапування GraphQL API для атак

Щоб протестувати або атакувати API, потрібно скласти карту його поверхні атаки. Для REST API це лише питання пошуку інтерфейсів, тому що коли про них відомо, відповідно відомо і про цільові URL-адреси.

Але лише знання інтерфейсів GraphQL не надає багато інформації про те, як її використовувати або тестувати – потрібно знати схему, щоб можна було створювати правильні запити.

Щоб полегшити розробку, GraphQL включає функцію інтроспекції (introspection), яка дозволяє дизайнерам і розробникам переглядати схему і створювати дійсні запити в інтерактивному режимі. Хоча інтроспекція надзвичайно корисна для розробки, вона також може дозволити зловмисникам скласти схему без доступу до повного визначення схеми, тому бажано вимкнути її для приватних API після запуску у виробництво (де це можливо).

Для платформи Apollo зловмисники також можуть зловживати іншою зручною функцією, а саме автокорекцією імен полів. За замовчуванням Apollo GraphQL намагається виправити нереальні назви полів і повертає найближчу відповідну назву. Ретельно підбираючи вхідні рядки, зловмисники можуть зловживати автокорекцією, щоб знайти правильні імена полів перебором.

Вектори атак на GraphQL API

GraphQL має свої унікальні проблеми з безпекою через свою принципову відмінність від REST API, на додаток до тих, що притаманні всім API. Як і у випадку з будь-яким іншим API, необхідно враховувати ризик ін’єкцій другого рівня в підлеглі інтерфейси або джерела даних. Важливим аспектом є також правильне впровадження автентифікації та авторизації, при цьому авторизація у GraphQL створює додаткові виклики. Ще однією небезпекою, специфічною для GraphQL, є ризик відмови в обслуговуванні (DoS) через рекурсивні запити.

Автентифікація та авторизація

Безпечний контроль автоматизованого доступу до будь-якого API (і, опосередковано, до даних за ним) є складним завданням. У випадку GraphQL, авторизація особливо складна, оскільки існує кілька способів доступу до одних і тих самих даних через різні запити. Це створює труднощі у забезпеченні доступу до певних полів лише для авторизованих користувачів API.

Якщо авторизація доступу не впроваджується централізовано та послідовно, це може призвести до серйозних вразливостей у безпеці даних, особливо коли GraphQL накладається на REST API. Це часто трапляється на ранніх етапах впровадження GraphQL, коли новий API додається до чинного застосунку. Якщо автентифікація та авторизація не координуються для обох API, можуть з’явитися прогалини, які дозволять зловмисникам отримати доступ до конфіденційних даних. Тому автентифіковане сканування вразливостей є важливою частиною тестування безпеки.

Відмова в обслуговуванні через рекурсію

Однією з головних переваг GraphQL є можливість переставляти та реструктурувати запити різними способами. Разом з тим, ця властивість може бути використана і як вектор атаки. Нічого не заважає користувачам API створювати та надсилати рекурсивні запити, які викликають ті самі поля знову і знову. Без певних обмежень частоти запитів це може призвести до відмови в обслуговуванні (DoS), особливо при роботі з великими наборами даних.

Цим вектором DoS-атаки надзвичайно легко зловживати, використовуючи лише кілька рядків тексту запиту, і важко блокувати, оскільки рекурсивні запити є дійсним синтаксисом GraphQL, тому такі запити можуть дійсно використовувати. Це ускладнює визначення ресурсомісткого запиту як спроби атаки.

Вразливості у вторинних контекстах (secondary contexts)

Останній вектор атаки не обмежується GraphQL і стосується будь-якого випадку, коли запити передаються через кілька рівнів. Наприклад, існує GraphQL API, що накладається на REST API, який взаємодіє з базою даних. Без належної санітарії вхідних даних зловмисники можуть націлюватися на підлеглий REST API, вводячи, наприклад, шкідливий шлях/переміщення по директоріях як значення поля в запиті GraphQL. GraphQL сприйматиме це як дійсний рядок, але якщо його бездумно вставити у відповідний виклик REST API, цей рядок може дозволити зловмиснику перейти до іншого інтерфейсу для виконання несанкціонованих операцій.

Чи є GraphQL менш безпечним, ніж REST API?

GraphQL не є менш безпечним за своєю суттю, ніж інші архітектури веб API. Насправді порівняно з REST API, які покладаються на конвенції, а не на добре визначений стандарт, GraphQL має вбудовану перевірку та контроль типів, що забезпечує принаймні певний рівень безпеки з самого початку.

Однак, як відносно нова технологія, GraphQL часто інтегрується в чинні застосунки та інтерфейси, що збільшує складність та потенційні вразливості.
Найбільший ризик виникає від спроб користувачів впроваджувати інтерфейси GraphQL без розуміння різниці від REST API. Крім обговорюваних проблем з безпекою, це також стосується інших аспектів, таких як зручність використання та продуктивність.

Перевірки безпеки GraphQL API в Invicti

Окрім надійного набору перевірок безпеки для REST API, Invicti тепер може застосовувати багато з таких перевірок і до GraphQL API. Щоб почати тестування програми за допомогою GraphQL API, потрібно просто імпортувати чинну схему GraphQL з файлу URL-адреси, вказати URL-адресу інтерфейсу та дозволити сканеру почати роботу. Якщо імпортується схема з URL-адреси, Invicti може відстежувати зміни в схемі та завжди використовувати останнє доступну дефініцію (the latest available definition) для кожного сканування.

Вразливості в вебдодатках, які можуть бути автоматично виявлені Invicti через GraphQL API, містять наступне:

  • Сліпе введення команд
  • Сліпа SQL-ін’єкція
  • Командна ін’єкція
  • Локальне включення файлів
  • Позасмугове віддалене виконання коду
  • Підробка запитів на стороні сервера (SSRF)
  • Віддалене виконання коду

Більше інформації про GraphQL API можна дізнатись у відео за посиланням:

Підписатися на новини