Bug 1121824 - Improve CORS console messages when request is blocked (r=sicking)

This commit is contained in:
Christoph Kerschbaumer 2015-01-21 19:44:43 -08:00
Родитель f2e2db81ac
Коммит ed011bcd95
2 изменённых файлов: 67 добавлений и 31 удалений

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

@ -4,7 +4,14 @@ 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).
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).
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,6 +525,7 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
}
if (gDisableCORS) {
LogBlockedRequest(aRequest, "CORSDisabled", nullptr);
return NS_ERROR_DOM_BAD_URI;
}
@ -528,6 +551,7 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
NS_ENSURE_SUCCESS(rv, rv);
if (!allowedOriginHeader.Equals(origin)) {
LogBlockedRequest(aRequest, "CORSMissingAllowOrigin", nullptr);
return NS_ERROR_DOM_BAD_URI;
}
}
@ -540,6 +564,7 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
NS_ENSURE_SUCCESS(rv, rv);
if (!allowCredentialsHeader.EqualsLiteral("true")) {
LogBlockedRequest(aRequest, "CORSMissingAllowCredentials", nullptr);
return NS_ERROR_DOM_BAD_URI;
}
}
@ -549,6 +574,7 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
rv = http->GetRequestSucceeded(&succeedded);
NS_ENSURE_SUCCESS(rv, rv);
if (!succeedded) {
LogBlockedRequest(aRequest, "CORSPreflightDidNotSucceed", nullptr);
return NS_ERROR_DOM_BAD_URI;
}
@ -567,6 +593,8 @@ 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);
@ -586,6 +614,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 +623,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 +688,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));