- Gate every layer behind AppLockView when the lock is enabled and lock on launch and on backgrounding; the passcode lives only in the Keychain (AppLockVault) and the enable state defaults to off. - Add the lock section to Settings: enable/setup, change passcode and disable all require the current passcode via a shared passcode sheet; Face ID / Touch ID unlock prompts automatically and can be toggled with passcode confirmation. - Add NSFaceIDUsageDescription to both app targets, cover the passcode policy with tests, guard the feature in verify.sh and document it in SECURITY.md.
91 lines
9.5 KiB
Markdown
91 lines
9.5 KiB
Markdown
# Безопасность и модель угроз MVP
|
||
|
||
- Пароль XMPP сохраняется в Keychain и не попадает в `UserDefaults` или
|
||
локальное хранилище истории.
|
||
- Проверка сертификата не отключается. Ручной host меняет маршрут подключения,
|
||
но XMPP domain/JID остаётся исходной идентичностью.
|
||
- TLS trust оценивается системным Apple Security framework как сертификат
|
||
сервера (`SecPolicyCreateSSL(true, ...)`) для домена из JID; hostname и цепочка
|
||
доверия обязательны даже при ручном адресе подключения.
|
||
- Приложение можно заблокировать паролем (хранится в Keychain, выключено по
|
||
умолчанию): блокировка срабатывает при запуске и при уходе в фон, а
|
||
разблокировка возможна по Face ID/Touch ID.
|
||
- Пароль для SCRAM нормализуется по RFC 4013 (SASLprep), чтобы совпадать с
|
||
серверной нормализацией; для PLAIN пароль отправляется как введён.
|
||
- SCRAM доступен в вариантах SHA-512 (предпочтительный, реализация Luma),
|
||
SHA-256 и SHA-1 (Martin); механизм выбирается по рекламе сервера.
|
||
- Канал шифруется STARTTLS/direct TLS через SecureTransport с уровнем
|
||
`negotiatedSSL` (исключает TLS ниже 1.2) и ALPN «xmpp-client»; на системах
|
||
с поддержкой SecureTransport договаривается TLS 1.3.
|
||
- Когда OMEMO включено глобально или для конкретного чата, исходящие сообщения
|
||
не откатываются на plaintext при ошибке: ошибка показывается пользователю.
|
||
- Пользователь может осознанно отключить OMEMO глобально или для отдельного
|
||
чата. В этом режиме сервер, MAM-хранилище и участники TLS-терминации видят текст.
|
||
- OMEMO доступно и для XEP-0045, но только в неанонимной комнате: клиенту нужны
|
||
реальные bare JID участников, чтобы зашифровать ключ для каждого устройства и
|
||
расшифровать входящее сообщение от правильной Signal identity. Luma проверяет
|
||
режим комнаты, собирает online occupants и доступные списки member/admin/owner,
|
||
а при скрытом JID или отсутствии устройств отменяет отправку без plaintext
|
||
fallback. Новые комнаты Luma создаются members-only и persistent с
|
||
`muc#roomconfig_whois=anyone`.
|
||
- Первый увиденный ключ получает доверие TOFU. Изменившийся ключ становится
|
||
undecided и требует ручной проверки отпечатка.
|
||
- При включённом OMEMO вложения шифруются до загрузки, а URL с ключом находится
|
||
внутри OMEMO payload. При выключенном OMEMO файл хранится на HTTP Upload
|
||
сервисе в исходном виде; ссылка и метаданные также не имеют E2EE.
|
||
- Даже для зашифрованного blob HTTP Upload сервис видит размер и транспортное
|
||
имя файла; у voice/video-note это имя содержит тип и округлённую длительность.
|
||
- Клиент принимает только HTTPS `put`/`get` URL от XEP-0363 компонента и не
|
||
понижает транспорт загрузки до обычного HTTP.
|
||
- В OMEMO-исправлении новое тело зашифровано, но стандартный XEP-0308
|
||
`<replace>` остаётся метаданными stanza: сервер видит id исправляемого
|
||
сообщения, но не новый текст.
|
||
- Ответ содержит id исходного сообщения и JID его автора. В зависимости от
|
||
поведения OMEMO-библиотеки и клиента эти XEP-0461 метаданные могут быть видны
|
||
серверу, даже когда текст ответа зашифрован.
|
||
- XEP-0424 не гарантирует стирание: retract может быть проигнорирован сервером
|
||
или клиентом, а получатель мог сохранить исходный текст. Fallback retraction
|
||
намеренно общий и никогда не повторяет удаляемое содержимое.
|
||
- Для inline-preview расшифрованные фото, видео, музыка и голосовые временно
|
||
записываются в sandbox `tmp`; Luma очищает известные preview-файлы при смене
|
||
аккаунта, а ОС может удалить их раньше как временные данные.
|
||
- Выбранные для пакетной отправки файлы временно копируются в `tmp` для экрана
|
||
предпросмотра и удаляются при отмене либо после завершения отправки.
|
||
- Core Location вызывается только из экрана явной отправки точки. Выбранные
|
||
координаты становятся содержимым сообщения и защищены OMEMO лишь тогда, когда
|
||
шифрование включено для этого чата; при plaintext сервер и MAM видят точку.
|
||
- Аудио/видео звонка шифруются WebRTC DTLS-SRTP между конечными клиентами.
|
||
Это не OMEMO: XMPP-сервер видит Jingle-сигналинг и адрес собеседника, а
|
||
STUN/TURN-сервис видит сетевые адреса и объём трафика. TURN ретранслирует уже
|
||
зашифрованный медиапоток. Если Prosody не публикует собственный сервис через
|
||
XEP-0215, резервный публичный STUN получает запрос на определение адреса.
|
||
- На iOS файл OMEMO-состояния и база локальной истории (SwiftData
|
||
`.store`) получают data-protection `completeUntilFirstUserAuthentication`.
|
||
|
||
## Известные ограничения
|
||
|
||
- На macOS история (SwiftData SQLite в Application Support) и OMEMO state
|
||
лежат в sandbox без дополнительного SQLCipher-слоя; защиту обеспечивает
|
||
учётная запись и FileVault пользователя. Для повышенной модели угроз нужна
|
||
зашифрованная база.
|
||
- Локальная история содержит уже расшифрованные тексты, как и у большинства
|
||
клиентов. Полное удаление требует выхода с опцией удаления истории.
|
||
- «Удалить у меня» удаляет запись только из локального SwiftData-хранилища
|
||
этого устройства и запоминает id против повторной MAM-загрузки; оно не
|
||
удаляет серверный архив, другие собственные устройства или копию собеседника.
|
||
- Глобальная политика шифрования хранится в `UserDefaults` отдельно для каждого
|
||
JID, а переопределение чата — в локальном SwiftData-хранилище. Эти значения
|
||
не являются секретами, но прямо влияют на конфиденциальность следующей
|
||
отправки.
|
||
- Аватары XEP-0084/vCard не шифруются OMEMO. Их видимость определяется
|
||
настройками PEP и roster на сервере; не используйте аватар как секретное фото.
|
||
- Используемая реализация MartinOMEMO поддерживает распространённый legacy
|
||
namespace. Она не должна называться полной реализацией новой редакции
|
||
XEP-0384 без отдельного interoperability test suite.
|
||
- В открытой или плохо настроенной сторонней MUC списки офлайн-участников могут
|
||
быть недоступны. Для предсказуемого группового OMEMO используйте members-only
|
||
комнату, разрешающую участникам получать affiliation lists; иначе отключите
|
||
OMEMO именно для этой комнаты осознанно.
|
||
- Jailbreak/root, скомпрометированный endpoint и запись экрана находятся вне
|
||
модели угроз MVP.
|