From e510e9309934669099664b527fa28d1f91ac53bc Mon Sep 17 00:00:00 2001 From: Repinoid Date: Sun, 11 Oct 2026 08:49:00 +0300 Subject: [PATCH] =?UTF-8?q?iotpg:=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20namespace=20(safeNamespa?= =?UTF-8?q?ceRe)=20=D0=B2=20getTenantDB=20=D0=BD=D0=B0=20=D0=B2=D1=81?= =?UTF-8?q?=D0=B5=D1=85=20=D0=BF=D1=83=D1=82=D1=8F=D1=85=20=D1=87=D1=82?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F/=D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/storage/iotpg/iot_telemetry_store.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/storage/iotpg/iot_telemetry_store.go b/internal/storage/iotpg/iot_telemetry_store.go index e6a88f9..29e8871 100644 --- a/internal/storage/iotpg/iot_telemetry_store.go +++ b/internal/storage/iotpg/iot_telemetry_store.go @@ -630,6 +630,13 @@ func (s *IoTPostgresStore) Close() error { // Открытие дедуплицируется per-namespace мьютексом (гонка Load→LoadOrStore // из ревью 2026-08-16). func (s *IoTPostgresStore) getTenantDB(ctx context.Context, namespace string) (*sql.DB, error) { + // Валидация namespace на ВСЕХ путях (чтение/запись) — defense-in-depth. + // Основной барьер — валидация при создании устройства, но JWT с sub, + // прошедшим namespace==sub в middleware, не должен читать чужую БД через + // подмену дефисов (a_b ↔ a-b дают одно имя tenant_a_b) — см. tenantDBName. + if !safeNamespaceRe.MatchString(namespace) { + return nil, fmt.Errorf("%w: %q", ErrInvalidNamespace, namespace) + } if cached, ok := s.tenants.Load(namespace); ok { return cached.(*sql.DB), nil }