{ "index": 146, "slug": "editorial-2023-12-mechanism-security-audit", "title": "Аудит веб-проекта: как отличить evidence от гипотезы и разрешения", "excerpt": "Отчёт об аудите полезен только тогда, когда каждое утверждение связано со scope, источником, разрешённым методом и проверяемым следующим шагом. Разбираем эту границу на учебном примере.", "contentHtml": "
После аудита в документе появляется строка: «найдена уязвимость на границе авторизации». Но рядом нет точного актива, версии среды, описания наблюдения и подтверждения, что проверка была разрешена. Через день команда уже спорит не о факте, а о формулировке. Одни требуют срочного исправления, другие не могут повторить проверку. Цена ошибки — неверный приоритет и риск изменить рабочий путь без понимания причины. Если вывод окажется ложным, команда потратит время на защиту несуществующей проблемы. Если он окажется верным, слабая запись задержит исправление.
\nТезис. Аудит строится из четырёх раздельных объектов: scope называет участок системы, authorization ограничивает допустимые действия, evidence связывает утверждение с наблюдением, а decision назначает владельца и следующий шаг. Ни один объект не заменяет другой. Публичный URL не описывает всю систему. Ссылка на стандарт не даёт право на тест. Скриншот не доказывает воспроизводимость. Score не превращается сам в план исправления.
\nНачните с одного пользовательского сценария: вход, смена адреса, оплата или загрузка документа. Опишите путь от действия пользователя до изменения состояния. Для каждого перехода запишите asset ID, границу, владельца, класс данных и вопрос проверки. Формулировка «проверить API» слишком широкая. Формулировка «подтвердить, кто принимает решение о доступе между браузером и API» уже задаёт предмет.
\nКарта активов не утверждает, что защита работает или не работает. Она показывает, где команда ожидает контракт и кто может его объяснить. Это важное отрицательное свойство карты. Если для identity provider нет владельца, запись не должна превращаться в «низкий риск». Её статус — пробел в evidence и запрос на подтверждение.
\n| Слой | Вопрос | Минимальная запись | Чего она не доказывает |
|---|---|---|---|
| Scope | Какой участок обсуждаем? | asset ID, boundary, owner | Что участок уже проверен |
| Authorization | Что разрешено делать? | метод, среда, окно, stop condition | Что проверка дала положительный результат |
| Evidence | Что именно наблюдалось? | источник, время, версия, ограничение | Что вывод переносится на всю систему |
| Decision | Кто и что делает дальше? | owner, reversible step, criterion | Что исправление уже выполнено |
Evidence начинается с узкого утверждения. Например: «в согласованной тестовой среде запрос без нужной роли получил ответ 200 на маршруте X». Такая запись ещё не объясняет причину и не говорит, что production уязвим. Она фиксирует наблюдение, условия и границу вывода. Чтобы перейти от наблюдения к finding, нужен повторяемый метод, сопоставимый результат и право выполнить именно это действие.
\nУ карточки evidence должны быть простые поля. scopeId связывает материал с активом. observation описывает факт, а не интерпретацию. source указывает лог, запрос, тестовый отчёт или подтверждение владельца. status различает гипотезу, наблюдение и внешне подтверждённый результат. limit показывает, чего материал не покрывает. nextAction задаёт обратимый шаг. Если одного поля нет, вывод нужно сузить.
Учебный пример ниже использует только фиксированные значения в памяти. Имена, идентификаторы и статусы вымышлены. Пример не открывает URL, не читает исходный код, логи или секреты, не запускает сканер и не имитирует право на тест. Он показывает контракт записи и отрицательную ветку.
\nconst card = {\n scopeId: 'synthetic-asset-web-api',\n observation: 'synthetic-role-check-needs-owner-confirmation',\n source: 'synthetic-record-only',\n status: 'synthetic-not-externally-verified',\n limit: 'no-real-system-no-production-claim',\n nextAction: 'synthetic-owner-review-before-change'\n};\n\nconst accepted =\n card.status === 'synthetic-not-externally-verified' &&\n card.limit.includes('no-real-system');\n\n// accepted === true означает только корректную форму учебной записи.\n// status = 'confirmed' здесь должно быть отклонено.\nЗдесь результат true не означает, что найден контрольный дефект или подтверждена безопасность. Он означает только, что запись сохранила ограничение модели. Если заменить статус на confirmed, пример обязан остановиться: у него нет внешнего источника, разрешённой среды и воспроизводимого теста. Это отрицательный путь, а не декоративная оговорка. Он не даёт учебному коду сказать больше, чем он действительно знает.
Веб-страница может быть доступна из интернета, но это не делает любое действие с ней допустимым. Перед активной проверкой нужны объект, среда, период, метод, ограничения нагрузки, запрещённые действия, контакт и условие остановки. Отдельно определите, как хранить и удалять полученные материалы. Если владелец не подтвердил границу, оставайтесь в режиме инвентаризации и обсуждения контракта.
\nФайл security.txt помогает найти канал раскрытия, но не расширяет scope и не создаёт подразумеваемое разрешение на тест. Так же работают публичная документация, ссылка на программу поиска ошибок и доступность административной формы: это сведения о контакте или интерфейсе, а не согласование конкретного действия. Запишите их как источники контекста, не как поле authorization.
| Симптом | Причина | Проверка | Действие |
|---|---|---|---|
| В отчёте есть finding, но нет asset ID | Домен выдали за scope | Построить путь сценария и назвать boundary | Перевести вывод в hypothesis до заполнения карты |
| Есть скриншот, но нет метода и версии | Материал отделили от условий наблюдения | Проверить источник, время, среду и повтор | Добавить limit или снять статус подтверждения |
| Ссылка на security.txt записана как permission | Канал связи смешали с authorization | Найти отдельную запись о владельце и допустимом методе | Остановить активную проверку до согласования |
| Высокий score требует «срочно чинить» | Оценку тяжести приняли за decision | Проверить exposure, owner, обратимость и критерий | Назначить triage и выбрать обратимый шаг |
| Интеграция не имеет владельца | Third-party boundary не вошла в карту | Запросить owner и контракт обмена данными | Зафиксировать evidence gap, не объявлять zero risk |
Такая модель не обнаруживает уязвимости сама. Она не заменяет ручное тестирование, автоматические проверки, threat modeling, анализ кода или договор с владельцем внешней системы. Стандарт помогает выбрать язык и метод, но не создаёт evidence. Карта не покрывает автоматически скрытые сервисы. Один успешный сценарий не доказывает безопасность остальных ролей и состояний.
\nЕсли новое наблюдение опровергло карточку, не стирайте историю. Верните статус в hypothesis или evidence-gap, сохраните причину пересмотра, уберите вывод из списка подтверждённых findings и назначьте владельца следующего запроса. Это и есть rollback документа. Для реального проекта отдельно определите хранение, доступ и удаление материалов; учебный пример этого не решает.
Критерий готовности проверяем. Для выбранного сценария существует versioned scope record. Каждая граница имеет владельца. Каждое активное действие связано с отдельным authorization record. Каждое утверждение связано с источником, наблюдаемым фактом, версией и limit. Отрицательные ветки останавливают неподтверждённый вывод. Следующий шаг имеет owner, reversible action и criterion. Если хотя бы одного поля нет, аудит не завершён: результатом остаётся конкретный evidence gap, а не общий статус «проверено».
\n