canPlayType() and MediaSource.isTypeSupported() reveal which system codec libraries are installed. Different environments have different FFmpeg versions or VideoToolbox availability, so these APIs return different results for the same browser profile. CreepJS flags this as differing media.mimeTypes.
A Linux server with FFmpeg 6.x spoofing a macOS profile still reports a Linux-server codec matrix. Easy correlation signal.
Root cause
MP4Decoder::IsSupportedType() and MatroskaDecoder::IsSupportedType() call PDMFactory::Supports() which enumerates actual system decoders. Useful for playback decisions, but leaks the host's codec stack to any page that asks.
Proposed fix
Add a media:spoof_codecs config key. When enabled, short-circuit IsSupportedType() to return true for any valid codec string without consulting PDMFactory. Trade-off: claims support for codecs that may not decode. Fine for fingerprint resistance; opt-in so default behaviour is unchanged.
canPlayType()andMediaSource.isTypeSupported()reveal which system codec libraries are installed. Different environments have different FFmpeg versions or VideoToolbox availability, so these APIs return different results for the same browser profile. CreepJS flags this as differingmedia.mimeTypes.A Linux server with FFmpeg 6.x spoofing a macOS profile still reports a Linux-server codec matrix. Easy correlation signal.
Root cause
MP4Decoder::IsSupportedType()andMatroskaDecoder::IsSupportedType()callPDMFactory::Supports()which enumerates actual system decoders. Useful for playback decisions, but leaks the host's codec stack to any page that asks.Proposed fix
Add a
media:spoof_codecsconfig key. When enabled, short-circuitIsSupportedType()to returntruefor any valid codec string without consultingPDMFactory. Trade-off: claims support for codecs that may not decode. Fine for fingerprint resistance; opt-in so default behaviour is unchanged.