Basis/KTX transcoders default to loading code from jsDelivr at runtime, unversioned and without SRI
Description
The KTX and Basis transcoders default to loading their JavaScript and WebAssembly from jsDelivr at runtime, from an unversioned path:
// src/compressed-textures/basis/utils/setBasisTranscoderPath.ts
export const basisTranscoderUrls = {
jsUrl: 'https://cdn.jsdelivr.net/npm/pixi.js/transcoders/basis/basis_transcoder.js',
wasmUrl: 'https://cdn.jsdelivr.net/npm/pixi.js/transcoders/basis/basis_transcoder.wasm',
};
// src/compressed-textures/ktx2/utils/setKTXTranscoderPath.ts -> same, /ktx/libktx.{js,wasm}
Any application that decodes Basis or KTX2 textures and hasn't called setBasisTranscoderPath / setKTXTranscoderPath fetches executable code and a wasm binary from a third-party CDN at runtime, by default. Two things about the default worth reconsidering:
- The path is unversioned.
npm/pixi.jsresolves to whatever jsDelivr currently serves as latest, so the transcoder a page loads is not pinned to the pixi.js version the app was built against. A major transcoder change (or a bad publish) reaches production without a version bump on the app's side. - No integrity. The script is injected with no Subresource Integrity, so the app is trusting jsDelivr's delivery at load time rather than a hash it reviewed.
This is @advanced and overridable, and jsDelivr is a reputable CDN, so this isn't a report of a live exploit — it's a hardening/defaults note. But "loads code from a CDN by default, unpinned, unhashed" is a property a lot of adopters won't realise they have, and it defeats a strict script-src/connect-src CSP unless they know to add jsDelivr or override the paths.
Suggested changes (any one helps)
- Pin the default URL to the installed pixi version, e.g.
.../npm/pixi.js@${VERSION}/transcoders/..., so the transcoder matches the build. - Document prominently (in the compressed-texture guide) that the default reaches jsDelivr and how to self-host with
setBasisTranscoderPath/setKTXTranscoderPath, plus the CSP entries needed if kept. - Optionally ship the transcoders as package files and default to a same-origin/bundler-resolved path rather than a CDN.
Verified on [email protected] and against dev. Found while auditing capability use across popular browser libraries with frostjs.
Source: pixijs/pixijs