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

Предварительные просмотры уведомлений о подтверждении требуют такой же модели угроз, как и действие, о котором они сообщают. Запрос на развертывание кода, вызов клиентского API или запуск удаленной команды может раскрыть важные сведения еще до нажатия кнопки «Подтвердить». Если эти сведения появляются на заблокированном телефоне, общем компьютере, экране в переговорной или синхронизированных часах, система подтверждения уже раскрыла часть операции.
Обычно уведомление считают безобидной технической деталью. Но это самостоятельный канал вывода со своей аудиторией, сроком хранения и правилами доступа. Проектируйте его как намеренно ограниченное приглашение перейти к защищенному экрану принятия решения. Не превращайте его в уменьшенную копию экрана подтверждения.
Экран блокировки - граница раскрытия данных
Заблокированный экран могут видеть коллеги, родственники, гости, камеры и любой человек, проходящий мимо стола. Владелец может находиться рядом, но близость не означает аутентификацию. Это кажется очевидным, пока уведомление о подтверждении не показывает имя рабочего хоста, имя клиента, метку инцидента или первую строку команды оболочки.
Многие команды считают уведомление малочувствительным, если в нем нет самого секрета. Такой критерий слишком узкий. Конечная точка вроде billing-prod.internal, путь вроде /customers/28471/refund или сообщение Rotate compromised access token могут раскрыть сведения о системах, связях и текущих операциях. Злоумышленнику, который собирает такие фрагменты, не нужен bearer-токен, чтобы получить преимущество.
Подумайте, что наблюдатель может понять из каждого поля:
- Адрес назначения может указать на клиента, регион, продукт или рабочий сервис.
- Операция может раскрыть, что аккаунт изменяют, возврат ожидает обработки или идет инцидент.
- Идентификатор агента может показать, с каким репозиторием или задачей работает разработчик.
- В поле причины часто попадает скопированный текст задачи, пользовательский ввод или заметки об инциденте.
- Результат может раскрыть данные, которые действие успело получить до принятия решения пользователем.
Экран блокировки - лишь первая граница раскрытия данных. Операционная система может показать тот же текст в центре уведомлений после разблокировки устройства. Уведомление на компьютере может остаться в истории после ухода человека от общего рабочего места. Его могут увидеть часы. Текст могут записать с экрана, получить через программу удаленной поддержки или видеозвонок. Предварительный просмотр должен оставаться безопасным во всех этих ситуациях.
В документации Apple Platform Security экран блокировки описан как защищенное состояние устройства, а пользовательская аутентификация играет центральную роль в доступе к защищенным данным. Но это не делает текст уведомления защищенными данными автоматически. Приложение само выбирает, что отправить службе уведомлений и что показать до аутентификации пользователя. Считайте настройку конфиденциальности операционной системы одним из уровней защиты, а не разрешением помещать чувствительные сведения в сообщение.
Оповещение должно привлекать внимание, а не раскрывать запрос
Безопасный предварительный просмотр сообщает, что действие требует проверки, и дает достаточно информации, чтобы оценить срочность. Он не воспроизводит само действие. Это важное различие часто стирают: контекст уведомления не равен контексту подтверждения.
Контекст подтверждения должен позволять оператору принять обоснованное решение. Для этого могут понадобиться точный адрес назначения, операция, область действия учетных данных, процесс агента, аргументы, ожидаемый эффект и срок действия. Контекст уведомления нужен, чтобы вернуть нужного человека к защищенному экрану. Ему требуется гораздо меньше сведений.
Для обычного действия предварительный просмотр на заблокированном экране может выглядеть так:
Action approval needed
A development agent requests access to a protected service.
Expires in 4 minutes. Open the app to review.
Этот текст сообщает о срочности и общем масштабе запроса. Он не говорит, обрабатывает ли сервис зарплатные данные, исходный код, платежи или внутренний инцидент. В нем нет URL, метода, команды, ветки, запроса или имени клиента.
Сравните его с сообщением, которое встречается в реальных системах:
Approve POST https://payments.example.internal/v1/refunds/28471
Agent requests bearer token for customer refund. Reason: duplicate charge.
Во втором уведомлении bearer-токен не напечатан, но оно все равно раскрывает слишком много. Из него видны чувствительный сервис, действие, объект, связанный с клиентом, и финансовая операция. Любой, кто прочитает предварительный просмотр, узнает то, что ему не разрешали знать.
Используйте небольшой набор формулировок. Часто достаточно «Требуется подтверждение», «Ожидает запрос на доступ» или «Требуется проверка». Если это влияет на скорость реакции, добавьте общий класс риска: «Внешнее действие», «Доступ к рабочей среде» или «Чтение чувствительных данных». Не делайте метку настолько подробной, чтобы она потеряла смысл. «Экспорт рабочей базы данных» - уже не общий класс.
На экране с аутентификацией нужно делать обратное. Он должен раскрывать запрос настолько подробно, чтобы его можно было безопасно отклонить или осознанно подтвердить. Сокрытие деталей ради конфиденциальности приводит к слепому подтверждению, а это всего лишь другая ошибка.
Обезличивание должно происходить до отправки уведомления из приложения
Для полезной нагрузки уведомления нужна собственная схема. Не формируйте ее, обрезая полную запись о подтверждении в последний момент, и не полагайтесь на список замен строк. Команды выбирают этот путь, потому что полная запись уже существует и ее легко вывести. Но подход ломается, когда появляется новое поле, URL перемещается в подзаголовок или причина содержит скопированные чувствительные данные.
Создайте две явные проекции запроса действия. Одна передает данные на экран подтверждения с аутентификацией, другая - в предварительный просмотр. В модели предварительного просмотра вообще не должно быть полей для исходных URL, заголовков, аргументов команд, фрагментов ответа, имен секретов или свободно вводимых причин.
Псевдокод показывает эту структуру:
type ApprovalRecord {
requestId
agentAuthority
destination
operation
arguments
credentialReference
userReason
expiry
riskClass
}
type NotificationPreview {
requestId
title
body
expiryText
riskClass
}
function makePreview(record):
return NotificationPreview(
requestId = opaqueId(record.requestId),
title = "Action approval needed",
body = previewBody(record.riskClass),
expiryText = formatExpiry(record.expiry),
riskClass = record.riskClass
)
Главное свойство здесь не формулировка, а однонаправленная структура данных. NotificationPreview не может случайно содержать destination, потому что такого поля в нем нет. Ревьюер может проверить эту границу. Тест может отклонить любое новое поле предварительного просмотра, в котором допускается неограниченная строка.
Не пропускайте исходный текст причины через очистку и не считайте задачу выполненной. В причинах регулярно встречаются названия задач, вставленные команды, адреса электронной почты, идентификаторы аккаунтов и внутренние имена. Шаблоны обезличивания не угадывают форматы, которые никто не предусмотрел. Фиксированная фраза из перечисления безопаснее очищенного предложения, введенного пользователем.
С непрозрачными идентификаторами тоже нужна осторожность. Идентификатор подтверждения вроде APR-10482 может казаться безобидным, но предсказуемый номер дает наблюдателю запись, которую можно связать с видимой задачей или последующим разговором. Используйте идентификатор без делового смысла, который нельзя применять как токен авторизации. Еще лучше не показывать его в предварительном просмотре, если он действительно не нужен процессам поддержки.
Храните полный запрос в зашифрованном хранилище приложения или другой записи с аутентификацией, а не в теле уведомления. Система уведомлений может хранить текст дольше, чем сам баннер остается видимым. Ваши правила хранения данных не действуют, если копия остается в другой подсистеме.
Настройки конфиденциальности устройства полезны, но не могут заменить проектирование
Операционные системы обычно позволяют скрывать предварительные просмотры, когда устройство заблокировано. Это полезная настройка, но продукт для подтверждения не может рассчитывать, что она включена, понятна пользователю и одинаково применяется на всех его устройствах.
Кому-то нужны видимые предварительные просмотры для сортировки сообщений. Некоторые организации управляют настройками централизованно. На части устройств нет кода блокировки. Пользователь может читать уведомления на компьютере, экран которого уже разблокирован, пока за его спиной стоит коллега. Приложение, отправляющее чувствительный текст со словами «пользователь может отключить предварительный просмотр», переносит решение о безопасности в самый ненадежный момент настройки системы.
Проектируйте систему с учетом трех условий:
- Операционная система показывает полное уведомление на заблокированном экране.
- Операционная система скрывает тело, но показывает заголовок или имя приложения.
- Экран разблокирован, но его могут видеть другие люди.
Первое условие определяет вашу полезную нагрузку. Если текст безопасен в нем, два остальных проще оценивать. Если текст небезопасен, пользовательская настройка лишь делает проблему непостоянной.
Не делайте слишком далеко идущих выводов о состоянии устройства. Приложение может знать, разблокировано ли его собственное окно, но обычно не знает, кто смотрит на уведомление. Даже надежный сигнал о блокировке не защищает от проектора, внешнего монитора или демонстрации экрана. Безопасный предварительный просмотр должен оставаться безопасным и после аутентификации, потому что физические условия просмотра находятся вне контроля приложения.
Есть одно важное исключение: локальное уведомление с аутентификацией внутри окна приложения может показывать те же подробности, что и экран подтверждения, потому что приложение уже контролирует доступ к этому окну. Это не системное уведомление. Не путайте защищенный встроенный раздел уведомлений с баннером на экране блокировки только потому, что оба называются уведомлениями.
Кнопки подтверждения в уведомлениях ослабляют границу принятия решения
Кнопка «Подтвердить» в уведомлении кажется удобной. Но она создает привлекательный путь к случайному подтверждению, принуждению и потере контекста. Человек видит обрезанный баннер, нажимает знакомую кнопку и разрешает действие, не проверив его настоящую цель или эффект.
Уведомление должно предлагать только действия, сохраняющие границу принятия решения. Кнопка «Открыть для проверки» безопасна, потому что переводит оператора в приложение с аутентификацией. Кнопка «Закрыть» безопасна, если закрытие не отклоняет и не подтверждает запрос и не продлевает его незаметно. Кнопка «Подтвердить» небезопасна для значимых действий, даже если перед выполнением операционная система требует разблокировать устройство.
Аутентификация и осознанное согласие - разные проверки. Аутентификация устройства подтверждает, что кнопку нажал человек, способный разблокировать устройство. Она не доказывает, что человек увидел полный запрос или успел его оценить. Экран подтверждения должен связывать решение с деталями запроса, показывать, изменилось ли что-то после появления уведомления, и требовать нового подтверждения для чувствительного действия.
Это особенно важно для запросов агентов. Агент может создавать множество действий, которые издалека выглядят одинаково. Заголовок «Запрос доступа по SSH» не отличает проверку статуса только для чтения от разрушительной команды. Защищенный экран должен показать конкретное намерение до того, как оператор разрешит действие.
Процесс авторизации Sallyport оставляет решение о фактическом действии внутри приложения с аутентификацией, а не превращает системное уведомление в пульт управления доступом агента. Такой подход менее эффектен, чем подтверждение одним нажатием, зато лучше выдерживает последствия важных запросов.
Не добавляйте в уведомление и элемент «запомнить выбор». Изменения постоянных разрешений требуют отдельного явного экрана, четкой области действия и возможности просмотреть или отозвать их. Экран блокировки - плохое место для создания долговременных полномочий случайным нажатием.
Метки риска должны описывать последствия, не называя активы
Слишком общее уведомление приучает людей открывать каждое сообщение. Слишком подробное раскрывает защищаемый актив. Метки риска частично решают эту проблему, если описывают категорию последствий, а не ресурс.
Используйте категории, основанные на том, что может сделать действие. Например, оно может прочитать защищенную информацию, изменить внутренний сервис, отправить внешний запрос или выполнить операцию, которую трудно отменить. Такие категории объясняют, почему стоит прервать текущую работу, но не раскрывают базу данных, клиента или имя хоста.
Не смешивайте чувствительность доступа и срочность операции. «Высокий приоритет» мало говорит о последствиях подтверждения. «Запись в рабочую систему» сообщает больше, но все еще может раскрыть участие рабочей системы. Безопасность такой формулировки зависит от среды. Один человек на личном устройстве может принять ее, а общий стол службы поддержки должен использовать более широкую метку.
Зафиксируйте словарь и применяйте его к действию до формирования уведомления. Если разработчики могут самостоятельно придумывать текст заголовка, даже самая аккуратная схема не спасет систему. Правило ревью может быть простым: любая строка, поступающая от агента, пользователя, URL, команды, тела запроса или удаленного ответа, запрещена в предварительном просмотре.
Практическое соответствие может выглядеть так:
| Свойство действия | Формулировка в предварительном просмотре | Формулировка на защищенном экране |
|---|---|---|
| Читает защищенный сервис | Чтение чувствительных данных | Точный сервис, метод, путь, область доступа |
| Изменяет внутреннее состояние | Внутреннее изменение | Цель, измененные поля, ожидаемый эффект |
| Отправляет данные за пределы организации | Внешнее действие | Получатель, описание полезной нагрузки, адрес назначения |
| Может быть трудно отменить | Повышенное воздействие | Полная команда или запрос и сведения о восстановлении |
Таблица - это правило для авторов и инженеров, а не обещание, что каждое действие аккуратно впишется в четыре категории. Если действие сочетает несколько эффектов, выбирайте более серьезную категорию. Уведомление, которое слишком рано привлекло внимание, стоит человеку нескольких секунд. Уведомление, скрывшее внешнюю передачу под словами «Запрос доступа», приводит к плохому решению.
История уведомлений и синхронизированные устройства требуют отдельной проверки
Команды часто тестируют первый баннер и на этом останавливаются. Полный путь раскрытия включает сохраненные уведомления, сводки, зеркала на часах, ретрансляторы для компьютеров и все управляемые устройства, получающие те же оповещения аккаунта.
Начните с реального запроса, содержащего специально подготовленные узнаваемые тестовые данные: вымышленное имя клиента, вымышленный внутренний хост, вымышленный адрес электронной почты и вымышленный аргумент команды. Не используйте настоящие рабочие значения для проверки конфиденциальности. Запустите запрос и изучите каждое место, где может появиться текст.
Перед выпуском выполните такую последовательность:
- Заблокируйте основное устройство и отправьте запрос на подтверждение.
- Проверьте баннер, список на экране блокировки и центр уведомлений после разблокировки.
- Включите настроенную пересылку уведомлений или зеркало на часах и изучите их историю.
- Запишите экран через используемые командой средства удаленной поддержки и демонстрации экрана.
- Завершите или закройте запрос, затем проверьте, не остался ли старый текст видимым.
Записывайте точные отображаемые заголовок и тело в каждой точке. Успешный тест - это не «на моем телефоне предварительный просмотр скрыт». Это «ни один тестовый маркер не появился за пределами приложения с аутентификацией». Такой подход обнаруживает и ошибки локализации. Безопасный английский шаблон может стать небезопасным на другом языке, если переведенная строка разрастется и вытолкнет внутренний идентификатор в видимую строку.
Особенно внимательно проверяйте сгруппированные уведомления. Система может показать последнее сообщение, число уведомлений или сводку, собранную из нескольких оповещений. Если каждый отдельный предварительный просмотр безопасен, группа тоже должна быть безопасной. Если код группировки использует название действия вроде «три запроса на возврат», чувствительные сведения вернулись через обходной путь.
Сохранение уведомлений влияет и на реагирование на инциденты. Отзыв сессии агента предотвращает будущие запросы, но не может удалить текст, уже скопированный в историю уведомлений пользователя или на синхронизированное устройство. Поэтому минимизация предварительного просмотра должна происходить до авторизации и проверки аудита, а не после инцидента.
Записям аудита нужны подробности, предварительным просмотрам - сдержанность
Иногда команды безопасности делают предварительные просмотры общими, потому что так же поступили с записями аудита. Они боятся утечки подробных записей. Это смешивает две разные системы с разными аудиториями.
Запись аудита должна быть достаточно полной, чтобы восстановить решение об авторизации: какой процесс агента инициировал действие, с какими полномочиями он работал, каковы адрес назначения, операция, время, решение и результат. Чувствительные значения по-прежнему требуют осторожного обращения, но расследованию нужны факты. Предварительный просмотр не должен содержать ничего из этого, пока человек не прошел аутентификацию в приложении.
Различие особенно важно при сбое. Представьте, что агент запрашивает удаленную команду. В уведомлении написано «Требуется подтверждение», и ревьюер открывает приложение. Защищенный экран показывает команду, хост, идентификатор сессии и срок действия. Ревьюер отклоняет запрос. Позже инженер выясняет причину и обращается к соответствующей записи. Журнал аудита отвечает на этот вопрос, не заставляя исходное уведомление переносить команду через все поверхности отображения.
Sallyport отделяет журналы сессий и активности от обработки уведомлений. Оба журнала строятся из зашифрованного журнала аудита с цепочкой хешей, недоступной для записи. Благодаря этому оператор может изучать действия и проверять цепочку аудита офлайн, не используя предварительные просмотры на экране блокировки как замену доказательствам.
Не помещайте в уведомление хеши аудита, фрагменты записей или исходные идентификаторы корреляции. Они полезны в защищенном интерфейсе и инструментах расследования. На открытой поверхности они создают идентификаторы, которые наблюдатели могут собирать и связывать между собой.
Уведомление должно истекать одновременно с решением, к которому оно относится, а защищенная запись должна явно указывать этот срок. Если человек открывает старое оповещение, приложение обязано получить текущее состояние запроса. Не позволяйте сохраненному тексту уведомления убедить пользователя, что он подтверждает тот же запрос, который существовал пять минут назад.
Превратите правила предварительного просмотра в тесты, а затем попытайтесь их сломать
Рекомендация вроде «избегайте чувствительных данных» не выдержит давления сроков. Превратите ее в проверки, которые запускаются вместе с построителем уведомлений, и в тестовые сценарии, понятные ревьюерам.
Самая полезная проверка - список запрещенных источников данных, а не хрупкий список слов. Отклоняйте любое поле предварительного просмотра, полученное из URL, хоста, текста команды, заголовка, тела запроса, метки учетных данных, свободной причины, удаленного ответа, адреса электронной почты или идентификатора аккаунта. Затем разрешайте только ограниченный набор фиксированных шаблонов и категорий с заданным диапазоном значений.
Небольшая тестовая фикстура может выглядеть так:
record.destination = "https://claims-prod.internal/cases/FAKE-784"
record.arguments = "--account [email protected] --export"
record.userReason = "Customer Northstar reports a disputed claim"
record.riskClass = EXTERNAL_ACTION
preview = makePreview(record)
assert preview.title == "Action approval needed"
assert preview.body == "An external action requires review."
assert preview doesNotContain "claims"
assert preview doesNotContain "FAKE-784"
assert preview doesNotContain "fake.person"
assert preview doesNotContain "Northstar"
Положительные проверки не менее важны, чем отрицательные. Они не позволят последующему изменению заменить безопасное фиксированное сообщение на пустое и расплывчатое уведомление, которое пользователи научатся закрывать не глядя. Также тестируйте формулировки срока действия, локализацию, группировку уведомлений и отображение для специальных возможностей. Программы чтения с экрана могут озвучить содержимое, скрытое визуальным сокращением, поэтому вывод для специальных возможностей должен использовать ту же ограниченную модель предварительного просмотра.
Наконец, попросите человека, который не писал эту функцию, прочитать уведомления и поискать рабочие подсказки. Такой человек заметит то, к чему автор привык: кодовое имя проекта, знакомую метку среды или внутреннее прозвище сервиса. Если информированный посторонний может понять, какое действие защищается, уведомление содержит слишком много.
По умолчанию используйте наименее конкретное сообщение, которое все еще помогает человеку вовремя отреагировать. Доказательства, необходимые для настоящего подтверждения, оставляйте за аутентификацией, а каждый быстрый путь направляйте обратно к ним. Такой дизайн может стоить одного нажатия, зато не превращает каждый заблокированный экран в тихий канал раскрытия данных.
Вопросы и ответы
Что должно быть видно в уведомлении о подтверждении на экране блокировки?
Считайте экран блокировки общедоступной или частично общедоступной поверхностью. Покажите, что требуется подтверждение, укажите класс риска и короткий срок действия, но оставьте цели, учетные данные, тела запросов, аргументы команд и результаты внутри приложения с аутентификацией.
Безопасно ли показывать конечную точку API в предварительном просмотре уведомления?
В большинстве случаев нет. Имя ресурса может раскрыть клиента, внутренний проект, рабочую среду или инцидент безопасности. За пределами приложения используйте нейтральный класс ресурса, а точный адрес показывайте только после аутентификации.
Можно ли включать идентификатор действия в уведомление о подтверждении?
Обычный идентификатор подтверждения допустим, если он ничего не означает за пределами вашей системы и не может использоваться для авторизации. Не используйте в качестве идентификатора URL, номер аккаунта, имя клиента, фрагмент команды или предсказуемую последовательность.
Не приводят ли общие уведомления о подтверждении к усталости от подтверждений?
Общие уведомления тоже создают риск: люди могут подтверждать их, не понимая контекста. Поместите важные сведения на экран подтверждения с аутентификацией, а предварительный просмотр ограничьте информацией, достаточной для решения открыть его.
Должны ли пользователи иметь возможность подтверждать действие прямо из уведомления?
Нет. Действие уведомления должно только открывать экран решения с аутентификацией или закрывать уведомление. Оно не должно подтверждать действие, продлевать сессию, раскрывать скрытые сведения или передавать токен подтверждения через систему уведомлений.
Как классифицировать рискованные действия агентов для уведомлений?
Классифицируйте операцию до формирования сообщения. Чтение может раскрыть данные, запись изменяет состояние, а необратимое или внешнее действие требует более четкой формулировки и заметного уведомления, даже если предварительный просмотр остается закрытым.
Как проверить, не раскрывают ли предварительные просмотры чувствительные сведения?
Отдельно проверьте заблокированный, разблокированный и общий экран. Также изучите историю центра уведомлений, зеркала на часах, снимки экрана и все устройства, на которые пересылаются оповещения: каждая поверхность может сохранить больше, чем показывает первый баннер.
Что делать, если приложение не может определить, заблокирован ли экран?
Приложение должно использовать безопасный вариант, если не может определить состояние устройства или настройку конфиденциальности для зрителя. Отложенное или менее подробное уведомление лучше, чем показ команды для рабочей среды или данных клиента на неконтролируемом экране.
Когда допустимо показывать полный предварительный просмотр уведомления?
Только если у получателя нет другого полезного источника контекста и сообщение не раскрывает ничего чувствительного. Для систем подтверждения лучше использовать короткое уведомление с предложением открыть защищенное приложение.
Чем данные уведомления должны отличаться от записи аудита?
Разделите данные предварительного просмотра и защищенную запись подтверждения. Предварительный просмотр должен быть намеренно небольшим и обезличенным, а защищенная запись должна содержать адрес назначения, область полномочий, идентификатор, причину и итоговое решение.