Issue #2024 - Part 1: Add wildcard to Access-Control-Expose-Headers

For requests without credentials, add wildcard to Access-Control-Expose-Headers.
This commit is contained in:
Moonchild 2022-11-06 12:31:17 +00:00 committed by roytam1
commit 211b7cf219
6 changed files with 40 additions and 16 deletions

View file

@ -537,7 +537,8 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
nsAutoCString statusText;
httpChannel->GetResponseStatusText(statusText);
response = new InternalResponse(responseStatus, statusText);
response = new InternalResponse(responseStatus, statusText,
mRequest->GetCredentialsMode());
RefPtr<FillResponseHeaders> visitor = new FillResponseHeaders(response);
rv = httpChannel->VisitResponseHeaders(visitor);
@ -556,7 +557,8 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
}
MOZ_ASSERT(!result.Failed());
} else {
response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"),
mRequest->GetCredentialsMode());
ErrorResult result;
nsAutoCString contentType;

View file

@ -364,7 +364,7 @@ InternalHeaders::BasicHeaders(InternalHeaders* aHeaders)
// static
already_AddRefed<InternalHeaders>
InternalHeaders::CORSHeaders(InternalHeaders* aHeaders)
InternalHeaders::CORSHeaders(InternalHeaders* aHeaders, RequestCredentials aCredentialsMode)
{
RefPtr<InternalHeaders> cors = new InternalHeaders(aHeaders->mGuard);
ErrorResult result;
@ -373,6 +373,7 @@ InternalHeaders::CORSHeaders(InternalHeaders* aHeaders)
aHeaders->GetFirst(NS_LITERAL_CSTRING("Access-Control-Expose-Headers"), acExposedNames, result);
MOZ_ASSERT(!result.Failed());
bool allowAllHeaders = false;
AutoTArray<nsCString, 5> exposeNamesArray;
nsCCharSeparatedTokenizer exposeTokens(acExposedNames, ',');
while (exposeTokens.hasMoreTokens()) {
@ -388,19 +389,27 @@ InternalHeaders::CORSHeaders(InternalHeaders* aHeaders)
break;
}
if (token.EqualsLiteral("*") &&
aCredentialsMode != RequestCredentials::Include) {
allowAllHeaders = true;
}
exposeNamesArray.AppendElement(token);
}
nsCaseInsensitiveCStringArrayComparator comp;
for (uint32_t i = 0; i < aHeaders->mList.Length(); ++i) {
const Entry& entry = aHeaders->mList[i];
if (entry.mName.EqualsASCII("cache-control") ||
entry.mName.EqualsASCII("content-language") ||
entry.mName.EqualsASCII("content-type") ||
entry.mName.EqualsASCII("expires") ||
entry.mName.EqualsASCII("last-modified") ||
entry.mName.EqualsASCII("pragma") ||
exposeNamesArray.Contains(entry.mName, comp)) {
if (allowAllHeaders) {
cors->Append(entry.mName, entry.mValue, result);
MOZ_ASSERT(!result.Failed());
} else if (entry.mName.EqualsASCII("cache-control") ||
entry.mName.EqualsASCII("content-language") ||
entry.mName.EqualsASCII("content-type") ||
entry.mName.EqualsASCII("expires") ||
entry.mName.EqualsASCII("last-modified") ||
entry.mName.EqualsASCII("pragma") ||
exposeNamesArray.Contains(entry.mName, comp)) {
cors->Append(entry.mName, entry.mValue, result);
MOZ_ASSERT(!result.Failed());
}

View file

@ -8,6 +8,7 @@
// needed for HeadersGuardEnum.
#include "mozilla/dom/HeadersBinding.h"
#include "mozilla/dom/RequestBinding.h"
#include "mozilla/dom/UnionTypes.h"
#include "nsClassHashtable.h"
@ -122,7 +123,8 @@ public:
BasicHeaders(InternalHeaders* aHeaders);
static already_AddRefed<InternalHeaders>
CORSHeaders(InternalHeaders* aHeaders);
CORSHeaders(InternalHeaders* aHeaders,
RequestCredentials mCredentialsMode = RequestCredentials::Omit);
void
GetEntries(nsTArray<InternalHeaders::Entry>& aEntries) const;

View file

@ -17,12 +17,15 @@
namespace mozilla {
namespace dom {
InternalResponse::InternalResponse(uint16_t aStatus, const nsACString& aStatusText)
InternalResponse::InternalResponse(uint16_t aStatus,
const nsACString& aStatusText,
RequestCredentials aCredentialsMode)
: mType(ResponseType::Default)
, mStatus(aStatus)
, mStatusText(aStatusText)
, mHeaders(new InternalHeaders(HeadersGuardEnum::Response))
, mBodySize(UNKNOWN_BODY_SIZE)
, mCredentialsMode(aCredentialsMode)
{
}
@ -183,7 +186,7 @@ InternalResponse::CORSResponse()
MOZ_ASSERT(!mWrappedResponse, "Can't CORSResponse a already wrapped response");
RefPtr<InternalResponse> cors = CreateIncompleteCopy();
cors->mType = ResponseType::Cors;
cors->mHeaders = InternalHeaders::CORSHeaders(Headers());
cors->mHeaders = InternalHeaders::CORSHeaders(Headers(), mCredentialsMode);
cors->mWrappedResponse = this;
return cors.forget();
}

View file

@ -9,9 +9,10 @@
#include "nsIInputStream.h"
#include "nsISupportsImpl.h"
#include "mozilla/dom/InternalHeaders.h"
#include "mozilla/dom/RequestBinding.h"
#include "mozilla/dom/ResponseBinding.h"
#include "mozilla/dom/ChannelInfo.h"
#include "mozilla/dom/InternalHeaders.h"
#include "mozilla/UniquePtr.h"
namespace mozilla {
@ -32,7 +33,9 @@ class InternalResponse final
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalResponse)
InternalResponse(uint16_t aStatus, const nsACString& aStatusText);
InternalResponse(uint16_t aStatus,
const nsACString& aStatusText,
RequestCredentials aCredentialsMode = RequestCredentials::Omit);
static already_AddRefed<InternalResponse>
FromIPC(const IPCInternalResponse& aIPCResponse);
@ -294,8 +297,11 @@ private:
RefPtr<InternalHeaders> mHeaders;
nsCOMPtr<nsIInputStream> mBody;
int64_t mBodySize;
RequestCredentials mCredentialsMode;
public:
static const int64_t UNKNOWN_BODY_SIZE = -1;
private:
ChannelInfo mChannelInfo;
UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;

View file

@ -1182,7 +1182,9 @@ XMLHttpRequestMainThread::IsSafeHeader(const nsACString& aHeader,
if (!NS_IsValidHTTPToken(token)) {
return false;
}
if (aHeader.Equals(token, nsCaseInsensitiveCStringComparator())) {
if (token.EqualsLiteral("*") && !mFlagACwithCredentials) {
isSafe = true;
} else if (aHeader.Equals(token, nsCaseInsensitiveCStringComparator())) {
isSafe = true;
}
}