Что нельзя писать в журналы приложения: полный разбор для команды
Логи — последняя линия обороны, пока не становятся главной точкой атаки
Почему логирование — это проблема безопасности, а не только отладки
Разработчики логируют всё подряд — и это понятно. Логи нужны для дебага, расследования инцидентов, трассировки запросов. «Log all the things» — негласный закон команды ops. Проблема в том, что в погоне за наблюдаемостью данные, которые тщательно защищены в БД и зашифрованы в транзите, оказываются в открытом виде в текстовом файле, куда имеет доступ полкоманды.
Как точно описывает эту ситуацию практикующий security-инженер Майк Шевард: логирование способно обойти абсолютно все остальные средства защиты. Можно выстроить военный уровень шифрования и zero-trust-архитектуру — но если секрет попал в лог, часть этой работы обесценена [5].
У этой проблемы три измерения:
Безопасность. Логи — привлекательная цель. Они хранятся дольше, чем нужно, доступны большему числу людей, чем следует, часто отправляются в сторонние агрегаторы (ELK, Datadog, Splunk, Grafana Loki), для которых не всегда подписаны DPA. Атакующему достаточно получить доступ к одному лог-хранилищу — и он получает концентрат всего, что попало в журналы за месяцы.
Комплаенс. GDPR статьи 30 и 32, российский 152-ФЗ, PCI DSS Requirement 10, HIPAA 45 CFR § 164.312(b) — все эти документы требуют контролировать, что именно содержат журналы. Логи с PII — это обрабатываемые персональные данные, и они подпадают под все требования к их хранению, передаче и удалению [6, 7].
Репутация. Утечка через логи хуже стандартного взлома: она означает, что чувствительные данные хранились в открытом виде намеренно — пусть и по недосмотру. Это сигнал о системном провале в security culture.
Что такое CWE-532 и почему это важно знать
MITRE классифицирует запись секретов в логи как CWE-532: Insertion of Sensitive Information into Log File [8]. OWASP Top 10:2025 выделяет класс «Security Logging and Alerting Failures» как отдельную позицию (A09) — наравне с инъекциями и сломанной аутентификацией [1].
В том же стандарте присутствует CWE-117: Improper Output Neutralization for Logs — log injection, когда пользовательский ввод содержит управляющие символы (\n, \r) и позволяет атакующему дописывать в журнал произвольные строки, подделывать события и скрывать следы атак [9].
Обе уязвимости реализуются через банальные паттерны кода, которые пишет любой разработчик без злого умысла.
Восемь категорий данных, которые нельзя писать в логи
1. Пароли, хэши паролей, ответы на секретные вопросы
Это категория с нулевой терпимостью. Пароль не должен попасть в лог никогда: ни в открытом виде, ни в виде хэша, ни в составе URL-параметра, ни как часть тела HTTP-запроса.
В 2018 году Twitter обнаружил, что пароли 330 миллионов пользователей записывались во внутренние логи в открытом виде из-за ошибки в порядке выполнения операций: пароль перехватывался до того, как успевал пройти через bcrypt. GitHub раскрыл аналогичный инцидент в ту же неделю [10]. В 2019 году Facebook признал, что сотни миллионов паролей хранились в plaintext-логах с 2012 года, и к ним имели доступ около 2000 инженеров [3].
Общая причина всех этих инцидентов одна: фреймворк логирования перехватывал входящий HTTP-запрос целиком, до того как приложение успевало обработать поля формы.
2. Токены, API-ключи, секреты приложений
Bearer-токены, JWT, OAuth refresh-токены, API-ключи к внешним сервисам, webhook-секреты, приватные ключи — всё это не должно появляться в журналах.
По данным GitGuardian State of Secrets Sprawl 2026, в 2025 году в публичных репозиториях GitHub было обнаружено 28,65 млн новых hardcoded-секретов — рост 34% за год [11]. При этом 64% секретов, утёкших в 2022 году, по состоянию на январь 2026-го всё ещё активны. Логи — один из главных каналов, через которые секреты выходят за пределы доверенного периметра.
Отдельная история — секреты AI-сервисов. В 2025 году количество утечек ключей к AI-API выросло на 81% год к году. Разработчики, которые быстро интегрируют LLM-инструменты, часто логируют весь контекст запроса включая заголовки авторизации [11].
Типичная ошибка:
# Плохо: токен попадает в лог вместе с заголовком
logger.debug("Outgoing request headers: %s", request.headers)
# Хорошо: исключаем чувствительные заголовки
safe_headers = {k: v for k, v in request.headers.items()
if k.lower() not in ('authorization', 'x-api-key')}
logger.debug("Outgoing request headers: %s", safe_headers)3. Персональные данные (PII)
Согласно SEI CERT и OWASP, к чувствительным данным в контексте логирования относятся: полное имя, адрес электронной почты, IP-адрес, номер телефона, физический адрес, номер водительского удостоверения, СНИЛС/ИНН/паспортные данные, дата рождения, любые идентификаторы, позволяющие установить личность [12].
С точки зрения GDPR (Статья 30) и российского 152-ФЗ, журналы приложений, содержащие PII, — это реестр обработки персональных данных. Значит, к ним применяются требования о сроках хранения, праве на удаление, трансграничной передаче и уведомлении Роскомнадзора [6, 7].
С 1 сентября 2025 года поправки к 152-ФЗ прямо указывают, что IP-адреса, cookie, user-ID в зарубежных лог-хранилищах и дашбордах относятся к персональным данным, и их хранение за рубежом требует отдельного обоснования [13]. Логи, отправляемые в Datadog или Grafana Cloud с серверами в ЕС/США, могут нарушать требование о локализации.
По данным IBM Cost of a Data Breach 2025, PII составляет 52% всех нарушений и в среднем обходится компании в $10,22 млн [14].
4. Платёжные данные
PCI DSS Requirement 10 требует детального аудита доступа к карточным данным. При этом сами данные карты — PAN (Primary Account Number), CVV/CVV2, PIN, дату истечения срока — в логах хранить категорически нельзя [15].
Нарушение стоит дорого: утечка незашифрованных номеров карт из лог-файла является нарушением PCI DSS и может повлечь штрафы от платёжных систем, отзыв права приёма карт и обязательное уведомление держателей [12].
Интересный edge-case: URL с параметрами. Если система принимает номер карты как query-параметр (что само по себе плохая практика), стандартный access-лог веб-сервера запишет его в plaintext. Переход на POST-запросы с передачей данных в теле — обязательный шаг, но и тело запроса тоже нельзя логировать целиком [16].
5. Медицинские данные (PHI)
HIPAA определяет 18 типов Protected Health Information (PHI), которые не должны попадать в логи в незащищённом виде: имена пациентов, даты (кроме года), географические данные, номера телефонов, email, SSN, номера медицинских полисов, данные о заболеваниях, диагнозах, лекарствах [17].
Запись PHI в logging-сервис стороннего поставщика без Business Associate Agreement является нарушением HIPAA. Штрафы — от $100 до $50 000 за инцидент, до $1,5 млн в год за повторные нарушения [18]. В одном из задокументированных случаев больничная система была оштрафована на $2,5 млн за хранение незашифрованных PHI в системных логах, доступных неавторизованным пользователям [18].
6. Внешний пользовательский ввод без санитизации
Это уже не про приватность, а про integrity: неочищенный user-input в логах открывает вектор log injection (CWE-117).
Атакующий передаёт в поле username строку вида:
admin\n[CRIT] Security breach detected — access granted to all usersЕсли приложение логирует "Login attempt for: " + username, в журнале появляется поддельная запись об инциденте. Это позволяет скрывать реальные следы атаки, вводить в заблуждение SIEM-системы и генерировать ложные алерты.
Log4Shell (CVE-2021-44228) — крайний случай того же класса: уязвимая версия Log4j не просто принимала пользовательский ввод в логи, но и интерпретировала JNDI-lookup-выражения, что позволяло удалённо исполнять код [9].
Санитизация — удаление или экранирование символов \n, \r, управляющих последовательностей — обязательна для любых строк внешнего происхождения. Структурированное логирование в JSON закрывает часть этой проблемы автоматически.
7. Session-идентификаторы, cookie, refresh-токены
Идентификатор сессии — это фактически временный пароль. Если он попадает в лог, любой, кто имеет доступ к журналу, может перехватить сессию пользователя без знания его пароля.
Типичный сценарий: full-request-logging в режиме дебага, включённый разработчиком на prod для расследования инцидента и не отключённый после. Заголовок Cookie: session=... попадает в каждую строку access-лога.
Если логировать идентификатор всё же необходимо (для корреляции запросов), следует использовать хэш или усечённую версию: первые и последние 4 символа дают достаточно контекста для трассировки, не раскрывая полный токен.
8. Стек-трейсы с внутренними деталями системы
Полные stack trace с именами внутренних классов, структурой пакетов, версиями библиотек, SQL-запросами, путями к файлам — это разведывательная информация для атакующего. OWASP классифицирует это как information disclosure.
Отдельный пункт: SQL-запросы с подставленными параметрами. Запрос вида
SELECT * FROM users WHERE email = 'user@example.com' AND password_hash = 'abc123...'в логе раскрывает одновременно email пользователя, структуру таблицы и хэш пароля.
В продакшн-логах стек-трейс должен логироваться на уровне ERROR с минимальным контекстом. Полная трассировка — только во внутренние, защищённые системы с ограниченным доступом.
Регуляторный контекст: что грозит за несоблюдение
GDPR
Статья 32 GDPR требует «соответствующих технических мер для обеспечения безопасности персональных данных». Логи с PII без должного контроля доступа — прямое нарушение. Штрафы до €20 млн или 4% мирового оборота [6].
152-ФЗ (Россия)
С поправками 2024–2025 годов незаконное хранение и распространение персональных данных переведено в уголовную плоскость: ФЗ № 421-ФЗ от 30.11.2024 ввёл статью 272.1 УК РФ с максимальным наказанием до 10 лет лишения свободы в случае отягчающих обстоятельств [13]. Административные штрафы за первичное нарушение — от 300 тыс. до 700 тыс. рублей, повторное — до 1,5 млн рублей.
PCI DSS 4.0
PCI DSS v4.0 (обязателен с марта 2025 года) через Requirement 10 требует детального аудита всего, что касается карточных данных, и одновременно запрещает хранить сами данные в незащищённом виде. Хранение PANs и CVV в логах — прямое нарушение [15].
HIPAA
Нарушение требований к защите PHI в логах — от $100 до $50 000 за инцидент. OCR активизировал аудиты в 2024–2025 годах на фоне роста ransomware-атак на healthcare [19].
Как логировать безопасно: практический подход
Принцип минимально необходимого логирования
Логируй ровно столько, чтобы ответить на вопросы: когда, где, кто и что произошло. Без значений полей с чувствительными данными — только факт события, идентификаторы, статус-коды.
Плохо:
{"event": "login", "user": "ivan@company.com", "password": "qwerty123", "ip": "185.x.x.x"}Хорошо:
{"event": "login_attempt", "user_id": "usr_4f8a...", "result": "success", "ip_masked": "185.x.x.*"}Маскирование, токенизация, псевдонимизация
Три техники, каждая для своего случая [16]:
Маскирование (redaction) — замена данных на заглушку или звёздочки. Подходит для случаев, когда исходное значение для целей логирования не нужно совсем: *--*-1234 для номера карты.
Токенизация — замена чувствительного значения на случайный токен с сохранением в защищённом vault. Позволяет коррелировать события без раскрытия реального значения: один и тот же user получает один и тот же токен в разных лог-событиях.
Псевдонимизация — замена идентификатора на детерминированный, но необратимый без ключа псевдоним. Подходит, когда нужна возможность связать события одного пользователя, не раскрывая его личность.
Структурированное логирование как защитный слой
JSON-логи с явными полями сложнее атаковать через log injection: управляющие символы экранируются сериализатором автоматически. Но это не отменяет необходимость санитизации: если значение поля содержит JSON-структуру с вложенными данными, сериализатор запишет всё как есть.
Разграничение log-уровней и доступа
Дебаг-логирование с расширенным контекстом должно быть отключено на проде по умолчанию. Отдельные log-level для security-событий (AUTH, AUDIT) с отдельным каналом хранения и ограниченным доступом — не опция, а требование PCI DSS и хорошей security hygiene [15].
Автоматическое обнаружение секретов в логах
Инструменты статического анализа и сканирования — SAST-правила, специализированные детекторы (truffleHog, detect-secrets, GitGuardian) — позволяют обнаруживать паттерны секретов в лог-файлах и в самом коде до того, как данные попадут в продакшн [4].
Где обычно теряют бдительность: типичные сценарии
Дебаг-режим на проде
Самая частая причина инцидентов. Разработчик включает verbose-логирование для расследования проблемы — и забывает отключить. В логи начинают попадать полные тела запросов, заголовки, ответы внешних API. Решение: логирование на уровне DEBUG не должно включаться в коде приложения — только через конфигурацию с явным TTL.
Логирование всего HTTP-запроса middleware-слоем
Access-log middleware, перехватывающий все входящие запросы, запишет всё, включая форму логина с паролем, если она отправляется через POST. Необходим явный filter-list полей, которые вырезаются до записи.
Error-handling с dump всего объекта
# Плохо: в лог попадает весь объект пользователя
logger.error("Failed to process user: %s", user_object)
# Хорошо: только идентификатор и код ошибки
logger.error("Failed to process user %s: %s", user_object.id, error_code)Сторонние библиотеки и фреймворки
ORM-библиотеки с включённым query-логированием печатают SQL с параметрами. HTTP-клиенты с enabled debug — полные запросы включая заголовки. При включении любого debug-режима стороннего компонента нужно явно проверять, что именно он пишет в логи.
AI-generated код
AI-ассистенты генерируют рабочий, но не всегда безопасный код. Типичная ошибка — логирование всего контекста для трассировки:
// Код, который вполне мог написать AI-ассистент
console.log('Processing request:', JSON.stringify(req.body));
// Если req.body содержит password или token — они в логахИнструменты типа HighVibe, анализирующие конкретное изменение в коде до merge, могут поймать этот паттерн на этапе pull request — до того как он уйдёт в прод HighVibe.
Чеклист: проверь себя до деплоя
Перед выкаткой каждого изменения, связанного с логированием или обработкой форм:
- Проверь все вызовы
logger.*иconsole.logв диффе — нет ли там прямой подстановки пользовательских данных. - Убедись, что HTTP middleware не логирует поля
password,token,authorization,cookie,cvv,pan,ssn. - Проверь, что debug-уровень логирования выключен в конфигурации прода.
- Убедись, что весь внешний пользовательский ввод в лог-строках проходит санитизацию (удаление
\n,\r, управляющих символов). - Проверь конфигурацию ORM/query builder — не включён ли query logging с параметрами.
- Убедись, что стек-трейсы в проде не содержат значений переменных с чувствительными данными.
- Проверь, куда уходят логи: если в сторонний агрегатор — подписан ли DPA, удовлетворяют ли требованиям локализации 152-ФЗ.
- Убедись, что доступ к production-логам ограничен ролями — не весь инженерный состав.
Кейсы: когда игнорирование правил обходится дорого
Twitter, 2018. Ошибка в порядке выполнения операций при хэшировании пароля — пароли 330 млн пользователей записывались в внутренние логи в plaintext. Потребовала принудительной смены паролей и публичного раскрытия инцидента [10].
Facebook, 2019. Сотни миллионов паролей в plaintext-логах с 2012 года. Доступ имели ~2000 инженеров. Несмотря на отсутствие публично подтверждённых злоупотреблений, компания уведомила сотни миллионов пользователей [3].
LastPass, 2022. Атакующий, скомпрометировав рабочую станцию DevOps-инженера, получил доступ к ключам, которые позволили взломать резервные копии пользовательских хранилищ. Один из факторов — ненадлежащая защита credentials в рабочих окружениях [20].
Казначейство США, 2024. Атака была реализована через утёкший API-ключ сервиса аутентификации BeyondTrust. Атакующим не понадобились сложные эксплойты — один скомпрометированный credential дал доступ к критической инфраструктуре [4].
Паттерн во всех случаях одинаков: секреты попали в место, где контроль доступа был слабее, чем предполагалось.
Тренды: что меняется прямо сейчас
AI-assisted разработка ускоряет утечки. GitGuardian State of Secrets Sprawl 2026 фиксирует, что количество утечек секретов растёт в 1,6 раза быстрее, чем численность разработчиков [11]. AI-ассистенты пишут быстро — и регулярно включают в сгенерированный код паттерны с прямым логированием пользовательских данных.
Secrets в AI-инфраструктуре. В 2025 году количество утечек ключей к AI-сервисам выросло на 81%. LLM-оркестрация, RAG, векторные базы — каждая интеграция создаёт новый credential, который может попасть в лог [11].
Требования к локализации в России ужесточаются. С 2025 года IP, cookie и user-ID в зарубежных дашбордах прямо квалифицируются как ПДн. Компании, отправляющие логи в иностранные SaaS-платформы без надлежащего обоснования, рискуют нарушить требования локализации [13].
Логи как вектор атаки на AI-системы. OWASP Logging Vocabulary Cheat Sheet 2025 года уже включает рекомендации по безопасному логированию MCP (Model Context Protocol) и предупреждает против записи полных prompt/tool I/O — это создаёт вторичную поверхность для log injection и утечки чувствительных данных из LLM-контекста [21].
Заключение: что делать дальше
Небезопасное логирование — это не экзотическая уязвимость. Это паттерн, который воспроизводится в каждом новом проекте, потому что кажется безобидным: ну записали строчку в файл, что такого. «Такого» — то, что лог-файл живёт значительно дольше одного инцидента, распространяется в агрегаторы, бэкапы и dev-среды, и его трудно «отозвать».
Практические следующие шаги:
- Проведи аудит текущих log-output в проде — что именно пишется на уровнях DEBUG и INFO.
- Введи правило code review: любой вызов логирования с пользовательскими данными требует явного ревью на предмет чувствительности.
- Добавь SAST-правила или специализированный детектор (truffleHog, detect-secrets) в CI/CD-пайплайн.
- Если команда активно использует AI-ассистентов для кодинга — настрой проверку PR на предмет небезопасных паттернов логирования. Инструменты типа HighVibe анализируют конкретное изменение до merge и могут поймать такие паттерны до того, как они уйдут в прод.
- Определи политику доступа к production-логам: кто имеет право читать, на каком уровне, с каким сроком хранения.
Лог — это инструмент наблюдаемости, а не дамп состояния приложения. Разница между ними — это разница между управляемым активом и потенциальной точкой компрометации.
Источники
[1] OWASP — "A09:2025 Security Logging and Alerting Failures" — https://owasp.org/Top10/2025/A09_2025-Security_Logging_and_Alerting_Failures/
[2] Security Boulevard / GitGuardian Blog — "Keeping Secrets Out of Logs: Strategies That Work" — https://securityboulevard.com/2025/03/keeping-secrets-out-of-logs-strategies-that-work/
[3] TechCrunch — "Facebook admits it stored 'hundreds of millions' of account passwords in plaintext" — https://techcrunch.com/2019/03/21/facebook-plaintext-passwords/
[4] GitGuardian — "The State of Secrets Sprawl 2025" — https://blog.gitguardian.com/the-state-of-secrets-sprawl-2025/
[5] Mike Sheward / Medium — "Passwords in logs: why, what and how?" — https://mike-sheward.medium.com/passwords-in-logs-why-what-and-how-8ab7a6d18db6
[6] Konfirmity — "GDPR Logging And Monitoring: A Practical Guide" — https://www.konfirmity.com/blog/gdpr-logging-and-monitoring
[7] vc.ru — "Как работать с персональными данными в 2025 году: изменения с 1 сентября" — https://vc.ru/services/2238191-rabota-s-personalnymi-dannymi-v-2025-godu
[8] MITRE CWE — "CWE-532: Insertion of Sensitive Information into Log File" — https://cwe.mitre.org/data/definitions/532.html
[9] TuringSec — "CWE-117: Improper Output Neutralization for Logs" — https://turingsecure.com/vulnerability-database/CWE-117/
[10] BleepingComputer — "Twitter Admits Recording Plaintext Passwords in Internal Logs, Just Like GitHub" — https://www.bleepingcomputer.com/news/security/twitter-admits-recording-plaintext-passwords-in-internal-logs-just-like-github/
[11] GitGuardian — "The State of Secrets Sprawl 2026" — https://blog.gitguardian.com/the-state-of-secrets-sprawl-2026/
[12] SEI CERT Oracle Coding Standard — "FIO13-J. Do not log sensitive information outside a trust boundary" — https://wiki.sei.cmu.edu/confluence/display/java/FIO13-J.+Do+not+log+sensitive+information+outside+a+trust+boundary
[13] b-152.ru — "Закон о персональных данных: что изменилось в 2025–2026 годах" — https://b-152.ru/zakon-o-personalnyh-dannyh-2025
[14] eyer.ai — "Log Data Masking: 7 Best Practices for 2024" — https://www.eyer.ai/blog/log-data-masking-7-best-practices-for-2024/
[15] HeroDevs — "PCI DSS 4.0 Requirement 10: How to Log and Monitor All Access to System Components" — https://www.herodevs.com/blog-posts/pci-dss-4-0-requirement-10-how-to-log-and-monitor-all-access-to-system-components-and-cardholder-data
[16] Better Stack Community — "Best Logging Practices for Safeguarding Sensitive Data" — https://betterstack.com/community/guides/logging/sensitive-data/
[17] Loggly — "Protected health information and logging" — https://www.loggly.com/blog/protected-health-information-logging/
[18] ByteHide / Medium — "HIPAA-Compliant Logging in .NET Healthcare Applications" — https://medium.com/bytehide/hipaa-compliant-logging-in-net-healthcare-applications-d3fd4bda121f
[19] Censinet — "10 HIPAA Audit Log Requirements Explained" — https://censinet.com/perspectives/hipaa-audit-log-requirements-explained
[20] Wikipedia — "LastPass 2022 data breach" — https://en.wikipedia.org/wiki/LastPass_2022_data_breach
[21] OWASP Cheat Sheet Series — "Logging Vocabulary Cheat Sheet" — https://cheatsheetseries.owasp.org/cheatsheets/Logging_Vocabulary_Cheat_Sheet.html