--- a/media/filters/hls_network_access_impl.cc +++ b/media/filters/hls_network_access_impl.cc @@ -99,9 +99,20 @@ void HlsNetworkAccessImpl::ReadMediaSegment(const hls::MediaSegment& segment, weak_factory_.GetWeakPtr(), std::move(cb)); } + // RFC 8216 4.3.2.4: an EXT-X-KEY with METHOD=AES-128 "does not apply to + // Media Initialization Sections". The current code concatenates the init + // segment in front of the media segment and runs AES-CBC over the WHOLE + // buffer, which turns a cross-origin init segment into attacker-controlled + // ciphertext. Until decryption is taught about the init/media boundary, do + // not prepend the init segment when identity AES is in use. + bool aes_identity = false; + if (auto enc = segment.GetEncryptionData()) { + aes_identity = enc->GetMethod() == hls::XKeyTagMethod::kAES128 || + enc->GetMethod() == hls::XKeyTagMethod::kAES256; + } HlsDataSourceProvider::SegmentQueue queue; - if (include_init) { + if (include_init && !aes_identity) { if (auto init = segment.GetInitializationSegment()) { queue.emplace(init->GetUri(), init->GetByteRange(), false); } }