Безопасность
Кто и к чему имеет доступ, как это проверяется и что остаётся на стороне развёртывания.
Кратко
Каждый токен действует только в своём бакете. В базе хранится его хеш, а не значение.
При включённой панели управляющий API отвечает только самой панели внутри контейнера.
Пять неудачных входов за 15 минут — и адрес блокируется на 5 минут.
Временные ссылки подписаны ключом сервера: подделать или продлить их нельзя.
Токены доступа
- Токен выпускается для одного бакета и даёт доступ только к нему.
- В базе хранится хеш токена. Само значение показывается один раз, при выпуске; восстановить его нельзя — только перевыпустить.
- Два уровня:
BASIC(только проверка и скачивание по токену) иFULL(всё). ВыдавайтеBASICтем, кому нужно только читать. - Токен можно ограничить сроком, отключить или перевыпустить (ротация). После ротации старое значение перестаёт работать сразу.
- При каждом запросе проверяется: токен известен, активен, не истёк и его уровня
хватает. Ответы —
401(нет токена или он неизвестен) и403(отключён, истёк, мало прав).
Вход в админ-панель
Учётная запись одна, она задаётся переменными ADMIN_LOGIN и ADMIN_PASSWORD.
- Без них вход закрыт полностью. Это сделано намеренно: панель без учётных данных не открывается никому, а не всем.
- Сессия живёт 24 часа. Она хранится в куке
s5w_adminс флагамиHttpOnlyиSameSite=Strict: скрипт на странице её не прочитает, а другой сайт не сможет отправить запрос от имени администратора. - Сессия подписана ключом
WINTER_KEYи привязана к логину и паролю. Смена пароля или ключа сразу завершает все открытые сессии. - Блокировка перебора. Пять неудачных входов с одного адреса за 15 минут
блокируют этот адрес на 5 минут: вход отвечает
429с заголовкомRetry-After, даже с правильным паролем. Счётчик хранится в памяти и сбрасывается при перезапуске. - Адрес клиента за прокси берётся из
X-Forwarded-For, но только от доверенных прокси (TRUSTED_PROXIES). Иначе любой мог бы прислать чужой адрес и обойти блокировку.
Пароль по умолчанию
В примерах стоит change-me. В рабочем развёртывании задайте длинный случайный пароль
и храните его как секрет, а не в открытом compose-файле в репозитории.
Admin API
Управляющий API /admin/… создаёт бакеты, токены и всё остальное — это полный доступ
к хранилищу.
- С включённой панелью (по умолчанию) он принимает запросы только изнутри
контейнера, то есть от самой панели. Снаружи —
404, как будто его нет. ADMIN_API=publicоткрывает его наружу — например, для скриптов автоматизации. Тогда закройте порт9090или путь/adminна прокси для всех, кроме нужных адресов.- Без панели (
ADMIN_UI=false) он открыт по умолчанию — иначе бакетами было бы нечем управлять. Закройте/adminна уровне сети.
Публичность файлов
Файл либо публичный, либо нет; это определяется папкой.
- Корень бакета всегда публичный. Файл, загруженный или перенесённый туда,
открывается по
/o/{bucketId}/{id}без токена. - Файл в папке получает видимость папки. При переносе между папками видимость меняется на видимость новой папки.
- Публичный адрес содержит идентификатор бакета и случайный идентификатор файла (96 бит случайности) — его нельзя угадать перебором. Но кто получил ссылку, тот может её передать.
Перенос в корень
Приватный документ, перенесённый в корень, становится доступен всем, у кого есть адрес. Держите закрытые файлы в приватных папках.
Временные ссылки
- Ссылка подписана ключом
WINTER_KEY: срок, файл и параметры зашиты в подпись, изменить их нельзя. - Учитываемую ссылку (
revocableилиmaxDownloads) можно отозвать по одной. - Все ссылки бакета, включая подписанные, отзываются одним запросом
DELETE /v1/linksили кнопкой в панели. - Смена
WINTER_KEYделает недействительными все временные ссылки во всех бакетах.
Загруженное содержимое
- HTML и SVG никогда не открываются в браузере — только скачиваются. Показанные браузером, они могли бы выполнить скрипт от имени вашего домена.
- В браузере открываются только картинки, видео, аудио, PDF и простой текст; всё остальное отдаётся на скачивание.
- Имя файла очищается: разделители путей и управляющие символы заменяются на
-. В заголовокContent-Dispositionимя попадает экранированным, подставить через него лишний заголовок нельзя. - На диск содержимое попадает под именем-хешем: имя от клиента не участвует в путях.
Что остаётся на развёртывании
- TLS. Сам S5W говорит по HTTP. Шифрование делает прокси перед ним — nginx-proxy-manager, traefik, nginx.
- Сетевой доступ. Не публикуйте порты, которые не нужны. Домен панели стоит дополнительно закрыть списком доступа или basic auth.
- Секреты.
ADMIN_PASSWORDи, если вы задаёте его сами,WINTER_KEY— храните как секреты. - Резервные копии тома — они содержат все файлы и ключ подписи, защищайте их так же, как сами данные.