ktg-plugin-marketplace/plugins/llm-security/knowledge/marketplace-api-notes.md
Kjell Tore Guttormsen fe0193956d feat(llm-security): /security ide-scan <url> — Marketplace/OpenVSX/direct VSIX (v6.4.0)
Pre-installation verification of VS Code extensions via URL — fetch a remote
VSIX, extract it in a hardened sandbox, and run the existing IDE scanner
pipeline against it. No npm dependencies.

Sources:
- VS Code Marketplace (publisher.gallery.vsassets.io direct download)
- OpenVSX (open-vsx.org official API)
- Direct .vsix HTTPS URLs

Defenses:
- HTTPS-only, TLS verified, manual redirect with per-source host whitelist
- 30s total timeout via AbortController
- 50MB compressed cap, 500MB uncompressed, 100x expansion ratio
- Zero-dep ZIP extractor: zip-slip, absolute paths, drive letters, NUL bytes,
  symlinks (Unix mode 0xA000), depth limits, ZIP64 rejected, encrypted rejected
- SHA-256 streamed during fetch, surfaced in meta.source
- Temp dir cleanup in all paths (try/finally)

Files:
- scanners/lib/vsix-fetch.mjs (HTTPS fetcher, host whitelist, streaming SHA-256)
- scanners/lib/zip-extract.mjs (zero-dep parser with hardening caps)
- knowledge/marketplace-api-notes.md (endpoint reference)
- 3 test files (48 tests added: vsix-fetch, zip-extract, ide-extension-url)

Tests: 1296 → 1344 (all green).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 17:16:26 +02:00

84 lines
3.1 KiB
Markdown

# VS Code Marketplace + OpenVSX API notes
Reference notes for `scanners/lib/vsix-fetch.mjs`. These endpoints are used to
download VSIX packages for `/security ide-scan <url>` (v6.4.0).
## VS Code Marketplace
**Status:** Undocumented but stable. Used by the `vsce` CLI and by VS Code itself.
### Direct VSIX download (the URL we use)
```
https://{publisher}.gallery.vsassets.io/_apis/public/gallery/publisher/{publisher}/extension/{name}/latest/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage
```
- `{publisher}` and `{name}` come from the `itemName=publisher.name` query
parameter on `https://marketplace.visualstudio.com/items`.
- `latest` resolves to the most recent stable version. Specific versions can
be requested by replacing `latest` with `<version>`.
- The response is a ZIP (VSIX) with `Content-Type: application/octet-stream`.
- May redirect to `*.gallerycdn.vsassets.io`. Our fetcher allows redirects only
to that host family, never to arbitrary hosts.
### `extensionquery` (not used here, listed for completeness)
```
POST https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery
Headers:
Accept: application/json;api-version=3.0-preview.1
Content-Type: application/json
Body:
{ "filters": [{ "criteria": [{ "filterType": 7, "value": "publisher.name" }] }],
"flags": 914 }
```
This returns metadata (versions, publisher info, statistics) but is heavier
than the direct download, and parsing the response shape is brittle. We keep
the direct download path for v6.4.0.
### Stability risk
Microsoft has changed Marketplace APIs in the past without warning. Mitigation:
- Fall back to OpenVSX when both options exist (most extensions are mirrored).
- Document the endpoint here so that breakage can be diagnosed quickly.
- All callers receive a single `Error` with a descriptive message — no stack
traces leak through to the scanner envelope.
## OpenVSX (Eclipse Foundation)
**Status:** Officially documented at https://open-vsx.org/swagger-ui.
### Resolve "latest" version
```
GET https://open-vsx.org/api/{publisher}/{name}/latest
```
Returns JSON. We extract `.version` and use it for the next request.
### Direct VSIX download
```
GET https://open-vsx.org/api/{publisher}/{name}/{version}/file/{publisher}.{name}-{version}.vsix
```
Returns the raw VSIX. May redirect to `openvsxorg.blob.core.windows.net`.
## Caps & defenses (shared by all sources)
- TLS verification enabled (no `--insecure` opt-in).
- HTTPS only. Plain HTTP is rejected at `detectUrlType` and at fetch time.
- Manual redirect handling. Allowed hosts whitelisted per source type.
- 30-second total timeout via `AbortController`.
- 50MB compressed VSIX cap. Streaming reader aborts when cap exceeded.
- SHA-256 computed during streaming for `meta.source.sha256`.
## What is NOT supported (v6.4.0)
- GitHub repo URLs — would need `npm install` + `vsce package` build step.
- VS Code `code:` protocol URIs.
- VSIX signature verification (`.signature.p7s`). Deferred to v6.5.0.
- ZIP64 archives. Real VSIX never approaches the 4 GB threshold.
- Encrypted ZIP entries (general-purpose flag bit 0).