Software Integrity глазами Security Director ИЛИ размышления о том как искать backdoors и недекларированные возможности (НДВ в терминологии ФСБ и ФСТЭК РФ), проверять source → build → binary → update chain и снижать риск скрытого поведения в критичном коммерческом ПО
Проблема гораздо старше DevSecOps и серьезнее чем просто AppSec
Во времена, когда software supply chain ещё не называли supply chain (лет так 15 назад, а то и более), государства уже задавались тем же вопросом: можно ли доверять устройству, если его спроектировал, изготовил или обновляет кто-то другой?
Хороший исторический пример — швейцарская Crypto AG. Расследование, опубликованное в 2020 году, показало, что компания десятилетиями поставляла криптографическое оборудование множеству государств, при этом CIA и западногерманская разведка тайно контролировали производителя и могли использовать ослабленные системы для чтения защищённых коммуникаций. Документы указывали, что оборудование Crypto AG использовали более 120 стран. The Washington Post — The intelligence coup of the century
Это не AppSec в современном смысле термина и тем более не DevSecOps. Там не было pull request, SAST gate или SBOM. Однако, внимание, фундаментальная проблема была той же:
Trust in the supplier becomes trust in the product.
В 1984 году Ken Thompson в знаменитой лекции Reflections on Trusting Trust показал ещё более неприятную версию той же идеи: даже чистый source code не гарантирует чистый binary, если компилятор или toolchain уже скомпрометирован. Его короткая фраза до сих пор звучит современно: “You can't trust code that you did not totally create yourself.” ACM — Reflections on Trusting Trust
А проблема аппаратного доверия никуда не исчезла после холодной войны (70-е и 80-е годы технологического противостояния США и Великого СССР). DARPA, например, запускала программу TRUST in Integrated Circuits именно для разработки методов обнаружения malicious circuits в микросхемах, спроектированных или произведённых в недоверенной среде. DARPA — TRUST
Сегодня тот же вопрос пришёл в коммерческий Product Security.
Возьмём не военный объект, а обычный enterprise product:
- core banking platform;
- payment switch;
- electronic trading platform;
- database engine;
- IAM/IdP;
- HSM management software;
- EDR или network appliance;
- industrial control software;
- SaaS agent с privileged access на тысячи endpoints.
Такие продукты работают с PII, ключами, платёжными инструкциями, order books, privileged credentials и customer data. Они автоматически обновляются, получают remote configuration, загружают plugins, телеметрию и policy. И очень часто один vendor binary получает доверие на тысячи или миллионы систем.
Обычный Product Security задаёт знакомый вопрос:
Можно ли похэкать наш продукт из-за ошибки\бага?
Для этого у нас есть SAST, DAST, SCA, secret scanning, threat modeling, fuzzing, IaC scanning, container security и API testing. Все ОК! Да!
Но Software Integrity задаёт другой вопрос:
А что если опасное поведение — не ошибка? Что если оно было добавлено намеренно или появилось в source, dependency, build process, release artifact, firmware или update channel?
NIST SP 800-161 Rev. 1 формулирует этот риск буквально как возможность того, что приобретаемые продукты и сервисы могут содержать “potentially malicious functionality.” NIST SP 800-161 Rev. 1
Именно поэтому я рассматриваю эту задачу не как «ещё один scanner», а как отдельный, ВНИМАНИЕ, отдельный assurance track внутри трека Product Security:
SOFTWARE INTEGRITY & MALICIOUS FUNCTIONALITY ASSURANCE
Для меня он должен отвечать на четыре вопроса:
- Что продукту вообще разрешено делать?
- Соответствует ли проверенный source тому artifact, который реально получил клиент?
- Что shipping binary действительно делает во время выполнения?
- Что произойдёт, если vendor, update channel или control plane окажется hostile?
Если ответы на эти вопросы доказуемы, разговор о backdoors (НДВ в терминологии ФСТЭК) перестаёт быть конспирологией и становится обычной инженерией доверия.
Что я называю backdoor или недекларированной возможностью
Терминология здесь неидеальна. Backdoor обычно означает механизм, позволяющий обойти нормальные security controls или получить скрытый доступ. Но реальный класс проблем шире.
MITRE CWE использует, например:
- CWE-506 — Embedded Malicious Code
- CWE-510 — Trapdoor
CWE-506 описывает продукт, содержащий код, который выглядит вредоносным по своей природе. MITRE CWE-506
На практике я разделяю потенциально недекларированное поведение как минимум на несколько типов. Смотрим внимательно! Товарищ майор на экзамене будет спрашивать :)
| Тип | Пример |
|---|---|
| Hidden authentication bypass | специальный token/header/credential открывает административный доступ |
| Logic bomb | функция активируется по дате, hostname, license ID или другому триггеру |
| Remote kill switch | удалённая конфигурация может отключить критическую функцию |
| Undocumented admin/debug interface | скрытый API, port, command или maintenance account |
| Covert data exfiltration | данные отправляются на endpoint, которого нет в архитектуре продукта |
| Build-time injection | source repository чистый, payload добавляется при сборке |
| Malicious dependency | вредоносная логика приходит из npm/PyPI/Maven/Go module и т.д. |
| Binary-only modification | shipping artifact содержит код, отсутствующий в проверенном source |
| Malicious update | легитимный update channel доставляет вредоносную версию |
| Firmware implant | поведение находится ниже OS/app layer: UEFI, BMC, controller firmware и т.п. |
Важно отделять намеренный backdoor от просто плохого дизайна. Например, undocumented maintenance endpoint может быть создан инженером для поддержки и не иметь злого умысла. Но с точки зрения Product Security результат может быть практически тем же: появляется привилегированный путь, который не учитывался в threat model.
Intent сложнее доказать, чем capability.
Поэтому на практике я предпочитаю начинать не с вопроса «кто это сделал и зачем?», а с более инженерного:
Какие security-sensitive capabilities существуют в продукте, какие из них задекларированы и какие доказательства у нас есть, что shipping artifact соответствует ожидаемому поведению?
Почему классика в виде SAST и DAST не решают эту задачу
SAST отлично ищет классы ошибок:
- injection;
- path traversal;
- insecure deserialization;
- memory corruption;
- SSRF;
- broken crypto;
- unsafe API usage.
Но backdoor может быть идеально корректным кодом.
Условный пример:
def authorize(request, user):
if normal_policy_allows(user, request):
return True
if feature_flags.get("emergency_support_mode") and \
request.headers.get("X-Support-Token") == SECRET_VALUE:
return True
return False
Здесь может не быть ни SQL injection, ни buffer overflow. С точки зрения компилятора и SAST всё прекрасно. Проблема в другом: должна ли такая capability вообще существовать?
DAST сталкивается с другой проблемой — trigger space. Если скрытая функция активируется только когда одновременно выполняются условия:
date > X
AND region == Y
AND hostname hash == Z
AND remote configuration contains flag Q
обычный dynamic scan может никогда не попасть в нужное состояние. Есть ещё три распространённых заблуждения.
Code signing не означает, что код безопасен
Подпись отвечает примерно на вопрос:
«Этот artifact действительно подписан ожидаемой identity».
Она не отвечает на вопрос:
«Эта identity не подписала вредоносный artifact».
Authenticity и benignness — разные свойства.
SBOM не доказывает отсутствие backdoor
SBOM отвечает:
«Что входит в продукт?»
Это критически важно, но SBOM сам по себе не говорит:
«Поведение всех этих компонентов безопасно и соответствует спецификации».
Проверка source не доказывает, что именно этот source попал клиенту
Между Git commit и product-7.4.1.tar.gz находятся:
- CI runner;
- compiler;
- build scripts;
- package manager;
- artifact repository;
- signing system;
- release automation.
И любой из этих элементов может стать точкой внедрения.
Семь кейсов: одна проблема, разные точки внедрения
Теория полезна, но реальные incident patterns намного лучше объясняют, зачем нужен отдельный Software Integrity track.
1. Crypto AG: доверие к поставщику как часть модели угроз
Crypto AG — исторический, но очень чистый пример. Пользователь покупал security product именно потому, что доверял его криптографической функции. Если сам поставщик или его design process находится под чужим контролем, обычная проверка эксплуатации продукта не отвечает на главный вопрос: соответствует ли заявленная security property реальной?
Урок: vendor trust — это security dependency.
2. M.E.Doc / NotPetya: финансовое приложение как канал доставки
В июне 2017 года Microsoft сообщила, что первоначальная доставка Petya/NotPetya шла через update service украинского финансового приложения M.E.Doc. Microsoft MSRC — Update on Petya malware attacks
Для банковского или финансового threat model это особенно наглядно: бухгалтерское/финансовое ПО само по себе может быть trusted business dependency, но его update mechanism становится privileged distribution channel внутри customer network.
Урок: secure application + insecure update chain = insecure product.
3. CCleaner: valid signature не означает benign artifact
В 2017 году Cisco Talos обнаружила, что легитимно подписанный CCleaner 5.33, распространявшийся с официальных download servers, содержал multi-stage malware payload. Cisco Talos — CCleanup: A Vast Number of Machines at Risk
Это очень полезный контрпример для любого release process:
valid signature
!=
benign software
Code signing доказывает identity и integrity после подписи. Оно не доказывает, что подписывающая сторона не подписала уже скомпрометированный artifact.
4. SolarWinds Orion: trusted update масштабирует компрометацию
В 2020 году CISA квалифицировала инцидент SolarWinds как software supply-chain compromise. В SEC filing SolarWinds указывала, что до 18 000 клиентов могли скачать затронутые версии Orion, хотя число организаций, реально скомпрометированных через SUNBURST, было существенно меньше. CISA · SolarWinds SEC filing
Урок: legitimate distribution channel масштабирует не только fixes, но и compromise.
5. XZ Utils: Git repository — ещё не весь release source
XZ стал почти идеальным учебным кейсом. Andres Freund вышел на проблему не потому, что scanner написал backdoor detected, а потому что увидел странные runtime symptoms: необычную загрузку CPU при SSH login и ошибки Valgrind. В исходном сообщении он отдельно отметил, что часть backdoor chain находилась только в distributed tarballs и отсутствовала в Git tree. oss-security — Andres Freund, 29 March 2024
Уроки сразу два:
- review Git ≠ verify release artifact;
- иногда performance anomaly или behavioral diff обнаруживает то, чего не нашёл static gate.
6. X_TRADER → 3CX: supply-chain compromise может быть каскадным
В 2023 году Mandiant описала редкий и очень показательный сценарий: первоначальная компрометация 3CX началась с trojanized X_TRADER, software package компании Trading Technologies. Затем attackers получили доступ в 3CX и скомпрометировали уже её Windows и macOS build environments, после чего malicious code распространялся через 3CX Desktop App. Mandiant назвала это первым известным ей случаем, когда одна software supply-chain compromise привела к другой. Mandiant — 3CX Software Supply Chain Compromise
Особенно неприятная деталь: 3CX сообщала, что X_TRADER installer был digitally signed valid certificate и загружен с сайта vendor. 3CX incident update
Для electronic trading / fintech threat model это почти готовый tabletop scenario.
7. Juniper ScreenOS: unauthorized code внутри security product (е#ть дела!)
В 2015 году Juniper сообщила, что internal code review обнаружил “unauthorized code in ScreenOS”, которое могло позволить knowledgeable attacker получить administrative access к NetScreen devices и расшифровывать VPN traffic. Juniper — Important Announcement about ScreenOS
Здесь особенно важен класс продукта: security appliance сам является trust anchor.
Все эти случаи разные:
Crypto AG -> product design / supplier trust
M.E.Doc -> update channel
CCleaner -> signed release artifact
SolarWinds -> build + trusted distribution
XZ -> release tarball / build-time chain
X_TRADER/3CX -> cascading supplier + build compromise
ScreenOS -> unauthorized code in security product
Но общий вопрос один:
Какие доказательства показывают, что shipped product — именно тот продукт, который мы думаем, что проверили?
Threat model для критичного коммерческого продукта
Возьмём условную банковскую платформу / платёжный processing system / electronic trading platform.
У неё есть:
- customer PII;
- transaction data;
- credentials;
- API keys;
- signing keys;
- balances;
- order books;
- payment instructions;
- audit trail;
- privileged administrative functions.
Классический AppSec рассматривает внешнего attacker. Но для backdoor assurance threat model должен быть шире.
Potential adversaries
- Malicious insider
- Compromised developer account
- Compromised OSS maintainer
- Compromised CI/CD
- Compromised artifact repository
- Compromised signing infrastructure
- Compromised software supplier
- State-sponsored actor
- Malicious or coerced vendor
- Compromised firmware/hardware supplier
И attack surface выглядит уже не так:
Internet -> Application
а так:
Developer
|
Source repository
|
Dependencies
|
Build system
|
Compiler / toolchain
|
Artifact repository
|
Signing service
|
Update service
|
Customer environment
|
Runtime control plane
Product Security должен контролировать всю цепочку, а не только application code.
Два разных assurance-сценария: мы вендор или мы покупатель\юзер?
Здесь часто смешивают две очень разные задачи.
Если продукт разрабатываем мы
У нас потенциально есть доступ к:
source
code review history
CI/CD
compiler/toolchain
build workers
artifact repository
signing service
release metadata
runtime telemetry
Поэтому мы можем строить source-to-artifact evidence chain и достаточно глубоко проверять происхождение релиза.
Если мы покупаем closed-source enterprise software
У нас может быть только:
installer / container / appliance
vendor documentation
SBOM
signature
network traffic
runtime behavior
contractual evidence
В этом случае цель меняется. Мы не можем честно сказать «мы доказали отсутствие backdoor». Зато можем:
- проверить provenance и vendor security process;
- анализировать финальный binary/package;
- запускать продукт в sandbox/lab;
- строить network и syscall baseline;
- ограничить outbound connectivity;
- staged-rollout обновления;
- фиксировать hashes и release deltas;
- отключить необязательные vendor control-plane connections;
- получить договорные права на audit / incident notification / SBOM / vulnerability disclosure;
- минимизировать blast radius, если наше доверие ошибочно.
Для Security Director это принципиальное различие:
Producer assurance пытается доказать происхождение. Buyer assurance управляет остаточным доверием.
Именно поэтому я бы не писал спекулятивные фразы вроде «а вдруг в Oracle или Microsoft есть backdoor». Без доказательств это просто предположение.
Правильная постановка гораздо звучит сильнее:
Какой уровень доверия получает любой closed-source database/OS/security product, какие privileged capabilities ему доступны и какие независимые evidence мы можем получить от vendor и из собственного наблюдения?
Эта формулировка одинаково применима к любому поставщику.
Контроль №1: определить, что продукту вообще разрешено уметь
Это, на мой взгляд, один из самых недооценённых controls. Перед тем как искать «плохой код», нужно определить allowed behavior.
Например, для database engine:
MAY:
- listen on configured database ports
- read database files
- perform configured replication
- connect to explicitly configured backup endpoint
MUST NOT:
- spawn arbitrary shell
- connect to arbitrary Internet hosts
- read SSH private keys
- enable hidden administrative users
- download executable code at runtime
- disable audit logging through remote configuration
Это можно назвать:
- capability baseline;
- security invariants;
- negative requirements;
- prohibited behavior specification.
Без этого security team часто видит опасную capability, но не может ответить:
«Это bug или feature?»
Для critical product я бы делал Declared Security-Sensitive Capabilities Register.
Пример:
| Capability | Expected | Owner | Justification |
|---|---|---|---|
| Outbound Internet | No | Architecture | Product works offline |
| Child process execution | No | Platform | No operational need |
| Dynamic library loading | Limited | Core | Plugins only |
| Remote configuration | Yes | SRE | Signed config only |
| Debug interface | No in production | Engineering | Dev builds only |
| Auto-update | Yes | Release | TUF-protected |
После этого многие «backdoor-like» возможности становятся формально проверяемыми.
Контроль №2: source-code assurance, ориентированный на capability
Обычные CodeQL/Semgrep rules стоит дополнить custom queries.
Я бы искал:
process creation
shell execution
dynamic code loading
reflection / eval
raw sockets
new outbound HTTP clients
hardcoded IP addresses
hardcoded credentials
hidden feature flags
alternate authentication paths
debug/admin endpoints
audit disabling
runtime code download
filesystem access outside product directories
credential-store access
environment/time/hostname based branches
Например, такое изменение:
+ if config.remote_support:
+ auth.require_admin = False
может не породить классическую vulnerability finding. Но оно должно вызвать security-sensitive behavior review.
*Для критичных модулей я бы также использовал:
*- CODEOWNERS;
- mandatory security approval;
- two-person review;
- signed commits/tags where appropriate;
- protected branches;
- no direct pushes;
- отдельный approval для auth, crypto, update, audit и remote-management code.
NIST IR 8397 включает threat modeling, static analysis, secret detection, black-box testing, structural testing и fuzzing в минимальный набор developer verification techniques. NIST IR 8397
Контроль №3: dependency и release-source integrity
XZ показал, почему недостаточно проверить repository.
Для каждой release dependency полезно знать:
Where did it come from?
Which exact digest?
Which source revision?
Who built it?
Can we reproduce it?
Did the release tarball differ from the repository?
Минимальный baseline:
- lockfiles;
- digest pinning;
- dependency allowlist;
- SBOM;
- internal package proxy;
- provenance where available;
- policy against unreviewed new dependencies;
- monitoring maintainer/ownership changes для critical OSS.
Для high-risk dependency имеет смысл сравнивать:
upstream Git tag
vs
published source archive
vs
compiled package
Контроль №4: harden the build
Если attacker может изменить build environment, clean source уже не спасает.
Я бы стремился к:
- ephemeral build workers;
- hermetic или максимально изолированным builds;
- pinned toolchains;
- immutable builder images;
- minimal build-time secrets;
- short-lived workload identities;
- controlled/no outbound network during compilation;
- separation build and signing;
- immutable artifact repository;
- detailed build logs.
Здесь очень полезна SLSA.
В актуальной SLSA 1.2 Build Track описывает уровни от наличия provenance до hardened build platform. Provenance фиксирует, кто, чем, каким процессом и из каких inputs создал artifact. SLSA 1.2 SLSA Provenance
Но важно помнить:
Provenance доказывает происхождение. Оно не доказывает добрые намерения производителя.
Контроль №5: in-toto и attestations
in-toto позволяет описать ожидаемую supply chain и проверить, что каждый шаг был выполнен ожидаемой identity и в ожидаемом порядке.
Условно:
source
|
compile
|
test
|
package
|
binary scan
|
sign
|
publish
Для каждого шага можно получить evidence:
WHO
WHAT COMMAND
INPUT DIGEST
OUTPUT DIGEST
WHEN
Это превращает release из одного файла в artifact + evidence. И это принципиально другой уровень assurance. Едем дальше, копаем тему!
Контроль №6: reproducible builds и independent rebuild
Один из самых сильных ответов на вопрос:
«Соответствует ли бинарник исходникам?»
— reproducible build.
Идея тут проста как 2-ве копейки:
Source revision A
|
Builder #1
|
Artifact hash X
Source revision A
|
Independent Builder #2
|
Artifact hash X
Если output детерминирован и совпадает bit-for-bit, становится значительно сложнее незаметно внедрить дополнительный код только в production build.
Проект Reproducible Builds определяет воспроизводимую сборку через одинаковые inputs, заданное build environment и идентичный проверяемый output. Reproducible Builds
Для обычного SaaS продукта это может быть слишком дорого для каждого commit.
Для:
- HSM software;
- financial transaction engine;
- database;
- VPN;
- IAM;
- cryptographic library;
- trading engine;
я бы рассматривал independent rebuild как вполне оправданный release control. Да, только так!
Контроль №7: анализировать именно shipping binary
Это одна из главных мыслей всей этой статьи.
Source scan и binary scan отвечают на разные вопросы.
Для финального artifact можно проверять:
- imported APIs;
- system calls;
- strings;
- hardcoded domains/IPs;
- embedded certificates;
- embedded private keys;
- executable sections;
- packed/obfuscated regions;
- unexpected interpreters;
- bundled scripts;
- dynamic loaders;
- capabilities/permissions;
- new binaries between releases;
- suspicious network functionality;
- malware indicators.
Commercial platforms, например ReversingLabs Spectra Assure, специально делают complex binary analysis post-build и не требуют исходного кода.
Для manual deep-dive используются:
- Ghidra;
- IDA;
- Binary Ninja;
- radare2;
- language-specific decompilers.
Для firmware/device security существуют отдельные классы платформ вроде Binarly, Finite State и Eclypsium. Это не означает, что любой из этих продуктов может выдать сертификат:
“Backdoors: 0.”
Такого детектора в общем случае не существует. Но они резко повышают visibility именно в реальный поставляемый artifact.
Контроль №8: behavioral sandboxing
Статика показывает capability. Dynamic analysis показывает:
Что программа реально делает в конкретном environment.
Я бы собирал как минимум:
process tree
syscalls
filesystem access
registry/config changes
DNS
TCP/UDP destinations
TLS destinations
loaded modules
child processes
IPC
credential access
privilege changes
kernel interaction
Но один запуск недостаточен. Нужно менять сам environment:
time / date
timezone
locale
country
hostname
username
machine ID
network range
DNS responses
license state
feature flags
config values
server responses
То есть фактически делать behavioral state-space exploration.
Контроль №9: behavioral diff между релизами
Это крайне практичный control. И важный.
Допустим:
7.4.0 -> approved baseline
7.4.1 -> new release
И вы сравниваете behavior.
+ NEW outbound domain: telemetry-new.example
+ NEW child process: /bin/sh
+ NEW read: ~/.ssh/id_rsa
+ NEW privileged syscall
+ NEW dynamic library
Каждый такой diff не обязательно означает compromise.
Но каждый — хороший кандидат на review. Мне нравится этот подход, потому что он превращает сложную задачу:
«Найдите неизвестный backdoor»
в значительно более реалистичную:
«Объясните новые security-sensitive capabilities этого релиза».
Контроль №10: secure update architecture
Update channel — одно из самых привлекательных мест для supply-chain attacker.
Простая модель:
download
-> verify vendor signature
-> install
лучше, чем ничего, но не идеальна.
Что произойдёт, если signing key скомпрометирован? Именно эту задачу решает The Update Framework (TUF). TUF проектировался так, чтобы update system сохранял устойчивость даже при компрометации repository или части signing keys. Он использует:
- разделение signing roles;
- threshold signatures;
- expiration;
- version metadata;
- hashes;
- key rotation/revocation;
- offline root trust.
Для critical platform я бы также рассматривал:
- staged rollout;
- canary population;
- delayed automatic rollout для high-risk updates;
- rollback;
- emergency freeze;
- independent approval для security-critical changes.
Контроль №11: signing и transparency
Sigstore/Cosign хорошо закрывает authenticity и auditability artifact signing.
Sigstore keyless signing связывает artifact signature с identity, а signing events фиксируются в Rekor transparency log. Sigstore signing overview Rekor
Но снова:
valid signature != safe software.
Поэтому signing должен быть последним этапом после assurance gates, а не заменой assurance.
Контроль №12: runtime containment — предположить, что backdoor всё-таки прошёл
Security engineering становится зрелым, когда допускает failure предыдущих controls. Если приложение не должно ходить в произвольный Internet: не разрешайте ему это делать.
Например:
Default outbound: DENY
ALLOW:
api.company.example:443
updates.company.example:443
Everything else: DENY + ALERT
Для server-side продукта:
- Kubernetes NetworkPolicy;
- Cilium/Calico policies;
- service mesh egress;
- host firewall;
- proxy allowlist.
Для процесса:
- non-root;
- Linux capabilities drop;
- seccomp;
- AppArmor/SELinux;
- read-only filesystem;
- isolated service accounts;
- no access to cloud metadata unless needed.
Если потенциальный implant не имеет:
arbitrary outbound network
filesystem access
credential access
shell execution
privileged identity
его полезность для attacker резко снижается.
Containment иногда важнее detection.
Как это может выглядеть в CI/CD
Я бы строил отдельный release lane примерно так:
┌──────────────────────────────┐
│ SOURCE POLICY │
│ reviews / CODEOWNERS │
│ CodeQL / Semgrep │
│ security capability rules │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ DEPENDENCY ASSURANCE │
│ SCA / SBOM / digest pinning │
│ package policy │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ HERMETIC BUILD │
│ ephemeral runner │
│ pinned toolchain │
│ restricted network │
└──────────────┬───────────────┘
│
SLSA provenance
│
┌──────────────▼───────────────┐
│ INDEPENDENT REBUILD │
│ compare output digests │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ BINARY ASSURANCE │
│ malware / capability scan │
│ binary diff │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ SANDBOX │
│ syscall/network behavior │
│ behavioral diff │
└──────────────┬───────────────┘
│
sign + attest
│
┌──────────────▼───────────────┐
│ RELEASE │
│ policy verification │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ RUNTIME │
│ least privilege / egress │
│ telemetry / integrity │
└──────────────────────────────┘
Conceptual pipeline:
release-assurance:
- verify_security_review
- run_custom_sast_capability_rules
- generate_sbom
- verify_dependency_policy
- build_in_ephemeral_isolated_runner
- generate_slsa_provenance
- rebuild_in_independent_environment
- compare_release_digests
- scan_final_binary
- compare_binary_capabilities_with_previous_release
- run_behavioral_sandbox
- compare_network_and_syscall_baseline
- sign_artifact
- publish_attestations
- release_only_if_all_gates_pass
Это не конкретный vendor syntax. Это security architecture pipeline.
Release Evidence Bundle: что я хотел бы получать на каждый critical release
Для high-assurance продукта security gate должен выдавать не просто зелёную галочку, а evidence bundle, который можно проверить позже.
Например:
release-evidence/
source-commit.txt
dependency-lockfiles/
sbom.cdx.json
build-provenance.intoto.jsonl
build-environment.json
artifact.sha256
signature.bundle
binary-analysis-report.json
capability-diff.json
sandbox-network-diff.json
syscall-diff.json
security-approvals.json
update-metadata/
Тогда release decision можно формулировать как policy:
ALLOW RELEASE only if:
reviewed_source == provenance.source
AND independent_build_digest == release_digest
AND no_unapproved_new_capabilities
AND no_new_unapproved_egress
AND signature_identity == expected_release_identity
AND security_approvals >= required_threshold
Это не гарантирует отсутствие malicious functionality. Но оно резко увеличивает количество независимых следов, которые attacker должен одновременно подделать.
OWASP Software Component Verification Standard (SCVS) полезен именно как практический supply-chain assurance checklist: он отдельно покрывает Inventory, SBOM, Build Environment, Package Management, Component Analysis и Pedigree/Provenance. Для higher-assurance levels SCVS требует в том числе verifiable origin и auditable chain of custody для source и binary components. OWASP SCVS
Какие patterns я бы автоматически флагал
Ниже не «backdoor signatures», а security-sensitive patterns, требующие объяснения.
NEW process execution
NEW shell invocation
NEW outbound destination
NEW hardcoded IP/domain
NEW dynamic loader
NEW remote config key
NEW authentication branch
NEW debug/admin API
NEW crypto key embedded in binary
NEW credential-store access
NEW file access outside expected directories
NEW telemetry payload field
NEW capability/permission
NEW unsigned plugin/module path
Ключевое слово здесь — NEW. Для зрелого продукта baseline + diff часто полезнее, чем попытка написать универсальное правило «найти backdoor».
Что реально можно автоматизировать, а что останется экспертной работой
Рынок любит обещание: upload binary → get backdoor verdict.
На практике automated tooling хорошо помогает в пяти слоях:
- Source capability detection — CodeQL, Semgrep и custom rules для security-sensitive APIs и data flows.
- Component/provenance analysis — SCA, SBOM, package origin, signatures, attestations.
- Binary/package analysis — recursive unpacking, imports/exports, embedded files, certificates, strings, suspicious sections, malware signatures, YARA, binary diff.
- Dynamic behavior — process tree, syscalls, filesystem, registry, DNS, TCP/UDP, TLS destinations, IPC, loaded modules.
- Release diff — что появилось в версии N относительно N-1.
Но автоматизация плохо отвечает на вопрос:
“Зачем эта capability существует?”
Именно здесь нужен человек, знающий architecture и expected behavior. Например, следующий code path может быть полностью легитимным для remote-support agent и совершенно недопустимым для offline database engine:
payload = http.get(config.control_plane + "/task")
if verify_signature(payload):
subprocess.run(payload.command, shell=False)
Scanner может увидеть network + process execution. Но только architecture/security review может решить, должна ли система обладать такой power вообще.
Поэтому я бы не создавал отдельную команду “backdoor hunters”, которая работает в отрыве от product engineering. Я бы соединял:
Product Security
+ Architecture
+ Build/Release Engineering
+ Detection Engineering
+ Reverse Engineering
+ Supplier Security
+ Platform/SRE
Для сложных native binaries и firmware понадобятся reverse-engineering инструменты и специалисты; для Java/.NET проще использовать decompilation и semantic diff; для containers полезно сравнивать filesystem layers, entrypoints, capabilities и network behavior.
Коммерческие платформы класса software binary analysis могут автоматизировать часть post-build контроля. Но я бы всегда рассматривал их как источник evidence, а не как oracle, который способен доказать отсутствие закладки.
Vendor due diligence: что спрашивать у поставщика
Проблема становится особенно интересной, когда source code принадлежит не вам. NIST в 2026 году выпустил SP 1326 — C-SCRM Due Diligence Assessment Quick-Start Guide. Он рассматривает due diligence поставщика через provenance, resilience, foundational cyber practices, supply-chain tiers и FOCI. NIST SP 1326
Для critical software supplier я бы спрашивал ЭТО:
Development
- Есть ли documented secure SDLC?
- Кто может merge security-critical code?
- Используется ли two-person approval?
- Как защищены source repositories?
- Как контролируются dependencies?
Build
- Build workers ephemeral?
- Build network isolated?
- Toolchain pinned?
- Есть SLSA provenance?
- Возможен reproducible build?
- Разделены build и signing?
Release
- Каждый artifact подписан?
- Есть transparency/attestation?
- Финальный binary сканируется независимо от source?
- Есть binary diff между releases?
Update
- Как защищается update metadata?
- Что произойдёт при компрометации signing key?
- Есть threshold signing?
- Есть rollback protection?
- Есть staged rollout?
Runtime
- Какие outbound connections делает product?
- Какие endpoints обязательны?
- Может ли vendor remote-disable product?
- Есть ли remote support function?
- Есть ли undocumented telemetry?
- Какие данные покидают customer environment?
И один из моих любимых вопросов:
Can the product continue operating securely if the vendor's cloud control plane is unavailable or hostile?
Для банковской или инфраструктурной системы это очень хороший архитектурный тест.
Hardware и firmware: от холодной войны к современному trust chain
Разговор о software backdoors легко создаёт ощущение, что проблема родилась вместе с SolarWinds. На самом деле trust problem значительно старше.
Crypto AG хорошо показывает supplier-level manipulation на уровне security product. В hardware security существует параллельный класс угроз — hardware Trojans / malicious circuit modifications. DARPA в программе TRUST прямо исходила из сценария, где IC может быть designed or fabricated under untrusted conditions, и пыталась строить измеримые способы обнаружения модификаций. DARPA — TRUST
В современном enterprise stack граница между hardware и software размыта:
application
OS / hypervisor
bootloader
UEFI
BMC / management controller
NIC / storage firmware
microcode
silicon
Компрометация любого нижнего слоя может пережить reinstall верхнего.
NIST SP 800-193 поэтому строит firmware resiliency вокруг трёх функций:
Protection → Detection → Recovery.
Для high-assurance environment я бы постепенно добавлял:
- secure boot;
- measured boot;
- TPM-backed attestation;
- signed firmware updates;
- firmware inventory and version pinning;
- BMC isolation;
- hardware root of trust;
- independent firmware analysis там, где risk оправдывает стоимость.
И здесь важно не перейти в театр безопасности. Даже серьёзная hardware assurance программа не даёт философской гарантии «ничего скрытого нет». Она увеличивает cost of subversion и количество независимых способов её обнаружить.
Российская школа НДВ: термин старый, инструментарий неожиданно современный
Для русской версии эту часть было бы странно обходить. Сам термин «недекларированные возможности» в российской нормативной школе формализован намного раньше современного бума software supply-chain security.
Исторический Руководящий документ Гостехкомиссии 1999 года №114 назывался буквально:
«Программное обеспечение средств защиты информации. Классификация по уровню контроля отсутствия недекларированных возможностей».
Он определял НДВ как функциональные возможности ПО, не описанные или не соответствующие документации, использование которых способно нарушить confidentiality, integrity или availability. Гостехкомиссия, РД 1999 №114
Важно не выдавать этот документ за текущую универсальную норму для любого российского коммерческого ПО: область применения и сертификационный режим менялись, а прежний РД перестал использоваться как основа соответствующих сертификационных работ после реформы 2020 года. Но как историческая formalization проблемы он очень показателен.
Гораздо интереснее текущая картина.
ФСТЭК: новая Методика 2026 года
12 мая 2026 года ФСТЭК России утвердила новую «Методику выявления уязвимостей и недекларированных возможностей в программном обеспечении»; для решений по сертификации СЗИ, выданных после 1 августа 2026 года, должна применяться эта Методика. Информационное сообщение о Методике
Это не документ «для каждого сайта и SaaS». Его scope — исследования ПО средств защиты информации в рамках уровней доверия. Но набор техник очень интересен Product Security инженеру, потому что выглядит совсем не музейно.
В опубликованной выписке фигурируют:
- анализ архитектуры;
- static methods;
- dynamic methods;
- static analysis исходного кода;
- module testing со сбором покрытия;
- fuzzing attack-surface interfaces со сбором coverage;
- экспертиза source и restored/decompiled code;
- исследование code, который не был задействован dynamic analysis из-за anti-analysis механизмов;
- анализ сторонних компонентов;
- результаты composition/configuration analysis;
- build environment и build system;
- сам distribution artifact.
ФСТЭК 2026 — выписка, общие требования · Fuzzing requirements · Code expertise
Мне особенно нравится, что Методика рассматривает не только уязвимости и НДВ, но и «потенциально опасные декларированные возможности» — например, избыточные external interfaces или functions. Это очень близко к тому, что выше я называл capability baseline / negative requirements.
Ещё одна важная деталь: ФСТЭК связывает исследования с процессами безопасной разработки по ГОСТ Р 56939-2024, который действует с 20 декабря 2024 года и заменил ГОСТ Р 56939-2016. Росстандарт — ГОСТ Р 56939-2024
То есть современная российская модель уже тоже фактически соединяет:
secure development
+ architecture analysis
+ SCA/composition
+ static analysis
+ fuzzing
+ manual code expertise
+ build environment
+ distribution artifact
Это тот же conceptual shift, который в международной терминологии распределён между SSDF, C-SCRM, SLSA, provenance и product assurance.
А где ФСБ?
Здесь важно не смешивать регуляторов.
Традиционно ФСТЭК отвечает за большой пласт technical information protection и certification of non-cryptographic security controls, а криптографические средства и отдельные требования вокруг электронной подписи/СКЗИ относятся к компетенции ФСБ.
Хороший конкретный пример — Приказ ФСБ России №796 о требованиях к средствам электронной подписи и удостоверяющего центра. Для определённых классов средств УЦ там прямо требовалась проверка исходных текстов системного и прикладного ПО на отсутствие недекларированных возможностей, а для более высокого класса — формальная верификация соответствующих свойств. У текущей редакции этого приказа срок действия ограничен 1 января 2027 года, поэтому его корректно приводить именно как действующий на момент написания статьи специализированный пример, а не как универсальную норму. Приказ ФСБ №796
Почему этот российский экскурс полезен глобальному Product Security
Не потому, что международной компании нужно копировать российскую сертификацию. А потому что старая формулировка «отсутствие недекларированных возможностей» очень хорошо заставляет посмотреть на продукт иначе:
Vulnerability testing спрашивает, можно ли заставить программу сделать опасное действие. NDV assurance спрашивает, не умеет ли она уже делать опасное действие по замыслу или скрытому условию.
Современный Software Integrity program в коммерческой компании по сути соединяет обе модели.
Международные стандарты и frameworks, которые я бы использовал
NIST SSDF — SP 800-218
Базовый secure software development framework. Он не является «backdoor detection standard», но даёт фундамент для защищённой разработки и release process.
На момент написания final остаётся SSDF 1.1; NIST опубликовал draft SSDF 1.2 в декабре 2025 года.
NIST SSDF
NIST SP 800-218
NIST IR 8397
Minimum Standards for Developer Verification of Software.
Полезен как verification baseline:
- threat modeling;
- automated testing;
- static analysis;
- secret scanning;
- black-box testing;
- structural testing;
- fuzzing;
- dependency analysis.
NIST SP 800-161 Rev. 1
Один из наиболее прямых документов для C-SCRM. Особенно важна его постановка риска malicious functionality.
NIST SP 1326
Очень свежий документ — final опубликован в июле 2026 года. Это уже practical supplier due-diligence layer.
SLSA 1.2
Framework для build provenance и supply-chain integrity.
OWASP SCVS
OWASP Software Component Verification Standard — очень практичный complement к NIST/SLSA. Его шесть control families покрывают Inventory, SBOM, Build Environment, Package Management, Component Analysis и Pedigree/Provenance. OWASP SCVS
Для этой статьи особенно интересны требования к repeatable build, защите build pipeline и verifiable origin / chain of custody компонентов.
in-toto
Attestation framework для доказательства того, что software supply-chain steps выполнены ожидаемым образом.
Sigstore
Artifact signing + identity + transparency.
TUF
Защита software update systems, в том числе от key compromise.
Common Criteria — ISO/IEC 15408
Common Criteria исторически ближе к миру assurance, чем типичный AppSec framework.
В 2026 году опубликованы новые редакции серии ISO/IEC 15408. Part 3 определяет security assurance components, а vulnerability assessment включает independent vulnerability analysis и penetration testing на соответствующих уровнях.
ISO/IEC 15408-1:2026
ISO/IEC 15408-3:2026
Common Criteria Part 3
Европейский контекст: Cyber Resilience Act
EU Cyber Resilience Act не является стандартом поиска backdoors. Но направление очень показательное.
CRA вводит horizontal cybersecurity requirements для products with digital elements, включая:
- cybersecurity risk assessment;
- vulnerability handling;
- security testing/review;
- SBOM;
- secure update distribution;
- support obligations.
На момент публикации этой статьи есть интересный временной нюанс:
- основная масса CRA применяется с 11 December 2027;
- reporting obligations Article 14 уже применяются с 11 September 2026;
- положения о conformity-assessment bodies начали применяться с 11 June 2026.
Это хорошо показывает общий тренд:
Product security постепенно становится не только engineering practice, но и доказуемым свойством продукта и его lifecycle.
Почему невозможно «доказать отсутствие backdoor» одной платформой
Здесь важно не продавать security theatre.
Универсальный scanner:
Backdoors found: 0
не даёт математической гарантии отсутствия скрытого поведения.
Причины:
- Trigger может быть чрезвычайно редким.
- Behavior может зависеть от external service.
- Payload может загружаться позже.
- Code может быть obfuscated.
- Capability может выглядеть легитимной.
- Vendor сам может быть adversary.
- Build toolchain может быть скомпрометирован.
- Hardware/firmware может находиться вне scope анализа.
Поэтому правильная стратегия — defense in depth:
prevent
+
detect
+
verify
+
constrain
+
monitor
Практическая maturity model
Я бы оценивал capability примерно так. Ценим логику ниже.
Level 0 — Vulnerability Security
SAST
DAST
SCA
Компания в основном ищет случайные ошибки.
Level 1 — Release Integrity
SBOM
artifact signing
protected release pipeline
Level 2 — Build Assurance
SLSA provenance
ephemeral builders
attestations
Level 3 — Artifact Assurance
post-build binary scanning
binary diff
capability analysis
Level 4 — Behavioral Assurance
sandbox
behavioral diff
egress baseline
environment variation
Level 5 — High Assurance
reproducible builds
independent rebuild
independent binary review
runtime attestation
strict containment
supplier evidence
Не каждый продукт должен быть Level 5.
Но risk tier продукта должен определять depth of assurance.
Метрики, которые действительно имеют смысл
Я бы не измерял программу количеством binary scans.
Лучше:
% critical releases with verified provenance
% critical releases independently reproduced
% production artifacts scanned post-build
% security-sensitive capability changes reviewed
number of new outbound destinations per release
% workloads with default-deny egress
% release artifacts with verified signatures/attestations
% critical suppliers providing SBOM + provenance evidence
mean time to investigate behavioral diff
number of undocumented privileged interfaces discovered
Эти metrics уже показывают реальную maturity.
Где здесь роль Security Director
Security Director должен определить:
- Какие продукты действительно требуют такого assurance level.
- Какие capabilities считаются запрещёнными или security-sensitive.
- Какие evidence обязательны для release.
- Какие suppliers считаются high risk.
- Какие controls являются release blockers.
- Как ограничивается impact, если prevention не сработал.
И главное — перевести абстрактный страх:
«А вдруг в продукте есть закладка?»
в проверяемые инженерные вопросы:
Можно ли отследить источник этого бинарного файла?
Можно ли воспроизвести его в другой среде?
Что изменилось в его возможностях\поведении?
Какое новое сетевое поведение появилось?
Кто санкционировал изменение?
Может ли продукт\ПО осуществлять утечку данных?
Может ли поставщик удаленно отключить его?
Может ли приложение работать без произвольного доступа к Интернету?
Можно ли обнаружить изменения после развертывания?
Если на эти вопросы есть хорошие ответы, разговор о backdoors перестаёт быть конспирологией и становится обычной инженерией доверия.
Выводы
Product Security долгое время концентрировался на vulnerabilities. Это логично: SQL injection, memory corruption и broken access control встречаются значительно чаще, чем специально внедрённые backdoors.
Но по мере того как software supply chains становятся длиннее, продукты сложнее, а критичные системы всё сильнее зависят от внешних vendors, вопрос software integrity становится самостоятельной security discipline.
Не существует одного инструмента, который докажет отсутствие недекларированных возможностей. Такова рельсность.
Но можно построить архитектуру, в которой скрытую функцию:
- сложно внедрить;
- сложно протащить через build;
- сложно спрятать в binary;
- сложно активировать незаметно;
- сложно использовать для exfiltration;
- и значительно легче обнаружить.
Именно это, на мой взгляд, и есть современный Software Integrity & Malicious Functionality Assurance.
Что почитать и посмотреть дальше
Если хочется углубиться не только в standards, а именно в логику доверия и реальные investigations, я бы начал отсюда.
Papers / primary material
- Ken Thompson — Reflections on Trusting Trust — фундаментальный thought experiment про compiler-level subversion. https://doi.org/10.1145/358198.358210
- David A. Wheeler — Diverse Double-Compiling — практическая защита от класса “trusting trust” при определённых assumptions. https://dwheeler.com/trusting-trust/
- Andres Freund — original XZ disclosure — великолепный пример расследования, начавшегося с runtime anomalies. https://www.openwall.com/lists/oss-security/2024/03/29/4
- Mandiant — 3CX / X_TRADER — cascading software supply-chain compromise. https://cloud.google.com/blog/topics/threat-intelligence/3cx-software-supply-chain-compromise
- Cisco Talos — CCleaner — почему legitimate server + valid signature недостаточны. https://blog.talosintelligence.com/avast-distributes-malware/
Рекомендуемое видео
- Computerphile — Reflections on Trusting Trust — хорошее человеческое объяснение идеи Thompson. https://www.youtube.com/watch?v=SJ7lOus1FzQ
- Google Cloud Tech — Securing your software supply chain — короткий introduction к lifecycle trust и SLSA. https://www.youtube.com/watch?v=Dg-hD4HHKT8
Standards / guidance
- NIST SP 800-161 Rev. 1 — C-SCRM
- NIST SP 800-218 — SSDF
- OWASP SCVS
- SLSA 1.2
- in-toto
- Sigstore
- TUF
- Common Criteria / ISO/IEC 15408
И я бы обязательно читал original incident disclosures, а не только пересказы. Именно там обычно находятся детали, которые превращают заезженный термин “supply chain attack” в конкретный engineering control.
References
- NIST SP 800-161 Rev. 1 — Cybersecurity Supply Chain Risk Management Practices for Systems and Organizations https://csrc.nist.gov/pubs/sp/800/161/r1/upd1/final
- NIST SP 1326 — C-SCRM Due Diligence Assessment Quick-Start Guide, July 2026 https://csrc.nist.gov/pubs/sp/1326/final
- NIST SP 800-218 — Secure Software Development Framework https://csrc.nist.gov/pubs/sp/800/218/final
- NIST IR 8397 — Guidelines on Minimum Standards for Developer Verification of Software https://csrc.nist.gov/pubs/ir/8397/final
- NIST SP 800-193 — Platform Firmware Resiliency Guidelines https://csrc.nist.gov/pubs/sp/800/193/final
- MITRE ATT&CK T1195 — Supply Chain Compromise https://attack.mitre.org/techniques/T1195/
- MITRE CWE-506 — Embedded Malicious Code https://cwe.mitre.org/data/definitions/506.html
- MITRE CWE-510 — Trapdoor https://cwe.mitre.org/data/definitions/510.html
- SLSA Specification v1.2 https://slsa.dev/spec/v1.2/
- in-toto https://in-toto.io/docs/getting-started/
- Sigstore / Cosign https://docs.sigstore.dev/cosign/signing/overview/
- Rekor Transparency Log https://docs.sigstore.dev/logging/overview/
- The Update Framework https://theupdateframework.io/docs/overview/
- Reproducible Builds https://reproducible-builds.org/docs/formal-definition/
- CISA — Active Exploitation of SolarWinds Software https://www.cisa.gov/news-events/alerts/2020/12/13/active-exploitation-solarwinds-software
- SolarWinds SEC filing — SUNBURST investigation update https://www.sec.gov/Archives/edgar/data/1739942/000173994221000080/swi-20210331.htm
- Red Hat — CVE-2024-3094 / XZ Utils https://access.redhat.com/security/cve/cve-2024-3094
- Juniper — Important Announcement about ScreenOS https://community.juniper.net/browse/blogs/blogviewer?BlogKey=e0a62f51-c793-4e7e-98e8-c5ac081f2c18
- ISO/IEC 15408 series / Common Criteria https://www.iso.org/standard/15408-1 https://www.iso.org/standard/15408-3 https://www.commoncriteriaportal.org/
- EU Cyber Resilience Act — Regulation (EU) 2024/2847 https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32024R2847
- ReversingLabs Spectra Assure https://www.reversinglabs.com/products/spectra-assure
- Crypto AG investigation — The Washington Post https://www.washingtonpost.com/graphics/2020/world/national-security/cia-crypto-encryption-machines-espionage/
- Ken Thompson — Reflections on Trusting Trust https://doi.org/10.1145/358198.358210
- DARPA — TRUST in Integrated Circuits https://www.darpa.mil/research/programs/trusted-integrated-circuits
- Microsoft MSRC — Petya / M.E.Doc update service https://www.microsoft.com/en-us/msrc/blog/2017/06/update-on-petya-malware-attacks
- Cisco Talos — CCleaner supply-chain compromise https://blog.talosintelligence.com/avast-distributes-malware/
- Andres Freund — original XZ backdoor disclosure https://www.openwall.com/lists/oss-security/2024/03/29/4
- Mandiant — 3CX compromise initiated by X_TRADER compromise https://cloud.google.com/blog/topics/threat-intelligence/3cx-software-supply-chain-compromise
- OWASP Software Component Verification Standard https://scvs.owasp.org/
- ГОСТ Р 56939-2024 — Росстандарт https://protect.gost.ru/gost/details/f3818925-a96f-4f55-96e9-46b44720ee64
- ФСТЭК России — Методика выявления уязвимостей и недекларированных возможностей, 12.05.2026 (выписка) https://service.securitm.ru/docs/metodika-vyiavleniia-uiazvimostei-i-nedeklarirovannyx-vozmoznostei-v-programmnom-obespecenii-vypiska
- Гостехкомиссия России — РД 1999 №114 https://base.garant.ru/197898/
- Приказ ФСБ России №796 — требования к средствам электронной подписи и УЦ https://www.consultant.ru/document/cons_doc_LAW_126209/






Top comments (0)