- jetbrains-research-brief.md: 29 sources, confidence 0.88 — input for v6.6.0 JetBrains/IntelliJ extension scanning. Covers plugin format, install paths per OS+product, Marketplace API, threat landscape (zero confirmed-malicious cases), check-mapping table, sandbox reuse verdict, risk register. - ide-scan-url-support.md: retroactive plan doc for v6.4.0 URL-fetch feature.
7.6 KiB
7.6 KiB
Plan: /security ide-scan <url> — ekstern URL-support (v6.4.0)
Status: Planlagt
Mål-release: v6.4.0
Skrevet: 2026-04-17
Motivasjon: Hovedbruk av ide-scan er pre-installasjonsverifisering — sjekk en extension FØR du installerer den. Dagens scanner krever at extension allerede er installert (~/.vscode/extensions/) eller at target peker til en allerede utpakket mappe.
Støttede URL-typer
| Type | Eksempel | Fetch-strategi |
|---|---|---|
| VS Code Marketplace | https://marketplace.visualstudio.com/items?itemName=anthropic.claude-code |
POST til /_apis/public/gallery/.../vspackage (undokumentert men stabilt mønster) |
| OpenVSX | https://open-vsx.org/extension/anthropic/claude-code |
Offentlig API: /api/{pub}/{name}/{version}/file/{pub}.{name}-{version}.vsix |
| Direkte .vsix | https://example.com/ext.vsix |
Enkel GET |
| GitHub repo | https://github.com/anthropic/claude-code |
Bygg fra source? (se "Åpen beslutning") |
Sikkerhetsmodell
VSIX er en ZIP-fil. Extraction er den største angrepsflaten — vi må forhindre:
- Zip-slip (
../../etc/passwdi filnavn) - Symlink-angrep (VSIX-spec tillater ikke symlinks, men parser må avvise dem)
- Zip-bomber (10MB komprimert → 100GB ukomprimert)
- Path traversal via absolutte paths i entry-navn
- Unicode-normalization-angrep (NFC/NFD-forskjeller som omgår path-checks)
Caps:
- Max komprimert størrelse: 50MB (VSIX over dette er mistenkelig)
- Max ukomprimert størrelse: 500MB
- Max entries: 10 000
- Max depth: 20
- Max expansion ratio: 100x (sum ukomprimert / sum komprimert)
Arkitektur
/security ide-scan <url>
→ commands/ide-scan.md (dispatcher)
→ bin/llm-security.mjs eller direkte
→ scanners/ide-extension-scanner.mjs
├─ url-detect: pattern-match for supported URL typer
├─ lib/vsix-fetch.mjs (NY)
│ ├─ detectUrlType(url) → 'marketplace' | 'openvsx' | 'vsix' | 'github'
│ ├─ fetchMarketplaceVsix(publisher, name)
│ ├─ fetchOpenVsxVsix(publisher, name, version)
│ ├─ fetchDirectVsix(url)
│ └─ returnerer { buffer, url, contentType, size, sha256 }
├─ lib/zip-extract.mjs (NY)
│ ├─ zero-dep ZIP-parser (central directory + local file header + deflate via node:zlib)
│ ├─ validateEntry(name) — reject zip-slip, absolute paths, symlinks
│ └─ extractToDir(buffer, tempDir, caps) → Promise<void>
└─ Eksisterende scan-pipeline mot tempDir
Implementasjonssteg
Steg 1: lib/vsix-fetch.mjs (~150 linjer)
- Bruk
fetch()(Node 18+, zero deps) - Kun HTTPS, ingen redirect til HTTP
- Timeout 30s, size-cap 50MB via streaming + abort
- TLS-verifisering default (ikke tillat
--insecure) - SHA-256-beregning underveis
- Marketplace: POST-payload + header
Accept: application/octet-stream— se knowledge/marketplace-api-notes.md (lag den) - OpenVSX: offentlig dokumentert API, enklest
- Returnerer
{ buffer, sourceUrl, sha256, publisher, name, version }
Steg 2: lib/zip-extract.mjs (~250 linjer)
- Parse End of Central Directory (EOCD) fra slutten
- Les Central Directory headers → entries-array
- For hver entry: les Local File Header, inflate med
node:zlib.createInflateRaw - Valideringer PER entry (før skriv):
- Normaliser path (remove
., resolve.., reject absolute) - Avvis hvis path escaper targetDir (via
path.resolve+ prefix-sjekk) - Avvis
external_attrsom indikerer symlink (0xA000 flag) - Akkumulere expansion ratio, abort hvis > 100x
- Normaliser path (remove
- Kun filer, ingen dirs (opprett dirs on-the-fly)
- Tests: fixtures med kjente angrep (zip-slip fixture, symlink fixture, bomb fixture)
Steg 3: Utvid ide-extension-scanner.mjs
- Early-detect:
if (target.startsWith('http')) → fetch + extract → scan(tempDir) - Ny option:
--online-source <marketplace|openvsx>(default: auto-detect fra URL) - Cleanup:
try/finallymedrm(tempDir, { recursive: true, force: true }) - Error-mapping: network errors → "unreachable", signature fail → "tamper", zip fail → "malformed"
- Envelope.meta.source:
{ type: 'url', url, sha256, publisher, name, version }
Steg 4: CLI + command-dispatcher
bin/llm-security.mjs: passthrough, ingen endring nødvendig (target er allerede første arg)commands/ide-scan.md: oppdater eksempler + flagg-dokumentasjon
Steg 5: Tester (~20 nye)
- Mock HTTP-server (node:http) for fetch-tester
- Fixture-VSIX: bygg en fra
tests/fixtures/ide-extensions/root-benign/publisher.benign-ext-1.0.0/viazip -ri test-setup - Zip-slip fixture: VSIX med
../../etc/passwdentry - Zip-bomb fixture: 1KB komprimert → 10GB ukomprimert (syntetisk)
- Integration: OpenVSX-mock → fetch → scan → envelope
- Unit: detectUrlType, extractToDir med caps
Steg 6: Knowledge + docs
knowledge/marketplace-api-notes.md: dokumenter undokumenterte Marketplace-endpoints + stabilitetdocs/ide-scan-url-usage.md: eksempler for pre-install-workflow- CHANGELOG: v6.4.0-seksjon
- Plugin README: legg til URL-eksempler på
/security ide-scan - Rot-README: oppdater til v6.4.0 (hvis tests passerer 1300+ og URL-support er feature-highlight)
Steg 7: Versjon + ship
npm run bump -- 6.4.0- Test-suite grønn
- Smoke test:
llm-security ide-scan https://open-vsx.org/extension/anthropic/claude-code— skal funke (åpen API) - Commit + push til Forgejo (main, pre-autorisert)
Åpne beslutninger (diskuter i neste sesjon)
- GitHub repo som URL — skal vi bygge extension fra source? Legger til build-step (node+npm installert +
npm install + vsce package). Stor kompleksitet. Foreslår: IKKE støtt GitHub i v6.4.0 — bare VSIX-baserte kilder. - Marketplace API-stabilitet — undokumentert endpoint kan endres. Fall-back: OpenVSX-lookup hvis Marketplace feiler (de fleste Marketplace-extensions finnes også på OpenVSX).
- Cache — bør vi cache nedlastede VSIX i
~/.cache/llm-security/vsix/(med SHA-256 som key, 7-dagers TTL)? Sparer båndbredde ved gjentatte scans. JA — enkelt og skru-av-bart via--no-cache. - Signatur-verifisering av VSIX — VS Code har begynt å signere publisher uploads (
.signature.p7si VSIX). Bør vi verifisere? Krever X.509-parsing (Node harnode:cryptomen P7S er kompleks). Foreslår: v6.5.0, ikke v6.4.0.
Akseptansekriterier
llm-security ide-scan https://open-vsx.org/extension/anthropic/claude-codereturnerer envelope med korrekt publisher/name/versionllm-security ide-scan https://marketplace.visualstudio.com/items?itemName=anthropic.claude-codefungerer (forutsatt endpoint er stabilt)- Zip-slip-fixture resulterer i BLOCK-verdict, ingen filer skrevet utenfor tempDir
- Zip-bomb-fixture stoppes ved 100x expansion ratio
- Temp-dir renses i alle exit-paths (success, error, abort)
- Nettverksfeil → tydelig feilmelding, ikke stack trace
- Scan av ekte Marketplace-extension (f.eks.
ms-python.python) fullfører på < 30s på normal forbindelse - Test-suite 1300+ grønn
Estimat
- Kode: ~600 linjer (vsix-fetch: 150, zip-extract: 250, integrasjon: 100, tester: 100)
- Tid: 1 fokusert sesjon med auto mode
- Risiko: Moderat — zip-extraction er kjent angrepsvektor, trenger grundige tester. Fetch er enkelt.
Referanser
- OpenVSX API: https://open-vsx.org/swagger-ui
- VS Code Marketplace (undokumentert): https://github.com/microsoft/vscode-vsce/blob/main/src/publish.ts
- ZIP format spec: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
- Zip-slip CVE: https://snyk.io/research/zip-slip-vulnerability
- Node fetch + streaming: https://nodejs.org/api/globals.html#fetch