Сетевая ошибка часто передаётся одной строкой: «HTTPS не работает». Цена такой записи — повторить тот же эксперимент, потерять hostname за маской или отправить в чат токен из вывода curl -v. Получателю нужны не все байты, а минимальный набор фактов, по которому можно выбрать следующий безопасный запрос.
Ниже соберём полевую карточку для одного обращения: отделим входные данные, наблюдение и гипотезу, затем применим простую очистку вывода. Учебный код принимает текст, удаляет секретные заголовки и сохраняет строки, необходимые для различения TLS и HTTP. Он не отправляет данные и не пишет файл.
Карточка должна разделять факт и гипотезу
Факт — это то, что клиент действительно увидел: код, текст библиотеки, время соединения, имя узла и безопасная часть ответа. Гипотеза — «вероятно, просрочен сертификат» или «путь переписал proxy». Если смешать их в одном поле, следующий инженер примет предположение за результат и начнёт проверку с неверного уровня.
| Поле | Пример | Роль |
|---|---|---|
| Цель | api.example.test | какое имя проверяли |
| Метод и путь | GET /health | какой HTTP-контракт вызван |
| Этап | TLS или HTTP | где появился первый факт |
| Наблюдение | 404, тело missing | что вернул клиент |
| Гипотеза | маршрут не смонтирован | что проверить дальше |
| Следующий запрос | GET /health | ожидаемый результат |
Почему вывод curl требует очистки
Подробный вывод полезен для порядка рукопожатия, редиректов и заголовков, но в нём могут оказаться Authorization, cookie, query-параметры и внутренние адреса. Маскирование должно работать до копирования в задачу или чат. Не полагайтесь на память: человек легко пропустит строку, если вывод длинный.
Отдельно проверьте заголовки proxy-аутентификации и значения после редиректа: очистка только строки Authorization не покрывает все каналы секрета. В карточке оставьте имя поля и замените значение целиком, чтобы получатель понимал, какой тип аутентификации был задействован.
Очистка не должна удалять метод, статус и имя заголовка. Иначе получатель увидит «что-то с HTTP», но не сможет различить 401 и 403. Значение Authorization заменяем целиком, cookie очищаем по имени, а query оставляем только после удаления секретных ключей. Для персональных данных нужен отдельный список полей.
Учебный санитайзер текстового вывода
Входом функции является обычная многострочная строка. Ожидаемый результат — тот же порядок строк, но значение Authorization и Cookie заменены. Пример запускается без сети; он показывает обработку диагностического artefact, а не проверяет сертификат.
function redactNetworkOutput(text) {
return text
.replace(/(Authorization:\s*Bearer\s+)[^\s]+/gi, '$1[masked]')
.replace(/(Cookie:\s*)[^\n]+/gi, '$1[masked]')
.replace(/([?&](?:token|secret|signature)=)[^&\s]+/gi, '$1[masked]');
}
const raw = 'GET /health?token=abc HTTP/1.1\nAuthorization: Bearer abc\nCookie: sid=xyz';
console.log(redactNetworkOutput(raw));
// GET /health?token=[masked] HTTP/1.1
// Authorization: Bearer [masked]
// Cookie: [masked]Проверка результата здесь буквальная: в трёх строках не осталось исходных значений, а имена полей сохранились. Регулярное выражение учебное и намеренно ограниченное. Оно не понимает бинарные данные, нестандартное форматирование и секреты в произвольном JSON, поэтому перед передачей нужен отдельный просмотр очищенного вывода.
Сохраняем причинную цепочку
Хорошая карточка отвечает на четыре вопроса. Что вызвали? Где остановился клиент? Что именно получено? Какой следующий запрос отличит две гипотезы? Например: «GET /health, TLS завершён, HTTP 503 и Retry-After: 2, следующий шаг — повторить GET через две секунды и сравнить зависимость». Это уже проверяемый маршрут, а не комментарий «сервер тормозит».
Не нужно прикладывать полный дамп, если достаточно нескольких строк. При этом нельзя вырезать контекст, который меняет смысл: hostname, порт, метод и статус должны остаться. Время указывайте вместе с часовым поясом, а длительность — с единицей измерения. Если был proxy, напишите это явно, иначе получатель будет считать соединение прямым.
Когда 401, 403 и 404 похожи
| Статус | Наблюдаемая семантика | Проверка |
|---|---|---|
| 401 | нужна аутентификация или она не принята | какой challenge вернул сервер |
| 403 | сервер понял запрос, но отказывает | правило доступа и origin запроса |
| 404 | ресурс не найден по выбранному маршруту | путь, метод и версия API |
| 405 | метод не разрешён для ресурса | Allow и контракт метода |
Текст страницы может быть одинаковым у разных кодов, особенно на proxy. Поэтому в карточке статус важнее заголовка «access denied». RFC 9110 описывает классы статусов и методы, но не знает правила конкретного приложения. Источник задаёт язык сообщения; фактическая причина появляется только из вашего наблюдения и сопоставленного лога.
Порядок безопасной передачи
- Скопировать исходный вывод во временную локальную область, не отправляя его в общий канал.
- Удалить Authorization, Cookie, токены в query и внутренние персональные значения.
- Оставить hostname, порт, метод, путь без секретных параметров, этап, статус и длительность.
- Отделить наблюдение от гипотезы и не называть гипотезу причиной.
- Сформулировать один следующий запрос и его ожидаемый ответ.
- После повторной проверки заменить гипотезу новым фактом или явно сохранить её как неподтверждённую.
Ограничения и следующий шаг
Санитайзер не является системой управления секретами и не гарантирует, что неизвестный формат не содержит чувствительных данных. Не вставляйте очищенный текст в публичный issue без проверки. Для постоянной диагностики лучше использовать структурированные поля с allowlist, чем регулярно маскировать свободный текст.
Следующим шагом заведите шаблон карточки в репозитории: цель, метод, этап, статус, длительность, гипотеза и ожидаемый результат. Добавьте к нему локальный тест на маскирование трёх известных секретов и один отрицательный пример. Тогда следующая ошибка будет начинаться с проверяемого входа, а не с повторного поиска контекста.
Проверяемые источники
- RFC 9110 — HTTP Semantics — IETF Standards Track, June 2022. Нужен для различения методов, статусов, заголовков, маршрутизации и ответа посредника. Граница применимости: Не объясняет конкретную конфигурацию прокси, DNS или причину ошибки в вашем сервисе.
- RFC 8446 — The Transport Layer Security (TLS) Protocol Version 1.3 — IETF Standards Track, August 2018. Нужен для разбора рукопожатия TLS 1.3, проверки имени узла и сообщения об ошибке сертификата. Граница применимости: Не подтверждает доверие к конкретному центру сертификации и не заменяет проверку ключевого материала.