{"id":"CVE-2026-48758","title":"@sigstore/core has DSSE payloadType type-binding failure","summary":"@sigstore/core has DSSE payloadType type-binding failure","severity":"medium","cvss":5.4,"cwe":["CWE-347"],"vendor":"sigstore","product":"@sigstore/core","ecosystem":"npm","affected":["@sigstore/core <= 3.2.0"],"patched":["@sigstore/core 3.2.1"],"published":"2026-06-26","updated":"2026-06-26","source":"GHSA","sourceUrl":"https://github.com/advisories/GHSA-jfc7-64v2-mr8c","references":[{"url":"https://github.com/sigstore/sigstore-js/security/advisories/GHSA-jfc7-64v2-mr8c"},{"url":"https://github.com/advisories/GHSA-jfc7-64v2-mr8c"}],"tags":["ghsa","npm"],"ingestedAt":"2026-06-29T13:24:35.283Z","epss":0.00264,"epssPercentile":0.18579,"slug":"CVE-2026-48758","body":"## Overview\n\n### Impact\nThe `preAuthEncoding` function in `@sigstore/core` uses Node.js `'ascii'` encoding when converting the PAE (Pre-Authentication Encoding) string to bytes. This allows `payloadType` to be mutated after signing without invalidating the signature, breaking the type-binding guarantee that DSSE is designed to provide.\n\nIn `packages/core/src/dsse.ts`, the PAE function builds a string containing `payloadType` and then encodes it with `Buffer.from(prefix, 'ascii')`.\n\nIn Node.js, `'ascii'` encoding for string-to-Buffer is equivalent to `'latin1'`, which **truncates characters above U+00FF to their low byte**. This means for any ASCII character, there exist Unicode characters (at U+01xx, U+02xx, etc.) that produce the identical encoded byte:\n\n| Original | Codepoint | Mutant | Codepoint | Encoded byte |\n|----------|-----------|--------|-----------|--------------|\n| `t`      | U+0074    | `Ŵ`    | U+0174    | `0x74`       |\n| `e`      | U+0065    | `ť`    | U+0165    | `0x65`       |\n\nAn attacker can substitute every character in `payloadType` with a Unicode variant whose low byte matches, producing **identical PAE bytes** and a passing signature verification.\n\nAdditionally, `payloadType.length` returns the JavaScript string length (UTF-16 code units) rather than the UTF-8 byte length required by the DSSE spec, though this is only a contributing factor for non-ASCII types.\n\n#### Reproduction\n\n```javascript\nconst { preAuthEncoding } = require('@sigstore/core/dist/dsse.js');\nconst payload = Buffer.from('hello world');\n\nconst original = preAuthEncoding('text/plain', payload);\n// U+01xx chars whose low bytes match the original ASCII chars\nconst mutant = preAuthEncoding('\\u0174\\u0165\\u0178\\u0174/\\u0170\\u016c\\u0161\\u0169\\u016e', payload);\n\nconsole.log('PAE bytes equal:', original.equals(mutant)); // true — should be false\n```\n\n## Affected packages\n\n- `@sigstore/core <= 3.2.0`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `@sigstore/core 3.2.1`","depth":"sunlit","depthScore":30,"depthScoreParts":{"impact":29.7,"likelihood":0.1,"exploitation":0,"ransomware":0},"changes":[]}