После первого релиза DataSafeS3: что мы нашли и починили (v1.0.1, v1.0.2)

от автора

24 июня 2026 вышел v1.0.0 — первый публичный релиз DataSafeS3.

До этого систему в основном крутили мы сами и знакомые: дома, в test, иногда на staging. Production pilot не было — и это важно для контекста.

Как только продукт трогают не только авторы, всплывает другое. Loki оказывается на внутреннем IP. SSO приходит из CI. Возникает вопрос: образ на registry точно наш? Параллельно прогнали security review. Слабые места нашлись — в UI, в исходящих интеграциях, в auth.

v1.0.1 и v1.0.2 — ответ на это. Не «ещё один тег ради тега».

DataSafeS3 — молодой open-source: своё S3-хранилище с веб-консолью, пользователями и аудитом на вашем железе. Мы не MinIO и не пытаемся им быть. Делаем доступный open source для своих сценариев.

Ниже — что сломалось, почему это мешало администратору и что поменяли. Установка и переменные окружения — в upgrade guide RU и EN.


v1.0.1

Два изменения, на которые мы сами наткнулись при установке. Остальное — бантики: контакт в SECURITY.md, правки в project status, compose, Swagger guide.

Проверка релизов

Почти сразу после v1.0.0 главный вопрос оказался не про фичи, а про доверие: кто собрал контейнер и можно ли убедиться, что его не подменили в registry. SBOM и инструкции были, но разбросаны — ответ на «мы точно запускаем своё?» занимал лишнее время.

Без подписи и списка компонентов security-команда или DevOps остаются в режиме «верим на слово». В prod это слабая стратегия.

Теперь к каждому GitHub Release крепятся SBOM для storage-server и console. Образы подписываются при сборке. В руководстве администратора — пошаговая проверка (EN/RU). Менять ничего не нужно; если проверяете образы перед деплоем, стало проще. Примеры: onboarding, security hardening.

Страница Buckets

В одном сценарии ошибка API давала странный эффект: список bucket’ов становился пустым. Для администратора это выглядело так, будто данные исчезли. При создании bucket любая серверная ошибка могла отображаться как «имя уже занято» (HTTP 409) — хотя причина была в Postgres, правах или временном сбое.

Консоль теперь показывает текст ошибки от API. 409 — только при реальном конфликте имени.

Список buckets в консоли

Список buckets в консоли

v1.0.2

После внутреннего security review список находок оказался длиннее, чем хотелось бы: SSRF, JWT в URL после SSO, открытый CORS, login без лимита, слабые имена объектов S3, дефолтные секреты в шаблонах. Всё закрыто в Community Edition, без платных фич.

Три темы: сеть, аутентификация, безопасность хранения.

Защита сети

SSRF через исходящие интеграции

Webhooks, Loki, Elasticsearch, уведомления по bucket’ам и «Test hook» в админке делают HTTP-запросы наружу. Это удобно — пока в URL не попадает внутренний адрес. Тогда storage-server ходит по вашей сети от своего имени.

На review мы как раз на этом и споткнулись: без общих правил админка превращается в неожиданный прокси. Один webhook — и сервер стучится в cloud metadata или соседний сервис.

Теперь действует единая политика исходящих адресов. В production по умолчанию — только публичный HTTPS; локальные и внутренние адреса блокируются.

Если Loki или webhook ходят на http://10.x.x.x или localhost, после апгрейда запросы могут перестать уходить. Переведите sink на HTTPS или включите временный override — в upgrade guide. Для lab — dev-режим в доке.

CORS

В некоторых конфигурациях CORS был слишком открыт: фактически любой origin с credentials. Теоретически чужой сайт мог дергать API от имени залогиненного пользователя.

Список разрешённых origins теперь задаётся явно — через переменную окружения, см. документацию. Перед выкатом в prod укажите домены вашей консоли.


Аутентификация

OIDC и SSO

После входа через IdP JWT попадал в адресную строку (?token=...). Дальше — history, закладки, Referer, логи прокси. Session token в URL утекает через самые обычные каналы.

IdP теперь возвращает одноразовый код; консоль меняет его на сессию отдельным запросом. JWT в URL больше не передаётся.

Настройки IdP (redirect URI) менять не нужно. Закладки со старым ?token= перестанут работать — так и задумано. Подробности: upgrade guide RU.

Brute-force на login

Логин можно было перебивать без ограничений. Добавили лимит по IP — порядка десяти попыток в минуту по умолчанию, настраивается в env.

Если CI часто логинится и ловит 429 — поднимите лимит или добавьте паузу между попытками (upgrade guide EN).

LDAP, MFA и OIDC password-login

Можно было указать незашифрованный LDAP (ldap://); ключ MFA по умолчанию совпадал с JWT. Устаревший OIDC password-login (ROPC) был включён по умолчанию.

LDAPS и отдельный ключ MFA — через env, если ужесточаете политику (security self-assessment RU). ROPC выключен по умолчанию; если пользовались — см. upgrade guide.


Безопасность хранения

Имена объектов S3

Ключи с path traversal (../../...) или управляющими символами проходили на запись и чтение. Ломается логика префиксов, бэкапов и Object Lock — когда объект нельзя удалить по retention.

Такие ключи теперь отклоняются с 400.

Секреты

Дефолтные пароли из .env.example легко уезжали в production. Проверить «всё ли сменили» до выката было неудобно — первый pentest находил admin/admin и известный JWT secret.

Появился API security-status для слабых переменных окружения, подсказки в Helm для production, режим strict secrets — сервер не стартует с дефолтами. Перед prod смените JWT secret, S3 secret key и admin password (onboarding).

Зависимости сборки

Go 1.26.4; в CI — проверка известных уязвимостей в зависимостях. Для администратора это просто новые образы v1.0.2.


Обновление: один чеклист

Что проверить

Зачем

Storage-server и console на v1.0.2

Иначе SSO и часть UI разъедутся

URL Loki / webhooks / ES

SSRF-политика может их заблокировать

Секреты и CORS origins

Pre-flight перед prod

CI с частым login

Возможен 429

На v1.0.0 — сразу на v1.0.2. Полный список: CHANGELOG 1.0.1 · 1.0.2. Advisory: SECURITY.md v1.0.2.


Что сознательно не в этих патчах

  • Метрики Prometheus по HTTP без логина — закройте firewall’ом или прокси; в v1.1.0 — guard или жёсткая дока.

  • Временный override для HTTP-sink’ов — костыль на переход; следите за v1.1.0.

  • Teams в UI — пока только API.

  • Все security-фиксы — в бесплатной CE, без Enterprise-gate.


Итог

DataSafeS3 всё ещё молодой. v1.0.1 добавил проверяемые релизы и честные ошибки в UI. v1.0.2 закрыл SSRF, утечку токена после SSO, brute-force на login, CORS, имена объектов и секреты. Список выше — то, что сознательно отложили.

Цель — open source, который можно ставить не только автору проекта. v1.0.1 и v1.0.2 — шаг к этому, не финал. Дальше тот же режим: обратная связь → review → патч.

Доступный open source, за который не стыдно администратору. И не не только.

Если после апгрейда что-то ведёт себя не так — GitHub Issues. Уязвимости — SECURITY.md.


Автор: Илья Трачук — разработчик DataSafeS3

Теги s3, selfhosted, opensource, devops, информационнаябезопасность, ldap, objectstorage, datasafes3,datasafe,DirektorBani,releases

ссылка на оригинал статьи https://habr.com/ru/articles/1053082/