Bug 1802216 - Don't start nsCompressedAudioVideoImageDetector and nsUnknownDecoder in the same time r=farre,necko-reviewers,valentin

We should only need to start nsCompressedAudioVideoImageDetector when
nsUnknownDecoder is not going to be started. Generally, they are not
designed to be working together.

Differential Revision: https://phabricator.services.mozilla.com/D163063
This commit is contained in:
Sean Feng 2022-12-02 18:29:35 +00:00
parent a1e9c1d43b
commit 304592ae1b
5 changed files with 46 additions and 23 deletions

View File

@ -3085,8 +3085,8 @@ bool HttpBaseChannel::ShouldBlockOpaqueResponse() const {
// * `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff`
// * `OpaqueResponseBlocker::ValidateJavaScript`
OpaqueResponse HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff(
bool& aCompressedMediaAndImageDetectorStarted) {
OpaqueResponse
HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff() {
MOZ_ASSERT(XRE_IsParentProcess());
if (!mCachedOpaqueResponseBlockingPref) {
@ -3181,15 +3181,11 @@ OpaqueResponse HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff(
nsresult rv =
mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
if (NS_FAILED(rv) || contentEncoding.IsEmpty()) {
mLoadFlags |= (nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE);
} else {
mListener = new nsCompressedAudioVideoImageDetector(
mListener, &HttpBaseChannel::CallTypeSniffers);
aCompressedMediaAndImageDetectorStarted = true;
if (NS_SUCCEEDED(rv) && !contentEncoding.IsEmpty()) {
return OpaqueResponse::SniffCompressed;
}
mLoadFlags |= (nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE);
return OpaqueResponse::Sniff;
}

View File

@ -80,7 +80,7 @@ enum CacheDisposition : uint8_t {
kCacheUnknown = 5
};
enum class OpaqueResponse { Block, Alllow, Sniff };
enum class OpaqueResponse { Block, Alllow, SniffCompressed, Sniff };
/*
* This class is a partial implementation of nsIHttpChannel. It contains code
@ -632,8 +632,7 @@ class HttpBaseChannel : public nsHashPropertyBag,
bool ShouldBlockOpaqueResponse() const;
OpaqueResponse PerformOpaqueResponseSafelistCheckBeforeSniff(
bool& aCompressedMediaAndImageDetectorStarted);
OpaqueResponse PerformOpaqueResponseSafelistCheckBeforeSniff();
OpaqueResponse PerformOpaqueResponseSafelistCheckAfterSniff(
const nsACString& aContentType, bool aNoSniff);

View File

@ -313,6 +313,7 @@ nsresult OpaqueResponseBlocker::EnsureOpaqueResponseIsAllowedAfterSniff(
AllowResponse();
return NS_OK;
case OpaqueResponse::Sniff:
case OpaqueResponse::SniffCompressed:
break;
}

View File

@ -1535,9 +1535,8 @@ nsresult nsHttpChannel::CallOnStartRequest() {
// are the checks for Opaque Response Blocking to ensure that we block as many
// cross-origin responses with CORS headers as possible that are not either
// Javascript or media to avoid leaking their contents through side channels.
bool compressedMediaAndImageDetectorStarted = false;
OpaqueResponse opaqueResponse = PerformOpaqueResponseSafelistCheckBeforeSniff(
compressedMediaAndImageDetectorStarted);
OpaqueResponse opaqueResponse =
PerformOpaqueResponseSafelistCheckBeforeSniff();
if (opaqueResponse == OpaqueResponse::Block) {
SetChannelBlockedByOpaqueResponse();
CancelWithReason(NS_ERROR_FAILURE,
@ -1595,14 +1594,18 @@ nsresult nsHttpChannel::CallOnStartRequest() {
// If unknownDecoder is not going to be launched, call
// EnsureOpaqueResponseIsAllowedAfterSniff immediately.
if (!unknownDecoderStarted && !compressedMediaAndImageDetectorStarted &&
opaqueResponse == OpaqueResponse::Sniff) {
MOZ_DIAGNOSTIC_ASSERT(mORB);
nsresult rv = mORB->EnsureOpaqueResponseIsAllowedAfterSniff(this);
MOZ_DIAGNOSTIC_ASSERT(!mORB->IsSniffing());
if (!unknownDecoderStarted) {
if (opaqueResponse == OpaqueResponse::SniffCompressed) {
mListener = new nsCompressedAudioVideoImageDetector(
mListener, &HttpBaseChannel::CallTypeSniffers);
} else if (opaqueResponse == OpaqueResponse::Sniff) {
MOZ_DIAGNOSTIC_ASSERT(mORB);
nsresult rv = mORB->EnsureOpaqueResponseIsAllowedAfterSniff(this);
MOZ_DIAGNOSTIC_ASSERT(!mORB->IsSniffing());
if (NS_FAILED(rv)) {
return rv;
if (NS_FAILED(rv)) {
return rv;
}
}
}

View File

@ -0,0 +1,24 @@
<!DOCTYPE html>
<!-- Test verifies that gziped script which parses as Javascript (not JSON) without Content-Type will execute with ORB. -->
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
setup({ single_test: true });
window.has_executed_script = false;
</script>
<!-- www1 is cross-origin, so the HTTP response is CORB-eligible -->
<script src="http://{{domains[www1]}}:{{ports[http][0]}}/fetch/orb/resources/js-unlabeled.js?pipe=gzip|header(Content-Type,)">
</script>
<script>
// Verify what observable effects the <script> tag above had.
// Assertion should hold with and without ORB:
assert_true(window.has_executed_script,
'The cross-origin script should execute');
done();
</script>