Читать 7 мин

Как запросы с Unicode-именами хостов могут одобрить неправильный адресат

Запросы на одобрение Unicode-имен хостов должны заранее определять один канонический адресат, прежде чем HTTP-шлюз добавит учетные данные. Тестируйте punycode, письменности, точки, невидимые символы и перенаправления.

Как запросы с Unicode-именами хостов могут одобрить неправильный адресат

Карточка одобрения HTTP-запроса агента, это граница безопасности, а не вежливое уведомление. Если в карточке указан один адресат, а HTTP-стек отправляет учетные данные другому, пользователь не принял информированное решение. Решение за него принял шлюз, просто с более приятным шрифтом.

Unicode упрощает появление такого расхождения, потому что у имени хоста есть несколько форм. Они могут выглядеть связанными, но выполнять разные задачи. Пользователь видит Unicode. DNS получает ASCII-совместимые метки. Парсер URL может нормализовать разделители, процентные escape-последовательности, регистр, запись IPv4-адреса или пустую конечную метку. Обработчик перенаправлений может разобрать следующий адрес другим кодом. Если один слой одобряет одно представление, а другой подключается по другому, учетные данные могут уйти не тому адресату.

Решение не в том, чтобы «запретить домены не из ASCII». Такой подход наказывает легитимные интернационализированные имена и при этом не устраняет ASCII-трюки: вводящие в заблуждение поддомены, userinfo, числовые формы IP-адресов и цепочки перенаправлений. Нужно сделать одну разобранную запись адресата единственным объектом, который одновременно передает сведения в интерфейс одобрения и разрешает добавление учетных данных. А затем проверить неприятные входные данные до выхода в продакшен.

Карточка одобрения должна описывать выполняемый запрос

Запрос на одобрение должен строиться из того же канонического объекта запроса, который выполнит HTTP-клиент. Иначе появляются два источника истины: строка для человека и строка для транспорта. Именно здесь путаница с именем хоста превращается в раскрытие учетных данных.

Создавайте запрос в таком порядке:

  1. Принимайте исходный URL как недоверенный ввод и разбирайте его один раз с помощью реализации URL, выбранной для шлюза.
  2. Отклоняйте неподдерживаемые схемы, некорректные адресаты, встроенные учетные данные и данные, чья каноническая форма не проходит правила проверки имени хоста.
  3. Создавайте структурированную запись адресата со схемой, каноническим хостом, эффективным портом и признаком наличия конечной корневой точки во входных данных.
  4. Формируйте карточку одобрения из этой записи, а затем передавайте ту же запись коду, который выбирает и добавляет учетные данные.
  5. Требуйте нового одобрения, если перенаправление, повторная попытка, прокси или альтернативный адрес меняют запись адресата.

Исходный URL, это свидетельство, а не источник полномочий. Сохраняйте его в записи активности, чтобы объяснить, что пытался сделать агент. Не используйте его сам по себе для сопоставления учетных данных, кэширования одобрений или показа адресата.

Для HTTP адресат, это не просто имя хоста. https://api.example.test:8443/ и https://api.example.test/ могут вести к разным сервисам и политикам сертификатов. Стандартный порт можно не показывать после того, как парсер определил его, но нестандартный порт должен быть виден в карточке. Схему тоже нужно показывать. Отправка bearer-токена по http, а не по https, меняет уровень риска, даже если текст имени хоста совпадает.

RFC 3986 определяет часть host как IP-литерал, IPv4-адрес или зарегистрированное имя. Для синтаксиса этого достаточно, но системе одобрения этого мало, чтобы понять, что человек может безопасно распознать. Сначала разберите URL, затем создайте специальное для безопасности отображение на основе результата разбора.

Punycode, это идентификатор, а не понятное имя

Punycode нужен, чтобы DNS мог передавать интернационализированные метки в ASCII. A-label начинается с префикса ASCII xn, за которым следуют два дефиса, а U-label, это соответствующая форма Unicode. Преобразование обратимо только тогда, когда метка действительна по применимым правилам IDNA. Это важно, потому что строка, лишь похожая на A-label, не становится автоматически корректной или безопасной для показа в Unicode.

RFC 5891 требует, чтобы приложение, выполняющее поиск с учетом IDNA, проверяло внешне похожую на A-label метку до обработки декодированного Unicode-результата как U-label. В частности, если приложение декодирует A-label для показа на языке пользователя, оно должно убедиться, что обратное преобразование дает исходную метку. Такая проверка полного цикла не формальность. Без нее интерфейс может превратить некорректный ASCII в убедительный текст Unicode и дать проверяющему историю, которой транспорт на самом деле не сообщал.

Если ввод интернационализирован, карточка одобрения должна показывать обе формы:

Destination
https://xn--example-ascii-label.test
Unicode rendering: example-unicode-label.test
Port: 443
Credential: deploy token

Разместите каноническое ASCII-имя хоста отдельной строкой, используя моноширинное или иное хорошо читаемое оформление. Не прячьте его за элементом раскрытия. Unicode-форма помогает человеку узнать легитимный сервис, но ASCII-форма остается устойчивым идентификатором, который должен совпадать со списками разрешений, записями аудита, ключами кэша и фактическим путем DNS-поиска.

Не декодируйте каждую метку только потому, что она начинается с маркера A-label. Декодируйте, проверяйте, кодируйте обратно и сравнивайте. Если проверка не прошла, показывайте буквальную ASCII-метку с понятным предупреждением о неудачной проверке IDNA. Безопасное действие, это запретить добавление учетных данных, а не угадывать, что имел в виду агент.

Именно здесь не срабатывает популярная рекомендация: «Всегда показывайте Unicode, потому что punycode выглядит подозрительно». Такой совет делает интерфейс дружелюбнее, но убирает единственное представление, сохраняющее стабильность при разных шрифтах и письменностях. Показывать только ASCII тоже неправильно для легитимного интернационализированного сервиса. Показывайте обе формы, считайте ASCII основной и получайте обе из одного проверенного результата парсера.

Смешанные письменности требуют предупреждения, а не поспешного вердикта

Имя хоста, в котором сочетаются латинские и кириллические символы, может почти не отличаться от ASCII-имени. Например, в метке может быть строчная кириллическая буква, похожая в некоторых шрифтах на латинскую a, c, e, o, p или x. Проверяющий может пропустить подмену, особенно если смысловая часть имени короткая.

Unicode Technical Standard #39 называет это confusable со смешанными письменностями, когда строки визуально похожи, но результат не относится к confusable одной письменности. В стандарте также описаны confusable целой письменности, когда метка использует одну письменность, но напоминает метку другой. Стандарт прямо отмечает ограничение: похожесть зависит от шрифтов, контекстного формирования символов и опыта человека. Детектор может выявить риск, но не доказать, что имя обманное.

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

  • Помечайте каждую метку с результатом смешанных письменностей как требующую явного одобрения для каждого вызова.
  • Показывайте письменности и кодовые точки в подробном представлении, когда проверяющий раскрывает имя хоста.
  • Сравнивайте skeleton имени хоста по UTS #39 с защищенными внутренними именами и явно настроенными важными адресатами.
  • Запрещайте автоматическое повторное использование учетных данных, если адресат похож на защищенное имя, даже если раньше он не встречался.
  • Записывайте версию детектора и результат в журнал активности, чтобы позднее можно было воспроизвести решение.

Skeleton, это артефакт для сравнения, а не замена имени хоста. UTS #39 прямо говорит, что результаты skeleton не подходят для отображения, хранения или передачи как идентификаторы. Храните канонический ASCII-хост. Используйте skeleton для узкого вопроса: «Похож ли этот кандидат на имя, которому мы решили уделить особую защиту?»

Набор защищенных имен должен быть небольшим и осмысленным. Включите собственные точки развертывания, реестры пакетов, хосты систем контроля версий, провайдеров идентификации, платежные и рабочие API. Не составляйте огромный список всех публичных доменов, которые могут быть важны. Иначе предупреждений станет столько, что их перестанут читать, а действительно важное предупреждение будет выглядеть обычным.

Невидимые кодовые точки превращают проверку в проблему отображения

Невидимые символы опаснее явно отличающихся символов не из ASCII, потому что проверяющий не может надежно их увидеть. В зависимости от символа и используемого ПО они могут влиять на объединение, направление текста, переносы строк или выбор глифов. Некоторые IDNA отвергнет. Другие библиотеки могут сопоставить или обработать иначе. Поток одобрения не должен зависеть от того, заметит ли человек отсутствие видимого штриха.

Здесь есть два разных вопроса, которые команды часто смешивают:

  1. Допустима ли эта кодовая точка в метке имени хоста по правилам IDNA?
  2. Может ли эта кодовая точка сделать отображение вводящим в заблуждение, журнал неоднозначным или код сравнения непоследовательным?

Положительный ответ на первый вопрос не решает второй. Для некоторых кодовых точек IDNA устанавливает контекстные правила, а проверка при поиске отклоняет несколько категорий некорректных данных. Но HTTP-шлюз работает также с исходными URL, отображением интерфейса, JSON-журналами, скопированным текстом и, возможно, формами хостов, не связанными с DNS. Проверке безопасности нужны правила для всего этого пути, а не только для корректности DNS. RFC 5891 говорит, что IDNA предназначен для доменных имен, а не для произвольного текста. Ограничьте его обработкой имен хостов и не считайте, что он очищает полный URL.

На экране одобрения отклоняйте имя хоста до добавления учетных данных, если его разобранное Unicode-представление содержит кодовую точку, игнорируемую по умолчанию, управляющий двунаправленный символ или символ, который выбранная реализация IDNA считает некорректным. Это намеренно строже, чем «попробуем поиск и посмотрим». Анонимный публичный браузер может решить выполнить поиск. Шлюз с учетными данными не должен отправлять токен, пока разбирается с неоднозначной строкой.

При журналировании отклоненного ввода сохраняйте две формы: безопасно экранированную последовательность кодовых точек и исходную последовательность байтов или текст UTF-8 в поле, которое не подвергается незаметной нормализации. Хорошая запись активности содержит, например:

raw_host_escaped: "api\\u200d.example.test"
parsed_host_ascii: null
rejection: "default-ignorable code point in hostname display"
credential_attached: false

Не помещайте исходное имя хоста в предложение, которое оператор будет просматривать по диагонали. Во время расследования журналы часто становятся следующим интерфейсом одобрения. Если невидимый символ снова становится невидимым в терминале, вы лишь перенесли ловушку.

Конечная точка, это данные, даже если DNS считает ее корнем

Давайте агентам действия, а не секреты
Направляйте HTTP-запросы агента через встроенный sp mcp shim вместо передачи API-ключей модели.

Имя хоста, оканчивающееся точкой, не является декоративной пунктуацией. В представлении DNS конечная точка обозначает корневую метку и отмечает имя как абсолютное. RFC 1034 объясняет, что каждое полное доменное имя заканчивается корневой меткой, поэтому в печатной форме в конце стоит точка.

Это не означает, что каждый компонент HTTP одинаково обрабатывает api.example.test и api.example.test.. Один парсер может сохранить точку в свойстве hostname. Другой нормализует ее перед подключением. Проверка сертификата, обработка cookie, прокси, список разрешений или кэш перенаправлений могут использовать третий вариант. Единственное безопасное правило, решить, считаете ли вы эти формы эквивалентными, и проверить это решение во всех компонентах, обрабатывающих запрос.

Для шлюза учетных данных рекомендую сохранить сам факт ввода и нормализовать адресат только по документированному правилу сравнения. Храните оба значения:

input_host: "api.example.test."
canonical_dns_name: "api.example.test"
had_root_dot: true

Затем используйте canonical_dns_name для сопоставления записи адресата, но показывайте конечную точку в карточке одобрения, если она присутствовала. Проверяющий должен видеть, что агент передал необычную форму. Обычная точка не должна незаметно расширять полномочия. Если учетные данные одобрены для api.example.test, запрос к api.example.test. может использовать это одобрение только при согласии парсера, резолвера, проверяющего имя TLS и правила сравнения шлюза относительно одного и того же адресата.

Не удаляйте конечную точку универсальным строковым кодом до разбора. Такое удаление быстро превращается в «очистку хоста», после чего начинают удаляться пробелы, знаки пунктуации или разделители Unicode, которые должны были привести к отклонению. Сначала разбирайте. Нормализуйте только атрибуты, для которых есть письменное семантическое правило.

В наборе тестов парсера нужны враждебные случаи, а не примеры из презентации

Набор тестов имени хоста должен проверять согласованность разбора, каноникализации, отображения, сопоставления учетных данных, установки соединения и журналирования. Проверить вспомогательную функцию, превращающую Unicode-метку в ASCII, полезно, но этого недостаточно, чтобы доказать безопасность пути запроса.

Для первого прохода используйте URL-среду выполнения из продакшена. Следующий скрипт Node проверяет парсер WHATWG URL и выводит поля, которые шлюз одобрения должен сравнивать. Он намеренно печатает JSON, чтобы различия было удобно читать в CI.

const cases = [
  "https://example.test/",
  "https://example.test./",
  "https://münich.example.test/",
  "https://xn\\u002d\\u002dexample-ascii-label.test/",
  "https://pаypal.example.test/",
  "https://api\\u200d.example.test/",
  "https://[email protected]/",
  "https://example.test:8443/",
  "https://127.0.0.1./"
];

for (const raw of cases) {
  try {
    const u = new URL(raw);
    console.log(JSON.stringify({
      raw,
      href: u.href,
      protocol: u.protocol,
      hostname: u.hostname,
      host: u.host,
      port: u.port,
      username: u.username,
      passwordPresent: u.password.length \u003e 0
    }));
  } catch (error) {
    console.log(JSON.stringify({ raw, rejected: error.message }));
  }
}

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

Расширьте набор метками письменностей, с которыми ваша команда действительно сталкивается, символами Unicode, похожими на точки, процентным кодированием в хосте, начальными комбинируемыми знаками, скобками и формами IPv6, A-label в верхнем регистре, некорректными A-label, пустыми метками, локальными именами и перенаправлениями. Добавляйте случаи из отчетов об ошибках. Набор тестов становится полезным, когда содержит строки, из-за которых инженеру пришлось ругаться на файл журнала, а не десять вариантов example.com.

WHATWG URL Standard, это хорошая основа для поведения веб-URL: он описывает разбор хоста, ошибки в процентно-кодированном хосте, преобразование Unicode в ASCII и особые случаи IPv4. Но он не дает права предполагать, что каждый HTTP-стек, DNS-библиотека или виджет интерфейса ведет себя одинаково. Прогоняйте набор через фактический стек.

Перенаправления требуют нового решения об адресате

Останавливайте действия при блокировке хранилища
Когда хранилище заблокировано, Sallyport отклоняет все действия, пока его не откроют через аппаратно защищенный шлюз.

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

Представим, что агент запрашивает https://build.example.test/artifact. Пользователь одобряет токен развертывания для этого хоста. В ответ приходит перенаправление на https://downloads.example.test/file или, что еще хуже, на похожее Unicode-имя хоста. Если клиент автоматически следует перенаправлению и сохраняет заголовок Authorization, шлюз обходит границу одобрения.

Используйте простое правило: HTTP-перенаправление, меняющее схему, каноническое имя хоста или эффективный порт, аннулирует прежнее разрешение на учетные данные. Шлюз может продолжить перенаправление без учетных данных, если это безопасно для операции, но перед добавлением учетных данных к новому адресату он должен остановиться. Покажите новую карточку одобрения, созданную из заново разобранного URL.

Также отделяйте изменение origin от изменения пути. Перенаправление в пределах той же канонической схемы, хоста и порта может сохранить авторизацию, если правила пути операции это разрешают. Не сводите проверку к сравнению текстовых префиксов. https://api.example.test.evil.test/ начинается с успокаивающей строки, но принадлежит другому хосту.

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

Выбор учетных данных требует точных границ

Шлюз, хранящий несколько API-ключей, должен решать, какой ключ можно отправить хосту. Это не вопрос интерфейса. Именно здесь ошибка отображения превращается в сетевое действие.

Храните привязку учетных данных как структурированные данные, например:

{
  "scheme": "https",
  "host_ascii": "api.example.test",
  "port": 443,
  "allow_subdomains": false,
  "require_per_call_approval": true
}

Избегайте правила вроде host.endsWith("example.test"). Оно принимает notexample.test, а неосторожный вариант с проверкой предшествующей точки может неправильно обработать нормализацию Unicode или конечную корневую точку. Если вы разрешаете поддомены, разделяйте канонические ASCII-метки и сравнивайте их справа налево. api.example.test может соответствовать родительскому example.test только при явном разрешении поддоменов в привязке. Родитель никогда не должен соответствовать дочернему имени в обратном направлении.

Храните IP-литералы отдельно от зарегистрированных имен. Не выполняйте обратное разрешение IP, чтобы затем применить правило учетных данных для имени хоста. DNS-имена могут меняться, а обратный DNS не доказывает, что IP разрешен для API-учетных данных. Также не разрешайте имя хоста и не одобряйте каждый возвращенный адрес. Учетные данные привязаны к имени хоста, использованному для TLS и HTTP-адресата, а ограничения соединения могут отдельно запрещать частные, loopback, link-local и другие нежелательные адреса.

Шлюз также должен различать привязку учетных данных и одобрение. Привязка отвечает на вопрос «можно ли вообще использовать эти учетные данные здесь?». Одобрение отвечает на вопрос «разрешил ли человек этому процессу агента использовать их для этого запроса или сеанса?». Смешение этих вопросов превращает список разрешений в неуправляемый оракул подписи.

Записи аудита должны сохранять то, что увидел проверяющий

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

Когда позднее одобрение выглядит ошибочным, операторы должны ответить на три вопроса: что отправил агент, какой канонический адресат шлюз действительно использовал и какой точный текст увидел проверяющий. Одна отрисованная строка URL не может ответить на все три.

Записывайте поля отдельно:

  • исходный URL или его безопасно экранированное представление;
  • разобранные схему, каноническое ASCII-имя хоста, эффективный порт и путь;
  • проверенное отображение Unicode-имени хоста, если оно есть;
  • признаки риска имени хоста: конечная корневая точка, результат проверки смешанных письменностей, совпадение с похожим защищенным именем и отклонение из-за невидимого символа;
  • решение об одобрении, идентификатор учетных данных и факт добавления учетных данных шлюзом.

Делайте запись одобрения неизменяемой до запуска клиентом запроса. Если клиент позднее следует перенаправлению, создавайте связанную дочернюю запись с собственным разобранным адресатом и решением. Строки журнала вроде «одобренный запрос выполнен» недостаточно, если важный факт состоит в том, что первый хост вернул заголовок Location со вторым хостом.

Разделение Sallyport на журнал Sessions для запусков агентов и журнал Activity для отдельных вызовов хорошо подходит для таких свидетельств: сессия показывает, какой процесс получил полномочия, а запись вызова, какой адресат их использовал. Цепочка аудита с хешированием может проверить историю офлайн, но полезные поля все равно нужно зафиксировать до действия. Защищенное от подмены пустое поле все равно остается пустым полем.

Пусть подозрительные имена хостов усложняют работу агента, а не проверку человеком

Безопасный интерфейс одобрения не требует, чтобы человек за две секунды стал специалистом по Unicode. Он увеличивает объем полномочий, необходимый агенту для рискованных форм, и при этом дает проверяющему достаточно сведений для ясного решения.

Используйте такую матрицу поведения:

Условие хостаДействие шлюза
Обычное каноническое ASCII-имя хоста с точной привязкой учетных данныхОбычный режим с одобрением для сессии или отдельного вызова
Корректное интернационализированное имя хостаПоказать ASCII- и Unicode-формы, затем применить обычные правила привязки
Смешанные письменности или сходство с защищенным именемТребовать одобрение для каждого вызова и показывать подробности кодовых точек по запросу
Конечная корневая точкаСохранить и показать точку, сравнивать только по документированному каноническому правилу
Некорректная A-label, невидимый управляющий символ, неподдерживаемый разделитель или расхождение парсеровОтклонить до любой попытки добавить учетные данные или подключиться
Перенаправление на изменившийся адресатПрекратить передачу учетных данных и запросить новое одобрение

Не превращайте карточку предупреждения в спектакль. Стена красного текста приучает людей нажимать кнопку, не читая. Объясняйте причину простыми словами: «Это имя хоста смешивает латинские и кириллические символы» или «Это имя хоста содержит невидимый символ Unicode». Затем покажите канонический ASCII-хост, запрошенные учетные данные и действие. Люди одобряют действия, а не лекции.

Первым добавьте тест запроса, который для обычного читателя выглядит как один защищенный хост, но разбирается в другой адресат. Прогоните его через точную оболочку агента, интерфейс одобрения, селектор учетных данных, HTTP-библиотеку, код перенаправлений и журнал аудита. Если какой-либо этап создает другую строку имени хоста и при этом не приводит к отклонению, у шлюза по-прежнему две истины. Исправьте это до добавления очередного переключателя политики.

Вопросы и ответы

Почему домены Unicode опасны в запросах на одобрение?

Они могут одобрить запрос к другому хосту, если экран одобрения и HTTP-клиент используют разные разобранные и канонические адресаты. Опасность не в самой Unicode-поддержке. Проблема возникает, когда интерфейс показывает удобное для человека представление, а другой компонент решает, куда отправлять учетные данные.

Безопасно ли показывать punycode в диалоге одобрения?

Punycode, это ASCII-кодировка интернационализированных доменных меток, а не оценка безопасности. Метка может корректно декодироваться и при этом выглядеть подозрительно или запутанно для проверяющего. Поэтому экран одобрения должен показывать каноническое имя хоста в ASCII как основной идентификатор, а Unicode-форму использовать только как дополнительный контекст.

Меняет ли конечная точка имя HTTP-хоста?

Конечная точка обычно обозначает корневую метку DNS и превращает имя в абсолютное DNS-имя. HTTP-стек может сохранить ее, нормализовать, отклонить или по-разному обрабатывать при повторном использовании соединения и проверке сертификата. Считайте ее значимой частью ввода, пока ваш конкретный парсер и транспорт не подтвердят обратное.

Нужно ли блокировать каждый домен со смешанными письменностями?

Нет. Смешанный набор письменностей может быть у легитимного домена организации, использующей несколько алфавитов, а имя только из одного алфавита все равно может имитировать ASCII-имя. Обнаружение смешанных письменностей полезно как сигнал для предупреждения, но не как самостоятельное решение о доступе.

Что такое невидимые символы в имени хоста?

Невидимые символы, это кодовые точки Unicode, у которых может не быть видимого начертания, которые могут влиять на объединение или направление текста либо исчезать в конкретном шрифте. В запросе на одобрение они опасны тем, что две строки могут выглядеть одинаково, оставаясь разными входными данными для парсера, интерфейса, журналирования или кода сравнения.

Что должен показывать запрос на одобрение HTTP-запроса от агента?

Одобряйте разобранные схему, каноническое имя хоста, порт, идентификатор учетных данных, HTTP-метод и однозначное описание пути. Не одобряйте только исходную строку URL и не позволяйте перенаправлению или повторной попытке перенести это одобрение на новый адрес.

Может ли прокси решить проблемы с одобрением Unicode-имен хостов?

Только если прокси участвует в той же границе каноникализации и авторизации, что и клиент, добавляющий учетные данные. Журнал прокси может быть полезным свидетельством, но не исправит решение об одобрении, принятое на основе URL, разобранного иначе.

Можно ли просто разрешить список одобренных доменов?

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

Какие компоненты нужно тестировать на Unicode-имена хостов?

Проверяйте каждую среду выполнения, которая может разобрать, показать, разрешить, подключить или перенаправить URL. Обычно это оболочка агента, шлюз, HTTP-библиотека, окно браузера для одобрения, путь к DNS-резолверу и средство отображения журнала аудита.

Достаточно ли скрыть секрет, если адресат выглядит подозрительно?

Нет. Редактирование защищает секрет после журналирования или во время него, но не мешает отправить учетные данные на адрес, который проверяющий неправильно понял. Идентичность адресата нужно установить до того, как шлюз добавит заголовок Authorization или учетные данные клиента.

Sallyport

Sallyport выполняет API-вызовы и SSH-команды за вашего ИИ-агента. Ключи остаются в локальном хранилище на вашем Mac; вы подтверждаете каждый запуск, и каждое действие попадает в запечатанный журнал.

© 2026 Sallyport · Открытый код по лицензии Apache-2.0 · Oleg Sotnikov