{
  "variant_id": "cve-2026-54466-valid-length-bypass",
  "created_at": "2026-07-16T10:00:00Z",
  "variant_summary": "The 0.7.5 fix only guards against oversized length headers (_length > _maxLength) in the draft-75 length accumulator. The actual message-corruption mechanism depends on two independent bugs the fix does not address: (A) _parseLeadingByte does not reset _buffer when entering binary frame mode, and (B) stage 2 treats 0xFF as a frame terminator even in skip mode. A binary frame with a valid length (within _maxLength) that is >= the next frame's wire size triggers the same stale-buffer emission and sentinel loss. Confirmed as a bypass on websocket-driver@0.7.5.",
  "relation": "newer_version_sibling",
  "origin_kind": "pruva_variant",
  "repository": "https://github.com/faye/websocket-driver-node",
  "submitted_target": {
    "target_kind": "npm_package",
    "version": "0.7.4",
    "ref": "0.7.4",
    "commit_sha": "5f711f089234a46f8d1e50054115ea169257eaa4",
    "display": "websocket-driver@0.7.4 (commit 5f711f0)"
  },
  "variant_target": {
    "target_kind": "npm_package",
    "version": "0.7.5",
    "ref": "0.7.5",
    "commit_sha": "5d6a9aaf5f019007d917bd9ddc7eeb775c86cc1f",
    "display": "websocket-driver@0.7.5 (commit 5d6a9aa)"
  },
  "same_root_cause_confidence": "high",
  "same_surface_confidence": "high",
  "claimed_surface": "draft-75/76 length header abuse -> message corruption",
  "validated_surface": "draft-75/76 valid-length binary frame -> stale buffer emission via 0xFF in skip mode -> sentinel loss",
  "required_entrypoint_kind": "network_api",
  "required_entrypoint_detail": "Driver.server(...).parse(chunk) / Server.parse(chunk) with draft-75 handshake (no Sec-WebSocket-* headers)",
  "attacker_controlled_input": "Raw bytes on an established draft-75/76 WebSocket connection: a binary frame header (0x80 + valid length byte) followed by a sentinel text frame",
  "trigger_path": "Server.parse -> Server.http -> Draft75 -> Draft75.parse -> case 0 (_parseLeadingByte, high bit set, _buffer NOT reset) -> case 1 (length accumulator, _length=30 <= _maxLength, fix guard passes) -> case 2 (skip mode, sentinel 0xFF triggers stale _buffer emission)",
  "observed_impact_class": "other",
  "exploitability_confidence": "high",
  "evidence_scope": "runtime",
  "runtime_manifest_present": true,
  "end_to_end_target_reached": true,
  "inferred": false,
  "file_path": "lib/websocket/driver/draft75.js",
  "line_start": 57,
  "line_end": 90,
  "secondary_anchors": [
    {
      "file_path": "lib/websocket/driver/draft75.js",
      "line_start": 95,
      "line_end": 110
    }
  ],
  "review_scope_paths": [
    "lib/websocket/driver/draft75.js",
    "lib/websocket/driver/draft76.js"
  ],
  "artifact_refs": {
    "variant_manifest": "bundle/vuln_variant/variant_manifest.json",
    "validation_verdict": "bundle/vuln_variant/validation_verdict.json",
    "runtime_manifest": "bundle/vuln_variant/runtime_manifest.json",
    "repro_log": "bundle/logs/variant_repro.log",
    "root_cause_equivalence": "bundle/vuln_variant/root_cause_equivalence.json",
    "reproducer": [
      "bundle/vuln_variant/reproduction_steps.sh",
      "bundle/vuln_variant/variant_harness.js"
    ]
  }
}
