Threat Model

March 17, 2026 · View on GitHub

Based on the STRIDE framework.

Last updated: 2026-03-17


Scope

This threat model covers the Git ID Switcher VS Code extension. The extension manages Git identities (name, email, SSH keys, GPG keys) and interacts with external binaries (git, ssh-add, ssh-keygen) via child processes.

Trust Boundaries

┌─────────────────────────────────────────────────┐
│  VS Code Extension Host (trusted runtime)       │
│  ┌───────────────────────────────────────────┐  │
│  │  Git ID Switcher                          │  │
│  │  ┌─────────────┐  ┌────────────────────┐  │  │
│  │  │ User Config  │  │ Security Layer     │  │  │
│  │  │ (settings)   │  │ (validators,       │  │  │
│  │  │              │  │  allowlist,         │  │  │
│  │  │              │  │  secureExec)        │  │  │
│  │  └──────┬───────┘  └────────┬───────────┘  │  │
│  └─────────┼───────────────────┼──────────────┘  │
│            │ trust boundary    │                  │
└────────────┼───────────────────┼──────────────────┘
             │                   │
     ┌───────▼───────┐  ┌───────▼───────┐
     │ User Settings │  │ External      │
     │ (JSON)        │  │ Binaries      │
     │               │  │ (git, ssh-add,│
     │               │  │  ssh-keygen)  │
     └───────────────┘  └───────────────┘

Spoofing (S)

S1: Git Identity Forgery

AspectDetail
ThreatAttacker modifies Git identity to impersonate another developer
Attack VectorMalicious workspace settings override identity config
Existing MitigationsVS Code Workspace Trust integration; extension enters restricted mode in untrusted workspaces; identity changes are logged via security audit logger
Residual RiskLow — trusted workspaces can modify identity by design

S2: SSH Key Substitution

AspectDetail
ThreatAttacker replaces SSH key path to load a malicious key
Attack VectorModified sshKeyPath in configuration
Existing MitigationsPath validation pipeline (null bytes, traversal, symlinks, control chars, invisible Unicode incl. Bidi override — CVE-2021-42574); SSH key basename exact-match; key file type/size/permission validation; regular files only
Residual RiskVery low — multi-layer path validation blocks traversal, symlink, and Trojan Source attacks; SSH key matching is exact

S3: Extension Impersonation (Typosquatting)

AspectDetail
ThreatAttacker publishes a fake extension with a similar name to trick users into installing it
Attack VectorVS Code Marketplace / Open VSX typosquatting (similar publisher name, extension name, or icon)
Existing MitigationsCosign keyless VSIX signing (users can cryptographically verify authenticity); SLSA Level 3 build provenance; README fingerprint section (Publisher ID, Extension ID, repository URL); SECURITY.md typosquat reporting procedure; CI-enforced package.json URL validation
Residual RiskMedium — most users do not verify signatures; Verified Publisher badge planned for additional visual trust signal

Tampering (T)

T1: Configuration File Tampering

AspectDetail
ThreatAttacker modifies VS Code settings to inject malicious config
Attack VectorDirect modification of .vscode/settings.json
Existing MitigationsJSON schema validation (configSchema.ts); field length limits; type enforcement; identity duplicate detection at schema + runtime; prototype pollution defense (__proto__, constructor, prototype keys rejected via Object.hasOwn())
Residual RiskLow — VS Code Workspace Trust gates untrusted workspace settings

T2: Command Argument Injection

AspectDetail
ThreatAttacker injects malicious arguments into git/ssh commands
Attack VectorCrafted identity fields (name, email) containing shell metacharacters
Existing MitigationsexecFile() bypasses shell interpretation; strict command allowlist; argument count (max 20) and length (max 256) limits; flag injection prevention; flag validator rejects unsafe characters
Residual RiskVery low — execFile() + allowlist eliminates shell injection

T3: VSIX Binary Tampering

AspectDetail
ThreatSupply chain attack replaces legitimate VSIX with malicious version
Attack VectorCompromised marketplace, CDN, or download source
Existing MitigationsSLSA Level 3 build provenance; Cosign keyless VSIX signing (failure blocks release); Harden Runner egress-policy block on publish job with explicit allowed-endpoints; Trivy pre-publish scan; CycloneDX SBOM with attestation; npm audit high severity gate in CI
Residual RiskVery low — cryptographic verification available via cosign verify-blob and gh attestation verify; egress blocking limits exfiltration during build

Repudiation (R)

R1: Identity Switch Denial

AspectDetail
ThreatUser denies having switched Git identity
Attack VectorNo audit trail of identity operations
Existing MitigationsSecurity audit logger records IDENTITY_SWITCH, SSH_KEY_LOAD, SSH_KEY_REMOVE, CONFIG_CHANGE events with timestamps; dual logging to Output Channel + file; sensitive data redaction
Residual RiskLow — file logging is opt-in; Output Channel logs are ephemeral

Information Disclosure (I)

I1: SSH Key Path Leakage

AspectDetail
ThreatSSH key filesystem paths exposed in logs or error messages
Attack VectorVerbose error messages, debug logs
Existing MitigationssensitiveDataDetector.ts redacts paths in logs; MAX_LOG_STRING_LENGTH truncation; redactAllSensitive mode for maximum privacy; path sanitization in security logger
Residual RiskLow — paths visible in VS Code settings by design (user's own data)

I2: GPG Key ID Exposure

AspectDetail
ThreatGPG key IDs leaked through logs or UI
Attack VectorStatus bar display, notification messages
Existing MitigationsGPG key IDs are intentionally displayed (they are public identifiers); sensitive data detector masks longer secret-like strings
Residual RiskAccepted — GPG key IDs are public by design

Denial of Service (D)

D1: Resource Exhaustion via Identities

AspectDetail
ThreatAttacker creates thousands of identities to exhaust memory
Attack VectorMalicious workspace configuration
Existing MitigationsMAX_IDENTITIES limit (hardcoded, not configurable); field length limits on all string fields; icon byte length limit
Residual RiskVery low — hardcoded limits prevent abuse

D2: Command Execution Hang

AspectDetail
ThreatExternal binary hangs, blocking extension
Attack VectorUnresponsive git server, ssh-agent deadlock
Existing MitigationsCommand-specific timeouts (git: 10s, ssh-add: 5s, ssh-keygen: 5s); custom TimeoutError class; user-configurable timeouts with range validation (1-300s); ssh-add -D (bulk key deletion) removed from allowlist — only individual key removal (-d) permitted
Residual RiskVery low — all external calls have timeouts

D3: Log File Growth

AspectDetail
ThreatLog files consume excessive disk space or symlink-based log tampering
Attack VectorHigh-frequency operations triggering repeated logging; symlink replacement of log file between check and open
Existing MitigationsConfigurable maxFileSize and maxFiles with rotation (range-validated: 100KB-100MB, 1-100 files); file logging is opt-in; per-event-type rate limiter (10 events/10s window) prevents log flooding; O_NOFOLLOW flag on file open + fstat() symlink check (TOCTOU mitigation)
Residual RiskVery low — rotation + rate limiting + symlink protection prevent abuse

Elevation of Privilege (E)

E1: Command Injection via Shell

AspectDetail
ThreatAttacker executes arbitrary commands through the extension
Attack VectorShell metacharacters in user input passed to exec()
Existing MitigationsexecFile() used exclusively (no shell); strict command allowlist (git, ssh-add, ssh-keygen only); binary path resolution prevents PATH pollution; argument validation with allowlisted flags; ESLint no-restricted-imports enforces exec/execSync ban at lint time
Residual RiskVery low — no shell interpretation path exists; lint-time enforcement prevents regressions

E2: PATH Pollution

AspectDetail
ThreatAttacker places malicious binary earlier in PATH
Attack VectorModified PATH environment variable
Existing MitigationsbinaryResolver.ts resolves absolute paths using system which/where from hardcoded locations (/usr/bin/which, C:\Windows\System32\where.exe); resolved paths cached with 30-minute TTL (re-verified periodically); git.path setting validated via git --version output check; which fallback triggers user-visible warning (session-once); ESLint no-restricted-imports blocks exec/execSync imports
Residual RiskVery low — TTL-based cache prevents stale binary paths; git.path spoofing detected by version check

E3: Workspace Trust Bypass

AspectDetail
ThreatExtension operates in untrusted workspace
Attack VectorOpening a malicious repository
Existing MitigationsworkspaceTrust.ts checks trust status; extension enters restricted mode when untrusted; commands are blocked in restricted mode
Residual RiskVery low — VS Code enforces trust boundary

Unmitigated Threats (Future Work)

IDThreatCategoryNotes
T4Malicious VS Code extension hostTamperingOut of scope — requires VS Code platform-level mitigation
I3Memory inspection of loaded SSH keysInfo DisclosureOut of scope — OS-level memory protection required