mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 1121824 - Improve CORS console messages when request is blocked (r=sicking)
This commit is contained in:
parent
92e95883b2
commit
2febb6d0f8
@ -4,7 +4,18 @@ BlockMixedDisplayContent = Blocked loading mixed display content "%1$S"
|
||||
BlockMixedActiveContent = Blocked loading mixed active content "%1$S"
|
||||
|
||||
# CORS
|
||||
CrossSiteRequestBlocked=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. This can be fixed by moving the resource to the same domain or enabling CORS.
|
||||
# LOCALIZATION NOTE: Do not translate "Access-Control-Allow-Origin", Access-Control-Allow-Credentials, Access-Control-Allow-Methods, Access-Control-Allow-Headers
|
||||
CORSDisabled=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: CORS disabled).
|
||||
CORSRequestFailed=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: CORS request failed).
|
||||
CORSRequestNotHttp=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: CORS request not http).
|
||||
CORSMissingAllowOrigin=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: CORS header 'Access-Control-Allow-Origin' missing).
|
||||
CORSAllowOriginNotMatchingOrigin=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: CORS header 'Access-Control-Allow-Origin' does not match '%2$S').
|
||||
CORSMethodNotFound=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: Did not find method in CORS header 'Access-Control-Allow-Methods').
|
||||
CORSMissingAllowCredentials=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: expected 'true' in CORS header 'Access-Control-Allow-Credentials').
|
||||
CORSPreflightDidNotSucceed=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: CORS preflight channel did not succeed).
|
||||
CORSInvalidAllowMethod=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: invalid token '%2$S' in CORS header 'Access-Control-Allow-Methods').
|
||||
CORSInvalidAllowHeader=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: invalid token '%2$S' in CORS header 'Access-Control-Allow-Headers').
|
||||
CORSMissingAllowHeaderFromPreflight=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: missing token '%2$S' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel"));
|
||||
|
||||
# LOCALIZATION NOTE: Do not translate "Strict-Transport-Security" or "HSTS"
|
||||
InvalidSTSHeaders=The site specified an invalid Strict-Transport-Security header.
|
||||
|
@ -42,16 +42,25 @@ using namespace mozilla;
|
||||
static bool gDisableCORS = false;
|
||||
static bool gDisableCORSPrivateData = false;
|
||||
|
||||
static nsresult
|
||||
LogBlockedRequest(nsIRequest* aRequest)
|
||||
static void
|
||||
LogBlockedRequest(nsIRequest* aRequest,
|
||||
const char* aProperty,
|
||||
const char16_t* aParam)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Get the innerWindowID associated with the XMLHTTPRequest
|
||||
uint64_t innerWindowID = nsContentUtils::GetInnerWindowID(aRequest);
|
||||
// Build the error object and log it to the console
|
||||
nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to log blocked cross-site request (no console)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!innerWindowID) {
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIScriptError> scriptError =
|
||||
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to log blocked cross-site request (no scriptError)");
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
@ -65,32 +74,47 @@ LogBlockedRequest(nsIRequest* aRequest)
|
||||
// Generate the error message
|
||||
nsXPIDLString blockedMessage;
|
||||
NS_ConvertUTF8toUTF16 specUTF16(spec);
|
||||
const char16_t* params[] = { specUTF16.get() };
|
||||
const char16_t* params[] = { specUTF16.get(), aParam };
|
||||
rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eSECURITY_PROPERTIES,
|
||||
"CrossSiteRequestBlocked",
|
||||
aProperty,
|
||||
params,
|
||||
blockedMessage);
|
||||
|
||||
// Build the error object and log it to the console
|
||||
nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIScriptError> scriptError = do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to log blocked cross-site request (no formalizedStr");
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString msg(blockedMessage.get());
|
||||
rv = scriptError->InitWithWindowID(msg,
|
||||
NS_ConvertUTF8toUTF16(spec),
|
||||
EmptyString(),
|
||||
0,
|
||||
0,
|
||||
nsIScriptError::warningFlag,
|
||||
"CORS",
|
||||
innerWindowID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = console->LogMessage(scriptError);
|
||||
return rv;
|
||||
// query innerWindowID and log to web console, otherwise log to
|
||||
// the error to the browser console.
|
||||
uint64_t innerWindowID = nsContentUtils::GetInnerWindowID(aRequest);
|
||||
|
||||
if (innerWindowID > 0) {
|
||||
rv = scriptError->InitWithWindowID(msg,
|
||||
EmptyString(), // sourceName
|
||||
EmptyString(), // sourceLine
|
||||
0, // lineNumber
|
||||
0, // columnNumber
|
||||
nsIScriptError::warningFlag,
|
||||
"CORS",
|
||||
innerWindowID);
|
||||
}
|
||||
else {
|
||||
rv = scriptError->Init(msg,
|
||||
EmptyString(), // sourceName
|
||||
EmptyString(), // sourceLine
|
||||
0, // lineNumber
|
||||
0, // columnNumber
|
||||
nsIScriptError::warningFlag,
|
||||
"CORS");
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to log blocked cross-site request (scriptError init failed)");
|
||||
return;
|
||||
}
|
||||
console->LogMessage(scriptError);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -470,8 +494,6 @@ nsCORSListenerProxy::OnStartRequest(nsIRequest* aRequest,
|
||||
nsresult rv = CheckRequestApproved(aRequest);
|
||||
mRequestApproved = NS_SUCCEEDED(rv);
|
||||
if (!mRequestApproved) {
|
||||
rv = LogBlockedRequest(aRequest);
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to log blocked cross-site request");
|
||||
if (sPreflightCache) {
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
if (channel) {
|
||||
@ -503,31 +525,45 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
|
||||
}
|
||||
|
||||
if (gDisableCORS) {
|
||||
LogBlockedRequest(aRequest, "CORSDisabled", nullptr);
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
// Check if the request failed
|
||||
nsresult status;
|
||||
nsresult rv = aRequest->GetStatus(&status);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_SUCCESS(status, status);
|
||||
if (NS_FAILED(rv)) {
|
||||
LogBlockedRequest(aRequest, "CORSRequestFailed", nullptr);
|
||||
return rv;
|
||||
}
|
||||
if (NS_FAILED(status)) {
|
||||
LogBlockedRequest(aRequest, "CORSRequestFailed", nullptr);
|
||||
return status;
|
||||
}
|
||||
|
||||
// Test that things worked on a HTTP level
|
||||
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aRequest);
|
||||
NS_ENSURE_TRUE(http, NS_ERROR_DOM_BAD_URI);
|
||||
if (!http) {
|
||||
LogBlockedRequest(aRequest, "CORSRequestNotHttp", nullptr);
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
// Check the Access-Control-Allow-Origin header
|
||||
nsAutoCString allowedOriginHeader;
|
||||
rv = http->GetResponseHeader(
|
||||
NS_LITERAL_CSTRING("Access-Control-Allow-Origin"), allowedOriginHeader);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
LogBlockedRequest(aRequest, "CORSMissingAllowOrigin", nullptr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mWithCredentials || !allowedOriginHeader.EqualsLiteral("*")) {
|
||||
nsAutoCString origin;
|
||||
rv = nsContentUtils::GetASCIIOrigin(mOriginHeaderPrincipal, origin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsContentUtils::GetASCIIOrigin(mOriginHeaderPrincipal, origin);
|
||||
|
||||
if (!allowedOriginHeader.Equals(origin)) {
|
||||
LogBlockedRequest(aRequest, "CORSAllowOriginNotMatchingOrigin",
|
||||
NS_ConvertUTF8toUTF16(allowedOriginHeader).get());
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
}
|
||||
@ -537,9 +573,9 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
|
||||
nsAutoCString allowCredentialsHeader;
|
||||
rv = http->GetResponseHeader(
|
||||
NS_LITERAL_CSTRING("Access-Control-Allow-Credentials"), allowCredentialsHeader);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!allowCredentialsHeader.EqualsLiteral("true")) {
|
||||
LogBlockedRequest(aRequest, "CORSMissingAllowCredentials", nullptr);
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
}
|
||||
@ -547,8 +583,8 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
|
||||
if (mIsPreflight) {
|
||||
bool succeedded;
|
||||
rv = http->GetRequestSucceeded(&succeedded);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!succeedded) {
|
||||
if (NS_FAILED(rv) || !succeedded) {
|
||||
LogBlockedRequest(aRequest, "CORSPreflightDidNotSucceed", nullptr);
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
@ -567,11 +603,16 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
|
||||
continue;
|
||||
}
|
||||
if (!NS_IsValidHTTPToken(method)) {
|
||||
LogBlockedRequest(aRequest, "CORSInvalidAllowMethod",
|
||||
NS_ConvertUTF8toUTF16(method).get());
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
foundMethod |= mPreflightMethod.Equals(method);
|
||||
}
|
||||
NS_ENSURE_TRUE(foundMethod, NS_ERROR_DOM_BAD_URI);
|
||||
if (!foundMethod) {
|
||||
LogBlockedRequest(aRequest, "CORSMethodNotFound", nullptr);
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
// The "Access-Control-Allow-Headers" header contains a comma separated
|
||||
// list of header names.
|
||||
@ -586,6 +627,8 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
|
||||
continue;
|
||||
}
|
||||
if (!NS_IsValidHTTPToken(header)) {
|
||||
LogBlockedRequest(aRequest, "CORSInvalidAllowHeader",
|
||||
NS_ConvertUTF8toUTF16(header).get());
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
headers.AppendElement(header);
|
||||
@ -593,6 +636,8 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
|
||||
for (uint32_t i = 0; i < mPreflightHeaders.Length(); ++i) {
|
||||
if (!headers.Contains(mPreflightHeaders[i],
|
||||
nsCaseInsensitiveCStringArrayComparator())) {
|
||||
LogBlockedRequest(aRequest, "CORSMissingAllowHeaderFromPreflight",
|
||||
NS_ConvertUTF8toUTF16(mPreflightHeaders[i]).get());
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
}
|
||||
@ -656,9 +701,6 @@ nsCORSListenerProxy::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags)) {
|
||||
rv = CheckRequestApproved(aOldChannel);
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = LogBlockedRequest(aOldChannel);
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to log blocked cross-site request");
|
||||
|
||||
if (sPreflightCache) {
|
||||
nsCOMPtr<nsIURI> oldURI;
|
||||
NS_GetFinalChannelURI(aOldChannel, getter_AddRefs(oldURI));
|
||||
|
Loading…
Reference in New Issue
Block a user