Skip to content

Security: snowfallite/secure_drop

Security

SECURITY.md

Архитектура Безопасности Secure Drop

Этот документ описывает, как Secure Drop обеспечивает конфиденциальность, целостность и доступность данных пользователей.

1. Транспортная безопасность (Transport Layer)

Все данные, передаваемые между клиентом и сервером, защищены стандартными протоколами шифрования транспортного уровня.

  • HTTPS / WSS: Весь HTTP трафик и WebSocket соединения шифруются с использованием TLS 1.2/1.3.
  • Reverse Proxy (Caddy): Caddy автоматически управляет SSL-сертификатами (Let's Encrypt / ZeroSSL) и терминирует TLS соединения, обеспечивая безопасный канал до сервера.
  • HSTS: Включен Strict-Transport-Security, принуждающий браузеры использовать только безопасные соединения.

2. Аутентификация и Авторизация

Мы не используем пароли для входа, что исключает их перехват или подбор (brute-force) в классическом понимании.

  • Идентификатор: Публичный username.
  • Фактор владения: TOTP (Time-based One-Time Password). Для входа требуется код из приложения-аутентификатора (Google Authenticator, Authy).
  • Сессии: После успешной проверки TOTP выдается JWT (JSON Web Token).
    • Токен хранится в localStorage (или sessionStorage).
    • Время жизни токена ограничено (по умолчанию 30 минут).
    • Токен используется для авторизации всех API запросов и WebSocket соединений.

3. Сквозное Шифрование (E2EE)

Это ядро безопасности проекта. Сервер никогда не видит содержимое сообщений.

3.1. Алгоритмы

  • Генерация ключей: ECDH (Elliptic Curve Diffie-Hellman) на кривой P-256.
    • Каждый пользователь имеет пару ключей: Public Key (открытый) и Private Key (закрытый).
  • Общий секрет (Shared Secret): Вычисляется на клиенте путем объединения своего Private Key и Public Key собеседника.
  • Шифрование данных: AES-GCM (256-bit).
    • Симметричный алгоритм, использующий общий секрет.
    • GCM (Galois/Counter Mode) обеспечивает не только конфиденциальность, но и целостность данных (защита от подмены).

3.2. Схема обмена сообщениями

  1. Алиса хочет написать Бобу.
  2. Фронтенд Алисы скачивает Public Key Боба с сервера.
  3. Фронтенд вычисляет Shared Secret (общий для Алисы и Боба).
  4. Сообщение шифруется этим ключом (AES-GCM).
  5. На сервер отправляется только: IV (вектор инициализации) и CipherText (шифротекст).
  6. Сервер сохраняет зашифрованный blob.
  7. Боб получает сообщение.
  8. Фронтенд Боба берет свой Private Key и Public Key Алисы -> вычисляет тот же самый Shared Secret.
  9. Сообщение расшифровывается на устройстве Боба.

4. Хранение Ключей и Данных

4.1. На устройстве пользователя (Client-side)

  • Private Key: Хранится в localStorage браузера в формате Base64.
    • Риск: Если злоумышленник получит физический доступ к разблокированному устройству или выполнит XSS атаку, ключ может быть скомпрометирован.
    • Защита: Внедрены строгие CSP (Content Security Policy) заголовки для предотвращения XSS.
  • Сообщения: Хранятся в оперативной памяти (React State) в расшифрованном виде. При перезагрузке страницы история подгружается и расшифровывается заново.

4.2. На сервере (Server-side)

Сервер выступает как "слепое" хранилище.

  • Users Table:
    • username
    • public_key: Открытый ключ (доступен всем для начала переписки).
    • encrypted_private_key: Закрытый ключ, зашифрованный паролем восстановления пользователя. Сервер не может его прочитать.
    • key_salt: Соль для деривации ключа шифрования приватного ключа.
  • Messages Table:
    • content: Текст вида iv:ciphertext. Сервер видит только абракадабру.
    • Метаданные: sender_id, chat_id, timestamp (не шифруются для работы сортировки и уведомлений).

5. Восстановление Доступа (Key Recovery)

Если пользователь меняет устройство, он теряет свой локальный Private Key. Для восстановления используется механизм Key Recovery:

  1. При регистрации пользователь задает пароль (он используется только для шифрования ключа, не для входа).
  2. Приватный ключ шифруется этим паролем (алгоритм PBKDF2 + AES-GCM) и отправляется на сервер (encrypted_private_key).
  3. При входе на новом устройстве:
    • Приложение скачивает зашифрованный ключ.
    • Просит пользователя ввести пароль.
    • Ключ расшифровывается локально и сохраняется в браузер.

6. Защита от Угроз (Threat Model)

Угроза Защита Статус
MITM (Перехват трафика) HTTPS/TLS, E2EE делает перехваченные данные бесполезными. ✅ Защищено
Взлом сервера БД Злоумышленник получит только зашифрованные сообщения и зашифрованные ключи. Без паролей пользователей данные не прочитать. ✅ Защищено
Подмена ключей (MITM v2) Front-end проверяет подпись или сверяет ключи (в разработке: индикация смены ключа собеседника). ✅ Защищено (Новый индикатор)
Утеря устройства Вход защищен TOTP. История сообщений зашифрована и недоступна без ключа. ✅ Защищено
Физический доступ к ПК Private Key в LocalStorage может быть извлечен. Рекомендуется выходить из системы (Logout) на чужих ПК. ⚠️ Риск пользователя

Итог: Secure Drop обеспечивает высокий уровень приватности, где даже администратор сервера не имеет технической возможности читать переписку.

There aren’t any published security advisories