Bug 1731778 - Implement COEP: credentialless for cache storage r=edenchuang

Spec: https://fetch.spec.whatwg.org/#ref-for-cross-origin-resource-policy-internal-check

This purpose of this patch is just to implement the spec.

One noticeable thing I did in the patch is I made `CacheResponse` to
include the `credentials mode` of the initial request. Consider the
below scenario:

  1. Create a fetch request with a URL and a specific credential_mode, and put it into cache
  2. Call cache.match by using a URL, but without credential_mode
  3. cache.match() result should be filtered according to the initial request's credential_mode

When applying the `response’s request-includes-credentials is true`
check, the initial request's `credential_mode` is needed because
`request-includes-credentials` is judged by the `credential_mode`.

The rest of the changes are just normal spec alignments.

Differential Revision: https://phabricator.services.mozilla.com/D147803
This commit is contained in:
Sean Feng 2022-06-27 17:07:15 +00:00
Родитель 6acee53f6c
Коммит 8b870c3847
4 изменённых файлов: 30 добавлений и 14 удалений

34
dom/cache/CacheOpParent.cpp поставляемый
Просмотреть файл

@ -226,21 +226,17 @@ void CacheOpParent::ProcessCrossOriginResourcePolicyHeader(
Maybe<mozilla::ipc::PrincipalInfo> principalInfo;
switch (mOpArgs.type()) {
case CacheOpArgs::TCacheMatchArgs: {
loadingCOEP =
mOpArgs.get_CacheMatchArgs().request().loadingEmbedderPolicy();
principalInfo = mOpArgs.get_CacheMatchArgs().request().principalInfo();
const auto& request = mOpArgs.get_CacheMatchArgs().request();
loadingCOEP = request.loadingEmbedderPolicy();
principalInfo = request.principalInfo();
break;
}
case CacheOpArgs::TCacheMatchAllArgs: {
if (mOpArgs.get_CacheMatchAllArgs().maybeRequest().isSome()) {
loadingCOEP = mOpArgs.get_CacheMatchAllArgs()
.maybeRequest()
.ref()
.loadingEmbedderPolicy();
principalInfo = mOpArgs.get_CacheMatchAllArgs()
.maybeRequest()
.ref()
.principalInfo();
const auto& request =
mOpArgs.get_CacheMatchAllArgs().maybeRequest().ref();
loadingCOEP = request.loadingEmbedderPolicy();
principalInfo = request.principalInfo();
}
break;
}
@ -266,6 +262,7 @@ void CacheOpParent::ProcessCrossOriginResourcePolicyHeader(
}
const auto& headers = it->mValue.headers();
const RequestCredentials credentials = it->mValue.credentials();
const auto corpHeaderIt =
std::find_if(headers.cbegin(), headers.cend(), [](const auto& header) {
return header.name().EqualsLiteral("Cross-Origin-Resource-Policy");
@ -294,11 +291,22 @@ void CacheOpParent::ProcessCrossOriginResourcePolicyHeader(
const mozilla::ipc::ContentPrincipalInfo& responseContentPrincipalInfo =
it->mValue.principalInfo().ref().get_ContentPrincipalInfo();
const auto& corp =
nsCString corp =
corpHeaderIt == headers.cend() ? EmptyCString() : corpHeaderIt->value();
if (corp.IsEmpty()) {
if (loadingCOEP == nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS) {
// This means the request of this request doesn't have
// credentials, so it's safe for us to return.
if (credentials == RequestCredentials::Omit) {
return;
}
corp = "same-origin";
}
}
if (corp.EqualsLiteral("same-origin")) {
if (responseContentPrincipalInfo == contentPrincipalInfo) {
if (responseContentPrincipalInfo != contentPrincipalInfo) {
aRv.ThrowTypeError("Response is expected from same origin.");
return;
}

1
dom/cache/CacheTypes.ipdlh поставляемый
Просмотреть файл

@ -84,6 +84,7 @@ struct CacheResponse
PrincipalInfo? principalInfo;
uint32_t paddingInfo;
int64_t paddingSize;
RequestCredentials credentials;
};
struct CacheRequestResponse

8
dom/cache/DBSchema.cpp поставляемый
Просмотреть файл

@ -1794,7 +1794,8 @@ Result<SavedResponse, nsresult> ReadResponse(mozIStorageConnection& aConn,
"entries.response_body_id, "
"entries.response_principal_info, "
"entries.response_padding_size, "
"security_info.data "
"security_info.data, "
"entries.request_credentials "
"FROM entries "
"LEFT OUTER JOIN security_info "
"ON entries.response_security_info_id=security_info.id "
@ -1896,6 +1897,11 @@ Result<SavedResponse, nsresult> ReadResponse(mozIStorageConnection& aConn,
QM_TRY(MOZ_TO_RESULT(state->GetBlobAsUTF8String(
7, savedResponse.mValue.channelInfo().securityInfo())));
QM_TRY_INSPECT(const int32_t& credentials,
MOZ_TO_RESULT_INVOKE_MEMBER(*state, GetInt32, 8));
savedResponse.mValue.credentials() =
static_cast<RequestCredentials>(credentials);
{
QM_TRY_INSPECT(const auto& state,
MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(

Просмотреть файл

@ -196,6 +196,7 @@ SafeRefPtr<InternalResponse> InternalResponse::Clone(CloneType aCloneType) {
clone->mPaddingSize = mPaddingSize;
clone->mCacheInfoChannel = mCacheInfoChannel;
clone->mCredentialsMode = mCredentialsMode;
if (mWrappedResponse) {
clone->mWrappedResponse = mWrappedResponse->Clone(aCloneType);