Suspicious IDE Extension Installation from VSIX
Detects installation of an IDE extension from a local VSIX ("--install-extension" with a ".vsix" path) when that path is in a staging directory, or the parent is a script host or installer. VS Code and compatible editors (Cursor, VSCodium, Windsurf) use this CLI to sideload extensions outside the marketplace.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2026/10/26"
3integration = ["endpoint"]
4maturity = "production"
5min_stack_comments = "MV_CONTAINS was added to ES|QL in 9.2.0 and is not available on 8.19; 9.3.0 is the lowest supported 9.x release."
6min_stack_version = "9.3.0"
7updated_date = "2026/10/26"
8
9[rule]
10author = ["Elastic"]
11description = """
12Detects installation of an IDE extension from a local VSIX ("--install-extension" with a ".vsix" path) when that path is
13in a staging directory, or the parent is a script host or installer. VS Code and compatible editors (Cursor, VSCodium,
14Windsurf) use this CLI to sideload extensions outside the marketplace.
15"""
16from = "now-9m"
17language = "esql"
18license = "Elastic License v2"
19name = "Suspicious IDE Extension Installation from VSIX"
20note = """## Triage and analysis
21
22### Investigating Suspicious IDE Extension Installation from VSIX
23
24An IDE CLI (`code`, `cursor`, `codium`, or a compatible editor) was invoked with `--install-extension` against a
25`.vsix` file. The VSIX path is under a staging directory (`Users\\Public`, `AppData\\Local\\Temp`, `/tmp`,
26`/var/tmp`, `/private/tmp`, `/dev/shm`), or the parent is a script host or installer rather than the editor itself.
27Sideloading a VSIX is a known way to persist or gain execution through a malicious IDE extension.
28
29### Possible investigation steps
30
31- From `process.command_line`, extract the `.vsix` path and the editor binary (`code`, `code.exe`, `cursor`, `codium`).
32- Review `process.parent.name` and `process.parent.command_line` to see whether a script host (`powershell`,
33 `pwsh`, `mshta`, `wscript`, `cscript`, `msiexec`, `python*`, `py.exe`, `node`, `bun`, `osascript`) launched the install.
34- Hash the VSIX and compare it with the extension the editor actually installed under `.vscode/extensions` or the
35 equivalent Cursor or VSCodium extensions directory.
36- On the same host and user, look for follow-on child processes from the extension host, new outbound connections,
37 and files written by the extension.
38
39### False positive analysis
40
41- Extension development often installs a locally built VSIX from PowerShell, pwsh, Node, Bun, or Python, including
42 from a temp directory. Confirm the VSIX path, publisher, and parent script with the developer before excluding.
43- Scope exceptions to a known VSIX path, parent command line, host, or user. Do not broadly exclude
44 `--install-extension` or the editor binary.
45
46### Response and remediation
47
48- If the VSIX is unapproved, uninstall the extension, remove the VSIX, and restart the editor.
49- Quarantine the VSIX, collect its hash, and hunt that hash and command line on other hosts.
50- If a script host launched the install, investigate that parent for a downloader or installer and remove it.
51- Rotate tokens or credentials the extension could have read from the user profile or workspace.
52"""
53references = [
54 "https://www.mdsec.co.uk/2021/01/macos-post-exploitation-shenanigans-with-vscode-extensions/",
55 "https://code.visualstudio.com/docs/editor/extension-marketplace#_install-from-a-vsix",
56]
57risk_score = 47
58rule_id = "7babe894-46e5-4cc8-a7ae-3b0e71e31d97"
59setup = """## Setup
60
61This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
62
63Setup instructions: https://ela.st/install-elastic-defend
64"""
65severity = "medium"
66tags = [
67 "Domain: Endpoint",
68 "OS: Linux",
69 "OS: Windows",
70 "OS: macOS",
71 "Use Case: Threat Detection",
72 "Tactic: Persistence",
73 "Data Source: Elastic Defend",
74 "Resources: Investigation Guide",
75 "Rule Type: ES|QL",
76 "Platform: Windows",
77 "Platform: Linux",
78 "Platform: macOS",
79]
80timestamp_override = "event.ingested"
81type = "esql"
82
83query = '''
84FROM logs-endpoint.events.process-* METADATA _id, _version, _index
85| WHERE MV_CONTAINS(event.category, "process")
86 AND MV_CONTAINS(event.type, "start")
87 AND TO_LOWER(process.command_line) LIKE "*--install-extension*"
88 AND TO_LOWER(process.command_line) LIKE "*.vsix*"
89 AND (
90 (
91 host.os.type == "windows"
92 AND (
93 TO_LOWER(process.command_line) RLIKE
94 """.*\\users\\public\\.*|.*\\appdata\\local\\temp\\.*|.*/users/public/.*|.*/appdata/local/temp/.*"""
95 OR TO_LOWER(process.parent.name) IN (
96 "mshta.exe",
97 "wscript.exe",
98 "cscript.exe",
99 "powershell.exe",
100 "msiexec.exe",
101 "pwsh.exe",
102 "node.exe",
103 "bun.exe",
104 "py.exe"
105 )
106 OR TO_LOWER(process.parent.name) LIKE "python*"
107 )
108 )
109 OR
110 (
111 host.os.type IN ("macos", "linux")
112 AND (
113 TO_LOWER(process.command_line) LIKE (
114 "*/tmp/*",
115 "*/var/tmp/*",
116 "*/private/tmp/*",
117 "*/dev/shm/*",
118 "*/users/shared/*"
119 )
120 OR TO_LOWER(process.parent.name) IN (
121 "osascript", "node", "bun"
122 )
123 OR TO_LOWER(process.parent.name) LIKE "python*"
124 )
125 )
126 )
127| KEEP
128 _id,
129 _version,
130 _index,
131 data_stream.namespace,
132 @timestamp,
133 host.name,
134 host.id,
135 agent.id,
136 host.os.type,
137 user.name,
138 user.domain,
139 process.name,
140 process.parent.name,
141 process.command_line,
142 process.parent.command_line
143'''
144
145
146[[rule.threat]]
147framework = "MITRE ATT&CK"
148
149[[rule.threat.technique]]
150id = "T1176"
151name = "Software Extensions"
152reference = "https://attack.mitre.org/techniques/T1176/"
153
154[[rule.threat.technique.subtechnique]]
155id = "T1176.002"
156name = "IDE Extensions"
157reference = "https://attack.mitre.org/techniques/T1176/002/"
158
159[rule.threat.tactic]
160id = "TA0003"
161name = "Persistence"
162reference = "https://attack.mitre.org/tactics/TA0003/"
163
164[rule.investigation_fields]
165field_names = [
166 "host.name",
167 "host.os.type",
168 "user.name",
169 "process.name",
170 "process.parent.name",
171 "process.command_line",
172 "process.parent.command_line"
173]
Triage and analysis
Investigating Suspicious IDE Extension Installation from VSIX
An IDE CLI (code, cursor, codium, or a compatible editor) was invoked with --install-extension against a
.vsix file. The VSIX path is under a staging directory (Users\Public, AppData\Local\Temp, /tmp,
/var/tmp, /private/tmp, /dev/shm), or the parent is a script host or installer rather than the editor itself.
Sideloading a VSIX is a known way to persist or gain execution through a malicious IDE extension.
Possible investigation steps
- From
process.command_line, extract the.vsixpath and the editor binary (code,code.exe,cursor,codium). - Review
process.parent.nameandprocess.parent.command_lineto see whether a script host (powershell,pwsh,mshta,wscript,cscript,msiexec,python*,py.exe,node,bun,osascript) launched the install. - Hash the VSIX and compare it with the extension the editor actually installed under
.vscode/extensionsor the equivalent Cursor or VSCodium extensions directory. - On the same host and user, look for follow-on child processes from the extension host, new outbound connections, and files written by the extension.
False positive analysis
- Extension development often installs a locally built VSIX from PowerShell, pwsh, Node, Bun, or Python, including from a temp directory. Confirm the VSIX path, publisher, and parent script with the developer before excluding.
- Scope exceptions to a known VSIX path, parent command line, host, or user. Do not broadly exclude
--install-extensionor the editor binary.
Response and remediation
- If the VSIX is unapproved, uninstall the extension, remove the VSIX, and restart the editor.
- Quarantine the VSIX, collect its hash, and hunt that hash and command line on other hosts.
- If a script host launched the install, investigate that parent for a downloader or installer and remove it.
- Rotate tokens or credentials the extension could have read from the user profile or workspace.
References
Related rules
- Suspicious Command Execution from Visual Studio Code
- Long Base64 Encoded Command via Scripting Interpreter
- LLM-Based Curl Activity Triage
- LLM-Based Wget Activity Triage
- Initial Access via File Upload Followed by GET Request