Перейти к основному содержимому

Правила Security Кодирования

Назначение

Документ фиксирует обязательные security-правила для backend разработчиков Pin. Платформа PIN работает с реальными деньгами, PII, регуляторными данными — нарушение security правил имеет прямые финансовые и юридические последствия.

Многоуровневая Авторизация

Каждый запрос проходит три независимых барьера:

  1. Endpoint Policy[Authorize(Policy = "...")] на каждом контроллере/экшене.
  2. MediatR AuthorizationBehavior — проверка IActorContext.HasPermission() для command.
  3. Handler Ownership Check — явная проверка withdrawal.TenantId == actorContext.TenantId.

Ни один барьер не заменяет другой. Endpoint без [Authorize] — это blocker в code review.

Repository scope filters автоматически добавляют tenant_id / brand_id к каждому запросу как четвёртый слой.

Secrets И Credentials

  • Secrets, credentials, API keys, webhook signing keys хранятся в Vault или k8s Secrets.
  • appsettings.json и appsettings.Production.json не содержат реальных secrets.
  • Secrets читаются через IOptions<T> — не через IConfiguration["key"] inline.
  • IOptions конфигурация валидируется при старте через ValidateDataAnnotations().ValidateOnStart().
  • Нет hardcoded strings с паролями, connection strings, token values в коде.

PII И Secrets В Логах

Следующее никогда не попадает в логи:

  • пароли, PIN, секретные ключи, API tokens, webhook secrets;
  • CVV, full PAN, IBAN, bank account numbers;
  • access token, refresh token, session cookie;
  • полные ФИО + дата рождения + адрес в одном log entry;
  • содержимое KYC документов;
  • encryption keys.

Поля, помеченные [Sensitive], автоматически маскируются через SensitiveDataMaskingPolicy.

Structured logging: в лог передаются Id (UserId, WithdrawalId), status, amount — но не имя, email, адрес пользователя.

Input Validation

  • API validator (AbstractValidator<TRequest>) проверяет формат, диапазон, MaxLength, Regex.
  • MediatR validator проверяет бизнес-правила (лимиты, статусы, наличие сущностей).
  • Нет AutoMapper.Map(request, existingEntity) — только явный mapping в command.
  • Строки из user input, используемые в имени файла, санируются через whitelist символов.
  • Загружаемые файлы проверяются по extension whitelist и MaxSize.
  • URL для redirect проверяются по origin whitelist.

SQL Injection

  • Используется EF Core — параметризация автоматическая.
  • Raw SQL через ExecuteSqlRawAsync с конкатенацией строк запрещён.
  • FromSql($"...") с FormattableString — безопасно (compile-time параметризация).
  • Elasticsearch queries строятся через typed builder, не через JSON строки с интерполяцией.

Callback / Webhook Security

  • Каждый payment/provider webhook callback валидируется по HMAC signature перед обработкой.
  • Callback без подписи → 401 Unauthorized + warning log.
  • Idempotency key webhook-а проверяется до бизнес-логики — дубль callback не меняет state.

JWT Tokens

  • ValidateIssuer, ValidateAudience, ValidateLifetime, ValidateIssuerSigningKey — все true.
  • ValidAlgorithms — whitelist разрешённых алгоритмов: ["HS256", "RS256"].
  • ClockSkew — не более 30 секунд.
  • Алгоритм none и HS1 запрещены в TokenValidationParameters.
  • Access token TTL: user 15 мин, admin 8 часов.

Rate Limiting

  • Auth endpoints (login, register, password reset) — strict rate limit per IP.
  • Sensitive operations (withdrawal create, KYC submit, admin approve) — per-actor sliding window.
  • SignalR — не более 10 push/s на пользователя.
  • 429 Too Many Requests возвращается как ProblemDetails, не пустой ответ.

Tenant Isolation

  • Repository scope filters автоматически применяют tenant_id и brand_id.
  • Handler явно проверяет entity.TenantId == actorContext.TenantId для критических операций.
  • Global admin bypass (ScopeOptions.BypassAll) требует explicit permission + audit log.
  • User не может видеть данные другого user или другого tenant.

Чувствительные Операции

Для KYC approve/reject, balance adjustment, withdrawal approve, limit change, PII access обязательно:

  • [Authorize(Policy = AuthorizationPolicies.AdminWithMfa)];
  • [AuditApiAction("event-type")];
  • Explicit permission check в handler;
  • Ownership check в handler;
  • Audit запись с before/after state через AuditDbContext.

Code Review Security Блокеры

Pull request не принимается, если:

  • endpoint без [Authorize] (кроме явно public);
  • handler без ownership check для tenant-scoped entity;
  • secret в appsettings или hardcoded в коде;
  • лог содержит password, token, email + name вместе, PAN, CVV;
  • callback endpoint без HMAC validation;
  • raw SQL с конкатенацией строк;
  • ValidateLifetime = false в JWT config;
  • отсутствует rate limit на auth или sensitive endpoint.

Детальный Справочник

14 — Security Patterns — полное руководство с примерами кода.

Обратные ссылки

Автоссылки: где используется этот документ.