diff --git a/browser/devtools/webconsole/webconsole.js b/browser/devtools/webconsole/webconsole.js index afe20c325f9..e0687c9e3c6 100644 --- a/browser/devtools/webconsole/webconsole.js +++ b/browser/devtools/webconsole/webconsole.js @@ -4444,6 +4444,7 @@ var Utils = { case "Invalid HSTS Headers": case "Insecure Password Field": case "SSL": + case "CORS": return CATEGORY_SECURITY; default: diff --git a/content/base/src/nsCrossSiteListenerProxy.cpp b/content/base/src/nsCrossSiteListenerProxy.cpp index 925e82bae3d..a25b6c1a448 100644 --- a/content/base/src/nsCrossSiteListenerProxy.cpp +++ b/content/base/src/nsCrossSiteListenerProxy.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -26,6 +26,12 @@ #include "nsHashKeys.h" #include "nsStreamUtils.h" #include "mozilla/Preferences.h" +#include "nsIScriptError.h" +#include "nsILoadGroup.h" +#include "nsILoadContext.h" +#include "nsIConsoleService.h" +#include "nsIDOMWindowUtils.h" +#include "nsIDOMWindow.h" #include using namespace mozilla; @@ -35,6 +41,75 @@ using namespace mozilla; static bool gDisableCORS = false; static bool gDisableCORSPrivateData = false; +static nsresult +LogBlockedRequest(nsIRequest* aRequest) +{ + nsresult rv = NS_OK; + + // Get the innerWindowID associated with the XMLHTTPRequest + PRUint64 innerWindowID = 0; + + nsCOMPtr loadGroup; + aRequest->GetLoadGroup(getter_AddRefs(loadGroup)); + if (loadGroup) { + nsCOMPtr callbacks; + loadGroup->GetNotificationCallbacks(getter_AddRefs(callbacks)); + if (callbacks) { + nsCOMPtr loadContext = do_GetInterface(callbacks); + if(loadContext) { + nsCOMPtr window; + loadContext->GetAssociatedWindow(getter_AddRefs(window)); + if (window) { + nsCOMPtr du = do_GetInterface(window); + du->GetCurrentInnerWindowID(&innerWindowID); + } + } + } + } + + if (!innerWindowID) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr channel = do_QueryInterface(aRequest); + nsCOMPtr aUri; + channel->GetURI(getter_AddRefs(aUri)); + nsAutoCString spec; + if (aUri) { + aUri->GetSpec(spec); + } + + // Generate the error message + nsXPIDLString blockedMessage; + NS_ConvertUTF8toUTF16 specUTF16(spec); + const PRUnichar* params[] = { specUTF16.get() }; + rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eSECURITY_PROPERTIES, + "CrossSiteRequestBlocked", + params, + blockedMessage); + + // Build the error object and log it to the console + nsCOMPtr console(do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr scriptError = do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + 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; +} + ////////////////////////////////////////////////////////////////////////// // Preflight cache @@ -398,8 +473,11 @@ NS_IMETHODIMP nsCORSListenerProxy::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) { - mRequestApproved = NS_SUCCEEDED(CheckRequestApproved(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 channel = do_QueryInterface(aRequest); if (channel) { @@ -622,6 +700,9 @@ 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 oldURI; NS_GetFinalChannelURI(aOldChannel, getter_AddRefs(oldURI)); diff --git a/content/base/test/mochitest.ini b/content/base/test/mochitest.ini index 7bdf6956576..25ffa92d432 100644 --- a/content/base/test/mochitest.ini +++ b/content/base/test/mochitest.ini @@ -580,3 +580,4 @@ support-files = [test_xhr_send_readystate.html] [test_xhr_withCredentials.html] [test_file_from_blob.html] +[test_warning_for_blocked_cross_site_request.html] diff --git a/content/base/test/test_warning_for_blocked_cross_site_request.html b/content/base/test/test_warning_for_blocked_cross_site_request.html new file mode 100644 index 00000000000..6dd40429fe4 --- /dev/null +++ b/content/base/test/test_warning_for_blocked_cross_site_request.html @@ -0,0 +1,92 @@ + + + + + + Test for Bug 713980 + + + + + + + +
+
+
+
+
+ + diff --git a/dom/locales/en-US/chrome/security/security.properties b/dom/locales/en-US/chrome/security/security.properties index c8091807f63..86256ac73b8 100644 --- a/dom/locales/en-US/chrome/security/security.properties +++ b/dom/locales/en-US/chrome/security/security.properties @@ -9,6 +9,10 @@ ReportOnlyCSPIgnored=Report-only CSP policy will be ignored because there are ot OldCSPHeaderDeprecated=The X-Content-Security-Policy and X-Content-Security-Report-Only headers will be deprecated in the future. Please use the Content-Security-Policy and Content-Security-Report-Only headers with CSP spec compliant syntax instead. # LOCALIZATION NOTE: Do not translate "X-Content-Security-Policy/Report-Only" or "Content-Security-Policy/Report-Only" BothCSPHeadersPresent=This site specified both an X-Content-Security-Policy/Report-Only header and a Content-Security-Policy/Report-Only header. The X-Content-Security-Policy/Report-Only header(s) will be ignored. + +# 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 "Strict-Transport-Security" or "HSTS" InvalidSTSHeaders=The site specified an invalid Strict-Transport-Security header. InsecurePasswordsPresentOnPage=Password fields present on an insecure (http://) page. This is a security risk that allows user login credentials to be stolen.