Проблема появляется после первого же аудиторского созвона: в документе уже есть «уязвимость», но внизу только ссылка на задачу, пересказ слов коллеги и скриншот без контекста. Никто не может ответить, кто наблюдал факт, в какой разрешённой среде, что именно проверялось и можно ли повторить вывод. Цена высока в обе стороны. Неподтверждённую гипотезу могут срочно отправить в релиз, а важное ограничение доступа — отложить, потому что evidence оформлен хуже, чем громкое предположение.
У этой ситуации одна частая причина: evidence, scope и authorization складывают в одну колонку «доказательство». Но это разные объекты. Evidence связывает конкретное утверждение с источником и ограничением. Scope определяет, к какому участку системы относится вопрос. Authorization ограничивает допустимые действия. Ни ссылка на стандарт, ни контакт из security.txt, ни положительный результат автоматического инструмента не могут заменить два остальных слоя. Пока они склеены, отчёт невозможно безопасно проверить или оспорить.
Evidence — это цепочка, а не убедительная формулировка
Для каждого утверждения полезно завести короткую evidence card. В ней есть ID scope, объект, наблюдаемый факт или вопрос, происхождение материала, владелец, состояние верификации, ограничение и следующий шаг. Важно различать «видели», «подтверждено владельцем», «воспроизводимо в согласованной среде» и «не проверено». Это не шкала доверия к человеку. Это способ не потерять то, чего в записи пока нет. Если источник — только устный контекст, он может быть полезен для гипотезы, но не должен превращаться в finding при экспорте отчёта.
ASVS задаёт требования к верификации, а WSTG предоставляет каталог сценариев. Обе рамки помогают назвать предмет проверки, но не производят evidence сами. WSTG identifier без версии может измениться вместе с guide, а ASVS requirement без описания метода не показывает, что было сделано. Поэтому рядом с каждой карточкой нужно фиксировать точную версию источника, локальную границу и тот факт, который действительно подтверждён. Если этого нет, честный статус — evidence gap, а не «контроль пройден».
| Слой | Вопрос | Минимальная запись | Опасная подмена |
|---|---|---|---|
| Scope | какая часть системы обсуждается? | asset ID, boundary, owner | домен выдают за карту всей системы |
| Permission | что разрешено делать? | согласованный метод, среда, stop condition, контакт | security.txt трактуют как carte blanche |
| Evidence | что именно можно утверждать? | источник, статус, ограничение, связь со scope | скриншот или мнение называют воспроизводимым finding |
| Decision | кто и что делает дальше? | owner, reversible step, criterion, rollback | оценку severity выдают за автоматическое исправление |
Разрешённая проверка начинается там, где заканчивается догадка
Иногда команда ищет формальное слово, которое позволит «аккуратно проверить». Его нет. Authorization должна быть конкретной: объект, среда, временное окно, допустимые и запрещённые классы действий, контакт, условие остановки, обращение с данными и ожидаемый артефакт. Эта запись может быть краткой, но она должна существовать до того, как будет изменено состояние, отправлен необычный запрос или затронута внешняя зависимость. Если право не подтверждено, безопасное действие — задать вопрос владельцу, а не расширять эксперимент до фактической проверки.
RFC 9116 полезен именно как предохранитель от неверного вывода. Документ помогает организации опубликовать contact, policy и срок актуальности disclosure-информации. Он также напоминает, что файл относится к конкретному домену или IP и не создаёт implied permission for testing. Значит, security.txt можно положить в evidence как канал связи, но нельзя записать в поле authorization. Такой разделитель экономит время на споре и снижает риск, что исследование выйдет за неоговорённую границу.
Fixture хранит только форму evidence, не доказательство
Исполнимый пример этой партии намеренно строгий. Он принимает только четыре fixed synthetic evidence cards: scope map, owner route, permission limit и remediation gate. Каждая помечена synthetic-not-externally-verified. Если добавить raw secret, произвольное поле, изменить status на «externally confirmed» или назвать declared boundary реальным permission, contract отклонит вход. Такой тест не заменяет review; он проверяет, что учебная модель не переобещает то, чего у неё нет.
node web/scripts/upgrade-2023-12.mjs --verify-fixture
Проверка не читает сайт, URL, исходный код, CI, логи, переменные окружения или секреты. Она не производит сетевой запрос, не запускает browser и не выполняет security test. В ответе намеренно стоят vulnerability=not-claimed, coverage=not-claimed и compliance=not-claimed. PASS означает, что модель сохранила разделение слоёв, а не то, что команда имеет право проверять проект или что в нём нет слабых мест.
Как вести отрицательное evidence без самообмана
Отсутствие материала тоже нужно записывать. Например, для identity provider не удалось получить владельца или договор интеграции. Это не вывод «интеграция небезопасна» и не повод проставить zero risk. Правильная карточка говорит: boundary известна, owner route отсутствует, метод не согласован, утверждение не сделано, следующий шаг — получить подтверждение. Такая запись помогает triage: она поднимает вопрос туда, где его можно решить, но не создаёт фиктивный finding и не заставляет разработчика исправлять неизвестную причину.
Не следует компенсировать недостаток evidence длинным списком технических терминов. Если неизвестно, как проверяется authz, полезнее написать «требуется подтверждение механизма и тестового пути в разрешённой среде», чем предположить OAuth flow, claim mapping или роль CDN. Автор 2023 года умеет назвать boundary и стоимость пробела, но не притворяется владельцем каждой интеграции. Техническая точность здесь проявляется в том, что вывод ровно соответствует доказательству.
Маршрут: симптом → причина → проверка → действие
- Симптом. В отчёте есть громкое утверждение, но нельзя показать scope, источник, статус верификации, владельца и разрешённую среду.
- Причина. Evidence, permission и decision попали в одну строку; предположение получило статус finding только из-за убедительной формулировки.
- Проверка записи. Для каждого утверждения спросите: к какому asset ID оно относится, кто владелец, откуда взят материал, что именно наблюдалось, какое ограничение у источника и что ещё не проверено.
- Проверка границы. До действия подтвердите method, environment, stop condition и канал связи. Публичность ресурса, стандарт или disclosure contact не дают разрешения сами по себе.
- Действие. Переведите неподтверждённый пункт в hypothesis или evidence gap; назначьте owner и короткий запрос на подтверждение. Finding публикуйте только вместе с воспроизводимым и разрешённым evidence.
- Повтор. Перед triage проверьте, что значение severity не скрывает отсутствие доказательства. Нулевая уверенность не становится низким приоритетом без отдельного решения владельца.
Rollback нужен и для документа
Если новая информация опровергла карточку, откат должен быть простым: вернуть статус к hypothesis, убрать неподтверждённый вывод из decision record, сохранить ссылку на причину пересмотра и повторно назначить владельца. Не надо стирать след изменения: иначе команда снова будет спорить, почему пункт исчез. Но и нельзя оставлять старую формулировку в списке findings с пометкой «уточняется» — на неё всё равно начнут опираться. В реальном процессе порядок хранения, доступа и удаления материалов должен быть определён отдельной политикой; fixture этого не делает.
Следующий шаг — взять один пункт из текущего security backlog и переписать его как evidence card. Добавьте scope ID, owner, literal observation или вопрос, источник, version, status, limit, разрешённый способ подтверждения, reversible next step и критерий закрытия. Если карточка не помещается в несколько строк, значит, в ней смешаны несколько границ или решений. Разделите её до того, как разработка начнёт исправление.
Историческая граница декабря 2023
Эта статья опирается на NIST SP 800-115 (сентябрь 2008), OWASP WSTG v4.2 (3 декабря 2020), OWASP ASVS 4.0.3 (28 октября 2021) и RFC 9116 (апрель 2022), все доступные до конца 2023 года. Они объясняют planning, versioned testing guidance, verification requirements и disclosure channel. Они не подтверждают конкретный finding, не устанавливают authorization для этого репозитория и не превращают fixed synthetic records в compliance evidence.
Проверяемые источники
- NIST SP 800-115: Technical Guide to Information Security Testing and Assessment, сентябрь 2008 — Первичный документ NIST о планировании, проведении, анализе и mitigation технических проверок. Это обзор 2008 года: он не заменяет актуальный договор об авторизации, не задаёт scope конкретного веб-проекта и не подтверждает результаты этого учебного fixture.
- OWASP Web Security Testing Guide v4.2, 3 декабря 2020 — Версионированный официальный guide описывает testing framework, mapping архитектуры и WSTG identifiers. Он не даёт права выполнять тест, не является перечнем всех активов и не доказывает coverage или finding в чужой системе.
- OWASP Application Security Verification Standard 4.0.3, 28 октября 2021 — Официальный ASVS задаёт требования к верификации приложения. Версия 4.0.3 существовала к концу 2023 года, но стандарт не выдает сертификат, не подменяет evidence и не делает учебную запись compliance-результатом.
- RFC 9116: security.txt, апрель 2022 — Информационный RFC описывает канал disclosure и прямо оговаривает отсутствие подразумеваемого разрешения на testing. security.txt относится к домену или IP, из которого он получен; сам по себе он не расширяет scope и не создаёт authorization.
- FIRST: Common Vulnerability Scoring System v3.1, июнь 2019 — Первичная спецификация различает Base, Temporal и Environmental metrics и называет CVSS входом для management process. Она не учитывает автоматически владельца, обратимость изменения, доказательство, разрешённые границы или бизнес-контекст конкретной команды.