Backout 1cefe3f794ba (bug 767778) for xpcshell failures
authorEd Morley <emorley@mozilla.com>
Tue, 10 Jul 2012 12:13:57 +0100
changeset 98753 0b4a966d3f85e60f6c1e0e874d1df7e32bceab3f
parent 98752 1cefe3f794ba37322b8657efe178e97d6642b460
child 98754 5b77d71ed9275a71ab9e3223e488eb6effd31cdf
child 98826 46b33c04a8401194f5e058e467ff03b60aab7008
push idunknown
push userunknown
push dateunknown
bugs767778
milestone16.0a1
backs out1cefe3f794ba37322b8657efe178e97d6642b460
Backout 1cefe3f794ba (bug 767778) for xpcshell failures
content/base/src/contentSecurityPolicy.js
content/base/src/nsCSPService.cpp
content/base/test/test_bug548193.html
--- a/content/base/src/contentSecurityPolicy.js
+++ b/content/base/src/contentSecurityPolicy.js
@@ -32,17 +32,16 @@ function ContentSecurityPolicy() {
   this._reportOnlyMode = false;
   this._policy = CSPRep.fromString("default-src *");
 
   // default options "wide open" since this policy will be intersected soon
   this._policy._allowInlineScripts = true;
   this._policy._allowEval = true;
 
   this._request = "";
-  this._referrer = "";
   this._docRequest = null;
   CSPdebug("CSP POLICY INITED TO 'default-src *'");
 }
 
 /*
  * Set up mappings from nsIContentPolicy content types to CSP directives.
  */
 {
@@ -148,23 +147,23 @@ ContentSecurityPolicy.prototype = {
   logViolationDetails:
   function(aViolationType, aSourceFile, aScriptSample, aLineNum) {
     // allowsInlineScript and allowsEval both return true when report-only mode
     // is enabled, resulting in a call to this function. Therefore we need to
     // check that the policy was in fact violated before logging any violations
     switch (aViolationType) {
     case Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_INLINE_SCRIPT:
       if (!this._policy.allowsInlineScripts)
-        this._asyncReportViolation('self',null,'inline script base restriction',
+        this._asyncReportViolation('self','inline script base restriction',
                                    'violated base restriction: Inline Scripts will not execute',
                                    aSourceFile, aScriptSample, aLineNum);
       break;
     case Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_EVAL:
       if (!this._policy.allowsEvalInScripts)
-        this._asyncReportViolation('self',null,'eval script base restriction',
+        this._asyncReportViolation('self','eval script base restriction',
                                    'violated base restriction: Code will not be created from strings',
                                    aSourceFile, aScriptSample, aLineNum);
       break;
     }
   },
 
   set reportOnlyMode(val) {
     this._reportOnlyMode = val;
@@ -184,28 +183,35 @@ ContentSecurityPolicy.prototype = {
 
   /**
    * Given an nsIHttpChannel, fill out the appropriate data.
    */
   scanRequestData:
   function(aChannel) {
     if (!aChannel)
       return;
+    // grab the request line
+    var internalChannel = null;
+    try {
+      internalChannel = aChannel.QueryInterface(Ci.nsIHttpChannelInternal);
+    } catch (e) {
+      CSPdebug("No nsIHttpChannelInternal for " + aChannel.URI.asciiSpec);
+    }
 
-    // Save the docRequest for fetching a policy-uri
+    this._request = aChannel.requestMethod + " " + aChannel.URI.asciiSpec;
     this._docRequest = aChannel;
 
-    // save the document URI (minus <fragment>) and referrer for reporting
-    let uri = aChannel.URI.cloneIgnoringRef();
-    uri.userPass = '';
-    this._request = uri.asciiSpec;
-
-    let referrer = aChannel.referrer.cloneIgnoringRef();
-    referrer.userPass = '';
-    this._referrer = referrer.asciiSpec;
+    // We will only be able to provide the HTTP version information if aChannel
+    // implements nsIHttpChannelInternal
+    if (internalChannel) {
+      var reqMaj = {};
+      var reqMin = {};
+      var reqVersion = internalChannel.getRequestVersion(reqMaj, reqMin);
+      this._request += " HTTP/" + reqMaj.value + "." + reqMin.value;
+    }
   },
 
 /* ........ Methods .............. */
 
   /**
    * Given a new policy, intersects the currently enforced policy with the new
    * one and stores the result.  The effect is a "tightening" or refinement of
    * an old policy.  This is called any time a new policy is encountered and
@@ -242,58 +248,37 @@ ContentSecurityPolicy.prototype = {
     this._policy = intersect;
     this._isInitialized = true;
   },
 
   /**
    * Generates and sends a violation report to the specified report URIs.
    */
   sendReports:
-  function(blockedUri, originalUri, violatedDirective,
-           aSourceFile, aScriptSample, aLineNum) {
+  function(blockedUri, violatedDirective, aSourceFile, aScriptSample, aLineNum) {
     var uriString = this._policy.getReportURIs();
     var uris = uriString.split(/\s+/);
     if (uris.length > 0) {
-      // see if we need to sanitize the blocked-uri
-      let blocked = '';
-      if (originalUri) {
-        // We've redirected, only report the blocked origin
-        let clone = blockedUri.clone();
-        clone.path = '';
-        blocked = clone.asciiSpec;
-      }
-      else if (blockedUri instanceof Ci.nsIURI) {
-        blocked = blockedUri.cloneIgnoringRef().asciiSpec;
-      }
-      else {
-        // blockedUri is a string for eval/inline-script violations
-        blocked = blockedUri;
-      }
-
       // Generate report to send composed of
       // {
       //   csp-report: {
-      //     document-uri: "http://example.com/file.html?params",
-      //     referrer: "...",
+      //     request: "GET /index.html HTTP/1.1",
       //     blocked-uri: "...",
       //     violated-directive: "..."
       //   }
       // }
       var report = {
         'csp-report': {
-          'document-uri': this._request,
-          'referrer': this._referrer,
-          'blocked-uri': blocked,
+          'request': this._request,
+          'blocked-uri': (blockedUri instanceof Ci.nsIURI ?
+                          blockedUri.asciiSpec : blockedUri),
           'violated-directive': violatedDirective
         }
       }
-
       // extra report fields for script errors (if available)
-      if (originalUri)
-        report["csp-report"]["original-uri"] = originalUri.cloneIgnoringRef().asciiSpec;
       if (aSourceFile)
         report["csp-report"]["source-file"] = aSourceFile;
       if (aScriptSample)
         report["csp-report"]["script-sample"] = aScriptSample;
       if (aLineNum)
         report["csp-report"]["line-number"] = aLineNum;
 
       var reportString = JSON.stringify(report);
@@ -413,17 +398,17 @@ ContentSecurityPolicy.prototype = {
       let ancestor = ancestors[i].prePath;
       if (!this._policy.permits(ancestor, cspContext)) {
         // report the frame-ancestor violation
         let directive = this._policy._directives[cspContext];
         let violatedPolicy = (directive._isImplicit
                                 ? 'default-src' : 'frame-ancestors ')
                                 + directive.toString();
 
-        this._asyncReportViolation(ancestors[i], null, violatedPolicy);
+        this._asyncReportViolation(ancestors[i], violatedPolicy);
 
         // need to lie if we are testing in report-only mode
         return this._reportOnlyMode;
       }
     }
     return true;
   },
 
@@ -433,17 +418,17 @@ ContentSecurityPolicy.prototype = {
    * decides whether or not the policy is satisfied.
    */
   shouldLoad:
   function csp_shouldLoad(aContentType, 
                           aContentLocation, 
                           aRequestOrigin, 
                           aContext, 
                           aMimeTypeGuess, 
-                          aOriginalUri) {
+                          aExtra) {
 
     // don't filter chrome stuff
     if (aContentLocation.scheme === 'chrome' ||
         aContentLocation.scheme === 'resource') {
       return Ci.nsIContentPolicy.ACCEPT;
     }
 
     // interpret the context, and then pass off to the decision structure
@@ -467,17 +452,17 @@ ContentSecurityPolicy.prototype = {
     // If the result is *NOT* ACCEPT, then send report
     if (res != Ci.nsIContentPolicy.ACCEPT) { 
       CSPdebug("blocking request for " + aContentLocation.asciiSpec);
       try {
         let directive = this._policy._directives[cspContext];
         let violatedPolicy = (directive._isImplicit
                                 ? 'default-src' : cspContext)
                                 + ' ' + directive.toString();
-        this._asyncReportViolation(aContentLocation, aOriginalUri, violatedPolicy);
+        this._asyncReportViolation(aContentLocation, violatedPolicy);
       } catch(e) {
         CSPdebug('---------------- ERROR: ' + e);
       }
     }
 
     return (this._reportOnlyMode ? Ci.nsIContentPolicy.ACCEPT : res);
   },
   
@@ -497,32 +482,30 @@ ContentSecurityPolicy.prototype = {
   /**
    * Asynchronously notifies any nsIObservers listening to the CSP violation
    * topic that a violation occurred.  Also triggers report sending.  All
    * asynchronous on the main thread.
    *
    * @param blockedContentSource
    *        Either a CSP Source (like 'self', as string) or nsIURI: the source
    *        of the violation.
-   * @param originalUri
-   *        The original URI if the blocked content is a redirect, else null
    * @param violatedDirective
    *        the directive that was violated (string).
    * @param observerSubject
    *        optional, subject sent to the nsIObservers listening to the CSP
    *        violation topic.
    * @param aSourceFile
    *        name of the file containing the inline script violation
    * @param aScriptSample
    *        a sample of the violating inline script
    * @param aLineNum
    *        source line number of the violation (if available)
    */
   _asyncReportViolation:
-  function(blockedContentSource, originalUri, violatedDirective, observerSubject,
+  function(blockedContentSource, violatedDirective, observerSubject,
            aSourceFile, aScriptSample, aLineNum) {
     // if optional observerSubject isn't specified, default to the source of
     // the violation.
     if (!observerSubject)
       observerSubject = blockedContentSource;
 
     // gotta wrap things that aren't nsISupports, since it's sent out to
     // observers as such.  Objects that are not nsISupports are converted to
@@ -535,18 +518,17 @@ ContentSecurityPolicy.prototype = {
     }
 
     var reportSender = this;
     Services.tm.mainThread.dispatch(
       function() {
         Services.obs.notifyObservers(observerSubject,
                                      CSP_VIOLATION_TOPIC,
                                      violatedDirective);
-        reportSender.sendReports(blockedContentSource, originalUri,
-                                 violatedDirective,
+        reportSender.sendReports(blockedContentSource, violatedDirective,
                                  aSourceFile, aScriptSample, aLineNum);
       }, Ci.nsIThread.DISPATCH_NORMAL);
   },
 };
 
 // The POST of the violation report (if it happens) should not follow
 // redirects, per the spec. hence, we implement an nsIChannelEventSink
 // with an object so we can tell XHR to abort if a redirect happens.
--- a/content/base/src/nsCSPService.cpp
+++ b/content/base/src/nsCSPService.cpp
@@ -91,23 +91,22 @@ CSPService::ShouldLoad(PRUint32 aContent
 #ifdef PR_LOGGING
             nsAutoString policy;
             csp->GetPolicy(policy);
             PR_LOG(gCspPRLog, PR_LOG_DEBUG,
                     ("Document has CSP: %s",
                      NS_ConvertUTF16toUTF8(policy).get()));
 #endif
             // obtain the enforcement decision
-            // (don't pass aExtra, we use that slot for redirects)
             csp->ShouldLoad(aContentType,
                             aContentLocation,
                             aRequestOrigin,
                             aRequestContext,
                             aMimeTypeGuess,
-                            nsnull,
+                            aExtra,
                             aDecision);
         }
     }
 #ifdef PR_LOGGING
     else {
         nsCAutoString uriSpec;
         aContentLocation->GetSpec(uriSpec);
         PR_LOG(gCspPRLog, PR_LOG_DEBUG,
@@ -216,25 +215,23 @@ CSPService::AsyncOnChannelRedirect(nsICh
    * the new channel's property bag. This container is propagated forward when
    * channels redirect.
    */
 
   // Does the CSP permit this host for this type of load?
   // If not, cancel the load now.
   nsCOMPtr<nsIURI> newUri;
   newChannel->GetURI(getter_AddRefs(newUri));
-  nsCOMPtr<nsIURI> originalUri;
-  oldChannel->GetOriginalURI(getter_AddRefs(originalUri));
   PRInt16 aDecision = nsIContentPolicy::ACCEPT;
   csp->ShouldLoad(loadType,        // load type per nsIContentPolicy (PRUint32)
                   newUri,          // nsIURI
                   nsnull,          // nsIURI
                   nsnull,          // nsISupports
                   EmptyCString(),  // ACString - MIME guess
-                  originalUri,     // nsISupports - extra
+                  nsnull,          // nsISupports - extra
                   &aDecision);
 
 #ifdef PR_LOGGING
   if (newUri) {
     nsCAutoString newUriSpec("None");
     newUri->GetSpec(newUriSpec);
     PR_LOG(gCspPRLog, PR_LOG_DEBUG,
            ("CSPService::AsyncOnChannelRedirect called for %s",
--- a/content/base/test/test_bug548193.html
+++ b/content/base/test/test_bug548193.html
@@ -77,18 +77,18 @@ examiner.prototype  = {
 }
 
 // content file that triggers a violation report
 var testFile = "file_bug548193.sjs";
 
 window.checkResults = function(reportObj) {
   var cspReport = reportObj["csp-report"];
   // correct violating request
-  is(cspReport["document-uri"],
-     "http://mochi.test:8888/tests/content/base/test/" + testFile,
+  is(cspReport["request"],
+     "GET http://mochi.test:8888/tests/content/base/test/" + testFile + " HTTP/1.1",
      "Incorrect violating request");
   // correct blocked-uri
   is(cspReport["blocked-uri"],
      "http://example.org/tests/content/base/test/file_CSP.sjs?testid=img_bad&type=img/png",
      "Incorrect blocked uri");
   // correct violated-directive
   is(cspReport["violated-directive"], "default-src http://mochi.test:8888",
      "Incorrect violated directive");