{
  "entrypoint_kind": "api_remote",
  "entrypoint_detail": "HTTP GET /api/{namespace}/{extension}/{version}/file/{iconName} (variant) and GET /vscode/unpkg/{ns}/{ext}/{ver}/extension/{path} (control) - serves files extracted from published VSIX packages; the iconName is attacker-controlled via package.json \"icon\"",
  "service_started": true,
  "healthcheck_passed": true,
  "target_path_reached": true,
  "runtime_stack": [
    "postgresql-16.2",
    "openvsx-server-spring-boot-3.5.14-jetty",
    "eclipse-temurin:25-jdk"
  ],
  "versions_tested": [
    {
      "label": "vulnerable",
      "ref": "v1.0.1",
      "commit_sha": "e92a1a7a448be08570cc4c4969717ed3e2260015",
      "jar": "bundle/logs/openvsx-server-v1.0.1.jar"
    },
    {
      "label": "fixed",
      "ref": "v1.0.2",
      "commit_sha": "9491f32a6d459a4d499c5028d37c0d0386771e9f",
      "jar": "bundle/logs/openvsx-server-v1.0.2.jar"
    }
  ],
  "variant_request": {
    "method": "GET",
    "url": "http://localhost:8080/api/vpub/vext/1.0.0/file/payload.html",
    "vulnerable_response": {
      "status": "200 OK",
      "content_type": "text/html",
      "content_security_policy": "MISSING",
      "content_disposition": "MISSING",
      "inline_html": true
    },
    "fixed_response": {
      "status": "200 OK",
      "content_type": "text/plain;charset=utf-8",
      "content_security_policy": "default-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; sandbox",
      "content_disposition": "MISSING",
      "inline_html": false
    }
  },
  "control_request": {
    "method": "GET",
    "url": "http://localhost:8080/vscode/unpkg/vpub/vext/1.0.0/extension/payload.html",
    "vulnerable_inline_html": true,
    "fixed_inline_html": false
  },
  "metadata_evidence": {
    "endpoint": "GET /api/vpub/vext/1.0.0",
    "advertised_icon_url": "http://localhost:8080/api/vpub/vext/1.0.0/file/payload.html",
    "comment": "The variant surface (icon URL) is advertised to victims in the extension metadata files.icon field on both versions."
  },
  "proof_artifacts": [
    "logs/vuln_variant/variant_repro.log",
    "logs/vuln_variant/vuln_variant_headers.txt",
    "logs/vuln_variant/vuln_variant_body.html",
    "logs/vuln_variant/fixed_variant_headers.txt",
    "logs/vuln_variant/fixed_variant_body.html",
    "logs/vuln_variant/vuln_control_headers.txt",
    "logs/vuln_variant/fixed_control_headers.txt",
    "logs/vuln_variant/vuln_publish.json",
    "logs/vuln_variant/fixed_publish.json",
    "logs/vuln_variant/vuln_metadata.json",
    "logs/vuln_variant/fixed_metadata.json",
    "logs/vuln_variant/vuln_icon_url.txt",
    "logs/vuln_variant/fixed_icon_url.txt",
    "logs/vuln_variant/variant_result.json",
    "logs/vuln_variant/variant_verdict.txt",
    "logs/vuln_variant/server_vuln_v1.0.1.log",
    "logs/vuln_variant/server_fixed_v1.0.2.log",
    "logs/vuln_variant/fixed_version.txt",
    "logs/vuln_variant/latest_version.txt"
  ],
  "verdict": {
    "variant_on_vulnerable": true,
    "variant_bypass_on_fixed": false,
    "outcome": "alternate_trigger_on_vulnerable_only"
  },
  "notes": "Real Open VSX Registry server built from source at v1.0.1 (e92a1a7a) and v1.0.2 (9491f32a), running with PostgreSQL 16.2 and JDK 25. The variant VSIX smuggles an HTML file as the extension icon; both the variant endpoint (/api/.../file/payload.html) and the control endpoint (/vscode/unpkg/.../payload.html) were exercised on both versions. Script run twice with identical results; no leftover containers."
}
