Перейти к содержанию

PT Sandbox — интеграция с антивирусной песочницей

Обзор

PT Sandbox (Positive Technologies Sandbox) — внешняя антивирусная песочница, которая проверяет файлы перед их сохранением в хранилище 1Формы. Интеграция выполняет перехват загрузки файлов на уровне FileProviders.UploadFile и блокирует вредоносные файлы до записи в БД/хранилище.

Версия API PT Sandbox: v5.7 (/api/v1).


Точка интеграции в коде

Проверка вызывается в одном месте:

TCClassLib/Files/Providers/FileProviders.cs:347

PTSandboxScanService?.EnsureFileIsSafe(content, name);
// Вызывается ПЕРЕД записью файла в хранилище
var provider = GetFileProvider(fileProviderId);

Все загрузки файлов через стандартный механизм 1Формы автоматически проходят через PT Sandbox, если сервис настроен и включён.


Архитектура

Слои

Слой Класс Описание
Интерфейс сервиса IPTSandboxScanService Публичный контракт
Реализация PTSandboxScanService Полный цикл проверки
HTTP-клиент (интерфейс) IPTSandboxApiClient Контракт к API PT Sandbox
HTTP-клиент (реализация) PTSandboxApiClient Двухшаговый вызов REST API
Конфигурация PTSandboxExternalServicesConfigurationService CRUD настроек через Admin API

Поток проверки файла (EnsureFileIsSafe)

FileProviders.UploadFile
  └─ EnsureFileIsSafe(content, fileName)
       ├─ Получить активные настройки (IsEnabled = true)
       ├─ Если не настроен → пропустить
       ├─ ScanFileInternalAsync
       │    ├─ Фильтр по расширению (ExtensionFilterMode)
       │    ├─ Фильтр по домену (DomainFilterMode)
       │    ├─ Проверка размера (MaxFileSizeBytes / OversizeFileAction)
       │    ├─ SHA-256 хеш → поиск в кеше PTSandboxFileScans (TTL 24ч)
       │    ├─ Если кеш Threat → PTSandboxThreatException
       │    ├─ Если кеш Clean → вернуть без вызова API
       │    ├─ [Опционально] Создать запись PTSandboxFileScans (IsLoggingEnabled)
       │    ├─ PTSandboxApiClient.UploadFileAsync → POST /api/v1/storage/uploadScanFile
       │    ├─ PTSandboxApiClient.CreateScanTaskAsync → POST /api/v1/analysis/createScanTask
       │    └─ Результат: Clean / Threat / Unknown
       └─ По результату:
            ├─ Threat → throw TCLogicException (HTTP 400 для пользователя)
            ├─ Oversize + Block → throw TCLogicException
            ├─ Unavailable + Block → throw TCLogicException
            └─ Clean / Skip → продолжить загрузку

API PT Sandbox (внешние вызовы)

Авторизация: заголовок X-API-Key: {accessToken}.

Этап 1 — загрузка файла

POST {ApiUrl}/api/v1/storage/uploadScanFile
Content-Type: multipart/form-data
X-API-Key: {token}

form-data: file = <binary>

Ответ:
{
  "data": {
    "file_uri": "sfm-files:///...",
    "ttl": 3600
  },
  "errors": []
}

Этап 2 — запуск проверки (синхронный режим)

POST {ApiUrl}/api/v1/analysis/createScanTask
Content-Type: application/json
X-API-Key: {token}

{
  "file_uri": "sfm-files:///...",
  "file_name": "document.docx",
  "short_result": false,
  "async_result": false,
  "options": {
    "mark_suspicious_files_options": { ... },  // из MarkSuspiciousOptionsJson; отсутствует, если поле null
    "sandbox": { ... }                          // из SandboxOptionsJson; отсутствует, если поле null
  }
}

Ответ:
{
  "data": {
    "scan_id": "uuid",
    "result": {
      "verdict": "DANGEROUS" | "CLEAN",
      "threat": "TrojanName",
      "duration": 12.5
    },
    "artifacts": [
      {
        "engine_results": [
          {
            "detections": [
              { "detect": "Trojan.Win32.Example" }
            ]
          }
        ]
      }
    ]
  },
  "errors": []
}

Этап 3 — проверка статуса (асинхронный режим)

POST {ApiUrl}/api/v1/analysis/checkTask
Content-Type: application/json
X-API-Key: {token}

{ "scan_id": "uuid" }

Текущая реализация использует синхронный режим (async_result=false) — ждёт вердикт в рамках одного HTTP-запроса до ScanTimeoutSeconds.


Настройка (AdminSPA)

Настройки управляются через стандартный механизм внешних сервисов (ServiceType.PTSandbox).

Admin API эндпоинты

Метод URL Описание
POST /api/services Создать конфигурацию PT Sandbox
POST /api/services/settings Сохранить настройки
GET /api/services/settings/{settingsId} Получить настройки по ID
DELETE /api/services Удалить конфигурацию
GET /api/admin/services/custom/{serviceType} Список всех конфигураций PT Sandbox

Все эндпоинты требуют прав администратора (CheckAdminRights()).

Параметры конфигурации (PTSandboxServiceSettingsDto)

Поле Тип По умолчанию Описание
ApiUrl string Базовый URL API, например https://sandbox.corp.local/api/v1
AccessToken string Токен X-API-Key. Хранится в зашифрованном виде.
IgnoreSslErrors bool false Игнорировать ошибки SSL (для самоподписанных сертификатов)
IsEnabled bool false Включена ли проверка
ScanTimeoutSeconds int 300 Таймаут ожидания вердикта (секунды)
MaxFileSizeBytes long 1 073 741 824 (1 ГБ) Максимальный размер файла для проверки
OversizeFileAction enum Block Действие при превышении размера: Skip / Block
ExtensionFilterMode enum ExcludeList Режим фильтрации по расширению
FileExtensionsToScan string Расширения для проверки (ScanList режим, через запятую без точки)
FileExtensionsToExclude string Расширения для исключения (ExcludeList режим)
DomainFilterMode enum ExcludeList Режим фильтрации по домену
DomainIds int[] Список ID доменов (интерпретация зависит от DomainFilterMode)
FailPolicy enum Block Действие при недоступности PT Sandbox: Skip / Block
IsLoggingEnabled bool false Сохранять результаты в PTSandboxFileScans
FileActionsLogMode enum None Запись в FileActionsLog: None / BlockOnly / All
MarkSuspiciousOptionsJson string (JSON) null JSON-объект с флагами пометки подозрительных файлов (блок mark_suspicious_files_options). При null — блок не передаётся, PT применяет дефолты (все флаги = true). Подробнее: раздел ниже
SandboxOptionsJson string (JSON) null JSON-объект настроек поведенческого анализа (блок sandbox). Ключевое поле — Enabled (включить/выключить запуск в ВМ). При null — блок не передаётся, PT применяет дефолты (поведенческий анализ включён). Подробнее: раздел ниже

Логика фильтрации

Фильтр по расширению

ExtensionFilterMode Логика
ExcludeList (по умолчанию) Проверяются все файлы, кроме расширений из FileExtensionsToExclude. Пустой список = проверять все.
ScanList Проверяются только расширения из FileExtensionsToScan. Пустой список = не проверять ничего.

Фильтр по домену

DomainFilterMode Логика
ExcludeList (по умолчанию) Проверяются все домены, кроме из списка DomainIds. Пустой список = проверять для всех.
IncludeList Проверяются только домены из DomainIds. Пустой список = не проверять вообще.

Домен определяется по Request.Host.Host → поиск в таблице Domains.Url.


Кеш вердиктов (дедупликация)

SHA-256 хеш файла используется для поиска предыдущих результатов проверки в таблице PTSandboxFileScans.

  • TTL кеша: 24 часа
  • Clean: возвращается из кеша без вызова API (если моложе 24 ч)
  • Threat: всегда возвращается из кеша без повторной проверки (навсегда)
  • Unknown: не кешируется, каждый раз проверяется заново

Таблицы БД

PTSandboxServiceSettings

Настройки конкретной конфигурации PT Sandbox. Связана с ServiceSettings (один к одному).

Колонка Тип Описание
ServiceId (PK/FK) int FK → ServiceSettings.Id
ApiUrl nvarchar Базовый URL API
AccessToken nvarchar Зашифрованный токен
IgnoreSslErrorsF bit Игнорировать SSL
IsEnabled bit Включена ли интеграция
ScanTimeoutSeconds int Таймаут (сек)
MaxFileSizeBytes bigint Максимальный размер (байты)
OversizeFileAction int 0=Skip, 1=Block
ExtensionFilterMode int 0=ExcludeList, 1=ScanList
FileExtensionsToScan nvarchar Null
FileExtensionsToExclude nvarchar Null
DomainFilterMode int 0=ExcludeList, 1=IncludeList
FailPolicy int 0=Skip, 1=Block
IsLoggingEnabled bit Включить лог проверок
FileActionsLogMode int 0=None, 1=BlockOnly, 2=All
MarkSuspiciousOptionsJson nvarchar(max) / text JSON-опции пометки подозрительных файлов (v2.267+)
SandboxOptionsJson nvarchar(max) / text JSON-опции поведенческого анализа в ВМ (v2.267+)

PTSandboxDomainSettings

Список доменов для фильтрации. FK → PTSandboxServiceSettings.ServiceId и Domains.Id.

Колонка Описание
ServiceId FK → PTSandboxServiceSettings
DomainId FK → Domains

PTSandboxFileScans

Журнал результатов проверок (заполняется при IsLoggingEnabled = true).

Колонка Тип Описание
Id int PK
FileHash binary(32) SHA-256 хеш содержимого
FileName nvarchar Имя файла
FileSize bigint Размер в байтах
UploadUserId int Пользователь, загрузивший файл
DomainId int? Домен загрузки
SandboxTaskGuid uniqueidentifier? ID задания в PT Sandbox
Verdict int 0=Clean, 1=Threat, 2=Unknown, 3=Skipped
VerdictDetails nvarchar JSON-ответ от PT Sandbox (угрозы, метаданные)
ScanRequestedAt datetime Время начала проверки
ScanCompletedAt datetime? Время завершения
ScanDurationMs int? Длительность (мс)
ServiceId int FK → PTSandboxServiceSettings.ServiceId

FileActionsLog

При FileActionsLogMode != None — записи с типами: - PTSandboxSkipped — файл пропущен фильтром - PTSandboxClean — проверен, угроз нет (только при All) - PTSandboxBlocked — заблокирован (угроза / oversize / unavailable)


Исключения и коды ошибок

Исключение Когда Что видит пользователь
PTSandboxThreatException Обнаружена угроза TCLogicException: "В файле {name} обнаружена угроза: {threats}"
PTSandboxOversizeException Файл > MaxFileSizeBytes и OversizeFileAction=Block TCLogicException: "Файл {name} превышает..."
PTSandboxUnavailableException Сервис недоступен и FailPolicy=Block TCLogicException: "Сервис недоступен: {reason}"

При FailPolicy=Skip сервис недоступен — загрузка продолжается, в лог пишется PTSandboxBlocked.


Enums

PTSandboxVerdict

Значение Описание
Clean = 0 Угроз нет
Threat = 1 Обнаружена угроза
Unknown = 2 Проверка не завершена (таймаут, ошибка)
Skipped = 3 Пропущен фильтром

PTSandboxFailPolicy

Значение Описание
Skip = 0 Разрешить загрузку при сбое (приоритет доступности)
Block = 1 Блокировать при сбое (приоритет безопасности)

PTSandboxOversizeFileAction

Значение Описание
Skip = 0 Пропустить проверку, загрузить без сканирования
Block = 1 Заблокировать загрузку

PTSandboxExtensionFilterMode

Значение Описание
ExcludeList = 0 Исключить перечисленные расширения
ScanList = 1 Проверять только перечисленные расширения

PTSandboxDomainFilterMode

Значение Описание
ExcludeList = 0 Исключить перечисленные домены
IncludeList = 1 Проверять только перечисленные домены

PTSandboxFileActionsLogMode

Значение Описание
None = 0 Не писать в FileActionsLog
BlockOnly = 1 Только блокировки
All = 2 Блокировки + успешные проверки

Расширенные опции сканирования (v2.267+)

Два JSON-поля в PTSandboxServiceSettings, добавленные в v2.267. При сохранении проходят валидацию — невалидный JSON отклоняется с локализованной ошибкой. При null соответствующий блок не передаётся в PT Sandbox и сервер применяет собственные дефолты.

MarkSuspiciousOptionsJson — пометка подозрительных файлов

Управляет блоком mark_suspicious_files_options. C#-DTO: PTSandboxSuspiciousFilesOptionsDto.

Поле Тип Дефолт Описание
EncryptedNotUnpacked bool true Помечать зашифрованные архивы, которые нельзя распаковать для анализа
MaxDepthExceeded bool true Помечать файлы с превышением глубины распаковки вложенных архивов (защита от zip-bomb)
OfficeEncrypted bool true Помечать зашифрованные документы Office (содержимое не проверяется)
OfficeHasMacros bool true Помечать Office-файлы с макросами VBA
OfficeHasEmbedded bool true Помечать Office со встроенными OLE-объектами
OfficeHasActiveX bool true Помечать Office с ActiveX-элементами
OfficeHasDde bool true Помечать Office с DDE-полями (Dynamic Data Exchange)
OfficeHasRemoteData bool true Помечать Office, подгружающий данные с удалённых ресурсов при открытии
OfficeHasRemoteTemplate bool true Помечать Office со ссылкой на удалённый шаблон (template injection)
OfficeHasAction bool true Помечать Office с автодействиями при открытии/закрытии (AutoOpen, Document_Open и др.)
PdfEncrypted bool true Помечать зашифрованные PDF
PdfHasEmbedded bool true Помечать PDF со встроенными файлами
PdfHasOpenAction bool true Помечать PDF с действием OpenAction, выполняющимся при открытии
PdfHasAction bool true Помечать PDF с любыми триггерными действиями
PdfHasJavascript bool true Помечать PDF, содержащий JavaScript
PdfProtected bool true Помечать PDF с ограничениями (запрет печати/копирования/редактирования)

Граничные случаи: - null в БД → блок не передаётся, PT применяет дефолты (все 16 = true). Поведение до v2.267 сохраняется. - Частичный JSON → отсутствующие поля заполняются дефолтами DTO (все true).

SandboxOptionsJson — параметры поведенческого анализа

Управляет блоком sandbox. C#-DTO: PTSandboxSandboxOptionsDto.

Поле Тип Дефолт Описание
Enabled bool true Включает поведенческий анализ (запуск в ВМ). При false — только статический анализ (быстрее, но ниже детектирование неизвестных угроз)
ImageId string Идентификатор образа ВМ: win7-sp1-x64, win10-1607-x64, astra-1.7-x64 и др. Доступные образы зависят от инсталляции PT. Обязательно если Enabled = true
AnalysisDuration int 120 Длительность поведенческого анализа (секунды, минимум 10). Рекомендации PT: 120 для офисных документов, 300+ для EXE
Bootkitmon bool false Режим анализа загрузочных модулей (буткиты/руткиты). Виртуалка перезагружается с инструментом мониторинга ранней стадии инициализации
AnalysisDurationBootkitmon int 60 Длительность bootkitmon-анализа (секунды, минимум 10). Применяется только при Bootkitmon = true
SaveVideo bool false Сохранять видеозапись экрана ВМ во время анализа (для отладки ложных срабатываний)
MitmEnabled bool false MITM-расшифровка HTTPS-трафика ВМ для анализа C2-коммуникаций malware
CustomCommand string? null Команда запуска файла в ВМ. Маркер {file} заменяется путём к файлу. При null PT использует дефолтный обработчик по типу
FileTypes string[]? null Явный список групп файлов для поведенческого анализа (executable-files/, adobe-acrobat/, microsoft-office/). При null PT определяет тип автоматически

Граничные случаи: - null в БД → блок не передаётся, PT применяет дефолты (поведенческий анализ включён). - Чтобы отключить поведенческий анализ — передать объект с Enabled: false, а не null всего поля. - Минимально валидный объект: Enabled + ImageId (если Enabled = true).


Ключевые файлы кода

Файл Назначение
Valhalla.Interfaces/PTSandbox/IPTSandboxScanService.cs Интерфейс сервиса
Valhalla.Interfaces/PTSandbox/IPTSandboxApiClient.cs Интерфейс HTTP-клиента
Valhalla.ExternalServices/PTSandbox/PTSandboxScanService.cs Реализация (фильтрация, кеш, API, лог)
Valhalla.ExternalServices/PTSandbox/PTSandboxApiClient.cs HTTP-клиент к PT Sandbox API v5.7
Valhalla.ExternalServices/Configuration/PTSandboxExternalServicesConfigurationService.cs Конфигурация через Admin API
TCClassLib/Files/Providers/FileProviders.cs:347 Точка вызова (EnsureFileIsSafe)
TCDataAccess/Kernel/Domain/Entities/PTSandbox/PTSandboxServiceSettingsEntity.cs ORM-сущность настроек
TCDataAccess/Kernel/Domain/Entities/PTSandbox/PTSandboxFileScanEntity.cs ORM-сущность журнала проверок
UniForm/Uniform.Admin.Api/Controllers/Services/ServicesSettingsController.cs Admin API контроллер