iotpg: валидировать namespace (safeNamespaceRe) в getTenantDB на всех путях чтения/записи

This commit is contained in:
Repinoid
2026-10-11 08:49:00 +03:00
parent 4c1b9b7b9e
commit e510e93099
@@ -630,6 +630,13 @@ func (s *IoTPostgresStore) Close() error {
// Открытие дедуплицируется per-namespace мьютексом (гонка Load→LoadOrStore // Открытие дедуплицируется per-namespace мьютексом (гонка Load→LoadOrStore
// из ревью 2026-08-16). // из ревью 2026-08-16).
func (s *IoTPostgresStore) getTenantDB(ctx context.Context, namespace string) (*sql.DB, error) { 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 { if cached, ok := s.tenants.Load(namespace); ok {
return cached.(*sql.DB), nil return cached.(*sql.DB), nil
} }