Bug 1304645: Pass individual CSP errors as categories to web console error messages. r=baku a=lizzard DEVEDITION_62_0b17_BUILD1 DEVEDITION_62_0b17_RELEASE FENNEC_62_0b17_BUILD1 FENNEC_62_0b17_RELEASE FIREFOX_62_0b17_BUILD1 FIREFOX_62_0b17_RELEASE
authorChristoph Kerschbaumer <ckerschb@christophkerschbaumer.com>
Fri, 20 Jul 2018 19:57:21 +0200
changeset 480906 31a3bae15c00308fc30cd4b5e7bd01c37b23f33f
parent 480905 a59e5c3dda046d0b6c1bc5ac17820ac8e9b20e83
child 480907 c6e5cd33138ae5abc515a4cda991423156da0481
push id1757
push userffxbld-merge
push dateFri, 24 Aug 2018 17:02:43 +0000
treeherdermozilla-release@736023aebdb1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku, lizzard
bugs1304645
milestone62.0
Bug 1304645: Pass individual CSP errors as categories to web console error messages. r=baku a=lizzard
dom/html/HTMLFormElement.cpp
dom/security/FramingChecker.cpp
dom/security/nsCSPContext.cpp
dom/security/nsCSPUtils.cpp
dom/security/nsCSPUtils.h
dom/security/nsMixedContentBlocker.cpp
dom/websocket/WebSocket.cpp
netwerk/base/nsNetUtil.cpp
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -1711,17 +1711,18 @@ HTMLFormElement::GetActionURL(nsIURI** a
 
     const char16_t* params[] = { reportSpec.get(), reportScheme.get() };
     CSP_LogLocalizedStr("upgradeInsecureRequest",
                         params, ArrayLength(params),
                         EmptyString(), // aSourceFile
                         EmptyString(), // aScriptSample
                         0, // aLineNumber
                         0, // aColumnNumber
-                        nsIScriptError::warningFlag, "CSP",
+                        nsIScriptError::warningFlag,
+                        NS_LITERAL_CSTRING("upgradeInsecureRequest"),
                         document->InnerWindowID(),
                         !!document->NodePrincipal()->OriginAttributesRef().mPrivateBrowsingId);
   }
 
   //
   // Assign to the output
   //
   actionURL.forget(aActionURL);
--- a/dom/security/FramingChecker.cpp
+++ b/dom/security/FramingChecker.cpp
@@ -191,17 +191,18 @@ ShouldIgnoreFrameOptions(nsIChannel* aCh
                                u"frame-ancestors" };
   CSP_LogLocalizedStr("IgnoringSrcBecauseOfDirective",
                       params, ArrayLength(params),
                       EmptyString(), // no sourcefile
                       EmptyString(), // no scriptsample
                       0,             // no linenumber
                       0,             // no columnnumber
                       nsIScriptError::warningFlag,
-                      "CSP", innerWindowID,
+                      NS_LITERAL_CSTRING("IgnoringSrcBecauseOfDirective"),
+                      innerWindowID,
                       privateWindow);
 
   return true;
 }
 
 // Check if X-Frame-Options permits this document to be loaded as a subdocument.
 // This will iterate through and check any number of X-Frame-Options policies
 // in the request (comma-separated in a header, multiple headers, etc).
--- a/dom/security/nsCSPContext.cpp
+++ b/dom/security/nsCSPContext.cpp
@@ -740,16 +740,17 @@ nsCSPContext::EnsureEventTarget(nsIEvent
 
 struct ConsoleMsgQueueElem {
   nsString      mMsg;
   nsString      mSourceName;
   nsString      mSourceLine;
   uint32_t      mLineNumber;
   uint32_t      mColumnNumber;
   uint32_t      mSeverityFlag;
+  nsCString     mCategory;
 };
 
 void
 nsCSPContext::flushConsoleMessages()
 {
   bool privateWindow = false;
 
   // should flush messages even if doc is not available
@@ -760,55 +761,61 @@ nsCSPContext::flushConsoleMessages()
   }
 
   mQueueUpMessages = false;
 
   for (uint32_t i = 0; i < mConsoleMsgQueue.Length(); i++) {
     ConsoleMsgQueueElem &elem = mConsoleMsgQueue[i];
     CSP_LogMessage(elem.mMsg, elem.mSourceName, elem.mSourceLine,
                    elem.mLineNumber, elem.mColumnNumber,
-                   elem.mSeverityFlag, "CSP", mInnerWindowID,
+                   elem.mSeverityFlag, elem.mCategory, mInnerWindowID,
                    privateWindow);
   }
   mConsoleMsgQueue.Clear();
 }
 
 void
 nsCSPContext::logToConsole(const char* aName,
                            const char16_t** aParams,
                            uint32_t aParamsLength,
                            const nsAString& aSourceName,
                            const nsAString& aSourceLine,
                            uint32_t aLineNumber,
                            uint32_t aColumnNumber,
                            uint32_t aSeverityFlag)
 {
+  // we are passing aName as the category so we can link to the
+  // appropriate MDN docs depending on the specific error.
+  nsDependentCString category(aName);
+
   // let's check if we have to queue up console messages
   if (mQueueUpMessages) {
     nsAutoString msg;
     CSP_GetLocalizedStr(aName, aParams, aParamsLength, msg);
     ConsoleMsgQueueElem &elem = *mConsoleMsgQueue.AppendElement();
     elem.mMsg = msg;
     elem.mSourceName = PromiseFlatString(aSourceName);
     elem.mSourceLine = PromiseFlatString(aSourceLine);
     elem.mLineNumber = aLineNumber;
     elem.mColumnNumber = aColumnNumber;
     elem.mSeverityFlag = aSeverityFlag;
+    elem.mCategory = category;
     return;
   }
 
   bool privateWindow = false;
   nsCOMPtr<nsIDocument> doc = do_QueryReferent(mLoadingContext);
   if (doc) {
     privateWindow = !!doc->NodePrincipal()->OriginAttributesRef().mPrivateBrowsingId;
   }
 
+
   CSP_LogLocalizedStr(aName, aParams, aParamsLength, aSourceName,
                       aSourceLine, aLineNumber, aColumnNumber,
-                      aSeverityFlag, "CSP", mInnerWindowID, privateWindow);
+                      aSeverityFlag, category, mInnerWindowID, privateWindow);
 }
 
 /**
  * Strip URI for reporting according to:
  * http://www.w3.org/TR/CSP/#violation-reports
  *
  * @param aURI
  *        The uri to be stripped for reporting
--- a/dom/security/nsCSPUtils.cpp
+++ b/dom/security/nsCSPUtils.cpp
@@ -124,17 +124,17 @@ CSP_LogStrMessage(const nsAString& aMsg)
 
 void
 CSP_LogMessage(const nsAString& aMessage,
                const nsAString& aSourceName,
                const nsAString& aSourceLine,
                uint32_t aLineNumber,
                uint32_t aColumnNumber,
                uint32_t aFlags,
-               const char *aCategory,
+               const nsACString& aCategory,
                uint64_t aInnerWindowID,
                bool aFromPrivateWindow)
 {
   nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
 
   nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
 
   if (!console || !error) {
@@ -153,30 +153,35 @@ CSP_LogMessage(const nsAString& aMessage
   // E.g. 'aSourceLine' might be: 'onclick attribute on DIV element'.
   // In such cases we append 'aSourceLine' directly to the error message.
   if (!aSourceLine.IsEmpty()) {
     cspMsg.AppendLiteral(" Source: ");
     cspMsg.Append(aSourceLine);
     cspMsg.AppendLiteral(u".");
   }
 
+  // Since we are leveraging csp errors as the category names which
+  // we pass to devtools, we should prepend them with "CSP_" to
+  // allow easy distincution in devtools code. e.g.
+  // upgradeInsecureRequest -> CSP_upgradeInsecureRequest
+  nsCString category("CSP_");
+  category.Append(aCategory);
+
   nsresult rv;
   if (aInnerWindowID > 0) {
-    nsCString catStr;
-    catStr.AssignASCII(aCategory);
     rv = error->InitWithWindowID(cspMsg, aSourceName,
                                  aSourceLine, aLineNumber,
                                  aColumnNumber, aFlags,
-                                 catStr, aInnerWindowID);
+                                 category, aInnerWindowID);
   }
   else {
     rv = error->Init(cspMsg, aSourceName,
                      aSourceLine, aLineNumber,
                      aColumnNumber, aFlags,
-                     aCategory, aFromPrivateWindow);
+                     category.get(), aFromPrivateWindow);
   }
   if (NS_FAILED(rv)) {
     return;
   }
   console->LogMessage(error);
 }
 
 /**
@@ -186,17 +191,17 @@ void
 CSP_LogLocalizedStr(const char* aName,
                     const char16_t** aParams,
                     uint32_t aLength,
                     const nsAString& aSourceName,
                     const nsAString& aSourceLine,
                     uint32_t aLineNumber,
                     uint32_t aColumnNumber,
                     uint32_t aFlags,
-                    const char* aCategory,
+                    const nsACString& aCategory,
                     uint64_t aInnerWindowID,
                     bool aFromPrivateWindow)
 {
   nsAutoString logMsg;
   CSP_GetLocalizedStr(aName, aParams, aLength, logMsg);
   CSP_LogMessage(logMsg, aSourceName, aSourceLine,
                  aLineNumber, aColumnNumber, aFlags,
                  aCategory, aInnerWindowID, aFromPrivateWindow);
--- a/dom/security/nsCSPUtils.h
+++ b/dom/security/nsCSPUtils.h
@@ -28,34 +28,34 @@ namespace dom {
 void CSP_LogLocalizedStr(const char* aName,
                          const char16_t** aParams,
                          uint32_t aLength,
                          const nsAString& aSourceName,
                          const nsAString& aSourceLine,
                          uint32_t aLineNumber,
                          uint32_t aColumnNumber,
                          uint32_t aFlags,
-                         const char* aCategory,
+                         const nsACString& aCategory,
                          uint64_t aInnerWindowID,
                          bool aFromPrivateWindow);
 
 void CSP_GetLocalizedStr(const char* aName,
                          const char16_t** aParams,
                          uint32_t aLength,
                          nsAString& outResult);
 
 void CSP_LogStrMessage(const nsAString& aMsg);
 
 void CSP_LogMessage(const nsAString& aMessage,
                     const nsAString& aSourceName,
                     const nsAString& aSourceLine,
                     uint32_t aLineNumber,
                     uint32_t aColumnNumber,
                     uint32_t aFlags,
-                    const char* aCategory,
+                    const nsACString& aCategory,
                     uint64_t aInnerWindowID,
                     bool aFromPrivateWindow);
 
 
 /* =============== Constant and Type Definitions ================== */
 
 #define INLINE_STYLE_VIOLATION_OBSERVER_TOPIC        "violated base restriction: Inline Stylesheets will not apply"
 #define INLINE_SCRIPT_VIOLATION_OBSERVER_TOPIC       "violated base restriction: Inline Scripts will not execute"
--- a/dom/security/nsMixedContentBlocker.cpp
+++ b/dom/security/nsMixedContentBlocker.cpp
@@ -800,17 +800,18 @@ nsMixedContentBlocker::ShouldLoad(bool a
 
     const char16_t* params[] = { reportSpec.get()};
     CSP_LogLocalizedStr("blockAllMixedContent",
                         params, ArrayLength(params),
                         EmptyString(), // aSourceFile
                         EmptyString(), // aScriptSample
                         0, // aLineNumber
                         0, // aColumnNumber
-                        nsIScriptError::errorFlag, "CSP",
+                        nsIScriptError::errorFlag,
+                        NS_LITERAL_CSTRING("blockAllMixedContent"),
                         document->InnerWindowID(),
                         !!document->NodePrincipal()->OriginAttributesRef().mPrivateBrowsingId);
     *aDecision = REJECT_REQUEST;
     return NS_OK;
   }
 
   // Determine if the rootDoc is https and if the user decided to allow Mixed Content
   bool rootHasSecureConnection = false;
--- a/dom/websocket/WebSocket.cpp
+++ b/dom/websocket/WebSocket.cpp
@@ -1713,17 +1713,18 @@ WebSocketImpl::Init(JSContext* aCx,
 
     const char16_t* params[] = { reportSpec.get(), u"wss" };
     CSP_LogLocalizedStr("upgradeInsecureRequest",
                         params, ArrayLength(params),
                         EmptyString(), // aSourceFile
                         EmptyString(), // aScriptSample
                         0, // aLineNumber
                         0, // aColumnNumber
-                        nsIScriptError::warningFlag, "CSP",
+                        nsIScriptError::warningFlag,
+                        NS_LITERAL_CSTRING("upgradeInsecureRequest"),
                         mInnerWindowID,
                         mPrivateBrowsing);
   }
 
   // Don't allow https:// to open ws://
   if (!mIsServerSide && !mSecure &&
       !Preferences::GetBool("network.websocket.allowInsecureFromHTTPS",
                             false)) {
--- a/netwerk/base/nsNetUtil.cpp
+++ b/netwerk/base/nsNetUtil.cpp
@@ -2925,17 +2925,18 @@ NS_ShouldSecureUpgrade(nsIURI* aURI,
           const char16_t* params[] = { reportSpec.get(), reportScheme.get() };
           uint32_t innerWindowId = aLoadInfo->GetInnerWindowID();
           CSP_LogLocalizedStr("upgradeInsecureRequest",
                               params, ArrayLength(params),
                               EmptyString(), // aSourceFile
                               EmptyString(), // aScriptSample
                               0, // aLineNumber
                               0, // aColumnNumber
-                              nsIScriptError::warningFlag, "CSP",
+                              nsIScriptError::warningFlag,
+                              NS_LITERAL_CSTRING("upgradeInsecureRequest"),
                               innerWindowId,
                               !!aLoadInfo->GetOriginAttributes().mPrivateBrowsingId);
           Telemetry::AccumulateCategorical(Telemetry::LABELS_HTTP_SCHEME_UPGRADE_TYPE::CSP);
         } else {
           nsCOMPtr<nsIDocument> doc;
           nsINode* node = aLoadInfo->LoadingNode();
           if (node) {
             doc = node->OwnerDoc();