nsresult
TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
             nsILoadGroup* aLoadGroup, nsIPrincipal* aCallerPrincipal)
{
    nsCAutoString spec;
    aUri->GetSpec(spec);
    PR_LOG(txLog::xslt, PR_LOG_ALWAYS, ("TX_LoadSheet: %s\n", spec.get()));

    // Content Policy
    PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
    nsresult rv =
        NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
                                  aUri,
                                  aCallerPrincipal,
                                  aProcessor->GetSourceContentModel(),
                                  NS_LITERAL_CSTRING("application/xml"),
                                  nsnull,
                                  &shouldLoad);
    NS_ENSURE_SUCCESS(rv, rv);
    if (NS_CP_REJECTED(shouldLoad)) {
        return NS_ERROR_DOM_BAD_URI;
    }

    nsRefPtr<txCompileObserver> observer =
        new txCompileObserver(aProcessor, aLoadGroup);
    NS_ENSURE_TRUE(observer, NS_ERROR_OUT_OF_MEMORY);

    nsRefPtr<txStylesheetCompiler> compiler =
        new txStylesheetCompiler(NS_ConvertUTF8toUTF16(spec), observer);
    NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);

    return observer->startLoad(aUri, compiler, aCallerPrincipal);
}
nsresult
txSyncCompileObserver::loadURI(const nsAString& aUri,
                               const nsAString& aReferrerUri,
                               txStylesheetCompiler* aCompiler)
{
    if (mProcessor->IsLoadDisabled()) {
        return NS_ERROR_XSLT_LOAD_BLOCKED_ERROR;
    }

    nsCOMPtr<nsIURI> uri;
    nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIURI> referrerUri;
    rv = NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIPrincipal> referrerPrincipal;
    rv = nsContentUtils::GetSecurityManager()->
      GetCodebasePrincipal(referrerUri, getter_AddRefs(referrerPrincipal));
    NS_ENSURE_SUCCESS(rv, rv);

    // Content Policy
    PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
    rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
                                   uri,
                                   referrerPrincipal,
                                   nsnull,
                                   NS_LITERAL_CSTRING("application/xml"),
                                   nsnull,
                                   &shouldLoad);
    NS_ENSURE_SUCCESS(rv, rv);
    if (NS_CP_REJECTED(shouldLoad)) {
        return NS_ERROR_DOM_BAD_URI;
    }

    // This is probably called by js, a loadGroup for the channel doesn't
    // make sense.
    nsCOMPtr<nsIDOMDocument> document;
    rv = nsSyncLoadService::LoadDocument(uri, referrerPrincipal, nsnull,
                                         PR_FALSE, getter_AddRefs(document));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
    rv = handleNode(doc, aCompiler);
    if (NS_FAILED(rv)) {
        nsCAutoString spec;
        uri->GetSpec(spec);
        aCompiler->cancel(rv, nsnull, NS_ConvertUTF8toUTF16(spec).get());
        return rv;
    }

    rv = aCompiler->doneLoading();
    return rv;
}
Exemple #3
0
void
ImportLoader::Open()
{
  AutoError ae(this, false);
  // Imports should obey to the master documents CSP.
  nsCOMPtr<nsIDocument> master = mImportParent->MasterDocument();
  nsIPrincipal* principal = Principal();

  int16_t shouldLoad = nsIContentPolicy::ACCEPT;
  nsresult rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_SUBDOCUMENT,
                                          mURI,
                                          principal,
                                          mImportParent,
                                          NS_LITERAL_CSTRING("text/html"),
                                          /* extra = */ nullptr,
                                          &shouldLoad,
                                          nsContentUtils::GetContentPolicy(),
                                          nsContentUtils::GetSecurityManager());
  if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
    NS_WARN_IF_FALSE(NS_CP_ACCEPTED(shouldLoad), "ImportLoader rejected by CSP");
    return;
  }

  nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
  rv = secMan->CheckLoadURIWithPrincipal(principal, mURI,
                                         nsIScriptSecurityManager::STANDARD);
  NS_ENSURE_SUCCESS_VOID(rv);

  nsCOMPtr<nsILoadGroup> loadGroup = master->GetDocumentLoadGroup();
  nsCOMPtr<nsIChannel> channel;
  rv = NS_NewChannel(getter_AddRefs(channel),
                     mURI,
                     mImportParent,
                     nsILoadInfo::SEC_NORMAL,
                     nsIContentPolicy::TYPE_SUBDOCUMENT,
                     loadGroup,
                     nullptr,  // aCallbacks
                     nsIRequest::LOAD_BACKGROUND);

  NS_ENSURE_SUCCESS_VOID(rv);

  // Init CORSListenerProxy and omit credentials.
  nsRefPtr<nsCORSListenerProxy> corsListener =
    new nsCORSListenerProxy(this, principal,
                            /* aWithCredentials */ false);
  rv = corsListener->Init(channel, true);
  NS_ENSURE_SUCCESS_VOID(rv);

  rv = channel->AsyncOpen(corsListener, nullptr);
  NS_ENSURE_SUCCESS_VOID(rv);

  BlockScripts();
  ae.Pass();
}
nsresult
txCompileObserver::loadURI(const nsAString& aUri,
                           const nsAString& aReferrerUri,
                           txStylesheetCompiler* aCompiler)
{
    if (mProcessor->IsLoadDisabled()) {
        return NS_ERROR_XSLT_LOAD_BLOCKED_ERROR;
    }

    nsCOMPtr<nsIURI> uri;
    nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIURI> referrerUri;
    rv = NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIPrincipal> referrerPrincipal;
    rv = nsContentUtils::GetSecurityManager()->
      GetCodebasePrincipal(referrerUri, getter_AddRefs(referrerPrincipal));
    NS_ENSURE_SUCCESS(rv, rv);

    // Content Policy
    PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
    rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
                                   uri,
                                   referrerPrincipal,
                                   nsnull,
                                   NS_LITERAL_CSTRING("application/xml"),
                                   nsnull,
                                   &shouldLoad);
    NS_ENSURE_SUCCESS(rv, rv);
    if (NS_CP_REJECTED(shouldLoad)) {
        return NS_ERROR_DOM_BAD_URI;
    }

    return startLoad(uri, aCompiler, referrerPrincipal);
}
nsresult
nsFontFaceLoader::CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
                                   nsIURI* aTargetURI,
                                   nsISupports* aContext)
{
  nsresult rv;
  
  if (!aSourcePrincipal)
    return NS_OK;

  // check with the security manager
  nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
  rv = secMan->CheckLoadURIWithPrincipal(aSourcePrincipal, aTargetURI,
                                        nsIScriptSecurityManager::STANDARD);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // check content policy
  PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
  rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_FONT,
                                 aTargetURI,
                                 aSourcePrincipal,
                                 aContext,
                                 EmptyCString(), // mime type
                                 nsnull,
                                 &shouldLoad,
                                 nsContentUtils::GetContentPolicy(),
                                 nsContentUtils::GetSecurityManager());

  if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
    return NS_ERROR_CONTENT_BLOCKED;
  }

  return NS_OK;
}
void
HTMLTrackElement::LoadResource()
{
  // Find our 'src' url
  nsAutoString src;
  if (!GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
    return;
  }

  nsCOMPtr<nsIURI> uri;
  nsresult rv = NewURIFromString(src, getter_AddRefs(uri));
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
  LOG(PR_LOG_ALWAYS, ("%p Trying to load from src=%s", this,
      NS_ConvertUTF16toUTF8(src).get()));

  if (mChannel) {
    mChannel->Cancel(NS_BINDING_ABORTED);
    mChannel = nullptr;
  }

  rv = nsContentUtils::GetSecurityManager()->
    CheckLoadURIWithPrincipal(NodePrincipal(), uri,
                              nsIScriptSecurityManager::STANDARD);
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));

  int16_t shouldLoad = nsIContentPolicy::ACCEPT;
  rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_MEDIA,
                                 uri,
                                 NodePrincipal(),
                                 static_cast<Element*>(this),
                                 NS_LITERAL_CSTRING("text/vtt"), // mime type
                                 nullptr, // extra
                                 &shouldLoad,
                                 nsContentUtils::GetContentPolicy(),
                                 nsContentUtils::GetSecurityManager());
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
  if (NS_CP_REJECTED(shouldLoad)) {
    return;
  }

  CreateTextTrack();

  // Check for a Content Security Policy to pass down to the channel
  // created to load the media content.
  nsCOMPtr<nsIChannelPolicy> channelPolicy;
  nsCOMPtr<nsIContentSecurityPolicy> csp;
  rv = NodePrincipal()->GetCsp(getter_AddRefs(csp));
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
  if (csp) {
    channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
    if (!channelPolicy) {
      return;
    }
    channelPolicy->SetContentSecurityPolicy(csp);
    channelPolicy->SetLoadType(nsIContentPolicy::TYPE_MEDIA);
  }
  nsCOMPtr<nsIChannel> channel;
  nsCOMPtr<nsILoadGroup> loadGroup = OwnerDoc()->GetDocumentLoadGroup();
  rv = NS_NewChannel(getter_AddRefs(channel),
                     uri,
                     nullptr,
                     loadGroup,
                     nullptr,
                     nsIRequest::LOAD_NORMAL,
                     channelPolicy);
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));

  mLoadListener = new WebVTTLoadListener(this);
  rv = mLoadListener->LoadResource();
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
  channel->SetNotificationCallbacks(mLoadListener);

  LOG(PR_LOG_DEBUG, ("opening webvtt channel"));
  rv = channel->AsyncOpen(mLoadListener, nullptr);
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));

  mChannel = channel;
}
static nsresult
DoContentSecurityChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo)
{
  nsContentPolicyType contentPolicyType =
    aLoadInfo->GetExternalContentPolicyType();
  nsContentPolicyType internalContentPolicyType =
    aLoadInfo->InternalContentPolicyType();
  nsCString mimeTypeGuess;
  nsCOMPtr<nsINode> requestingContext = nullptr;

  switch(contentPolicyType) {
    case nsIContentPolicy::TYPE_OTHER: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_SCRIPT: {
      mimeTypeGuess = NS_LITERAL_CSTRING("application/javascript");
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_IMAGE: {
      MOZ_ASSERT(false, "contentPolicyType not supported yet");
      break;
    }

    case nsIContentPolicy::TYPE_STYLESHEET: {
      mimeTypeGuess = NS_LITERAL_CSTRING("text/css");
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_OBJECT:
    case nsIContentPolicy::TYPE_DOCUMENT: {
      MOZ_ASSERT(false, "contentPolicyType not supported yet");
      break;
    }

    case nsIContentPolicy::TYPE_SUBDOCUMENT: {
      mimeTypeGuess = NS_LITERAL_CSTRING("text/html");
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                 "type_subdocument requires requestingContext of type Document");
      break;
    }

    case nsIContentPolicy::TYPE_REFRESH: {
      MOZ_ASSERT(false, "contentPolicyType not supported yet");
      break;
    }

    case nsIContentPolicy::TYPE_XBL: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_PING: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_XMLHTTPREQUEST: {
      // alias nsIContentPolicy::TYPE_DATAREQUEST:
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                 "type_xml requires requestingContext of type Document");

      // We're checking for the external TYPE_XMLHTTPREQUEST here in case
      // an addon creates a request with that type.
      if (internalContentPolicyType ==
            nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST ||
          internalContentPolicyType ==
            nsIContentPolicy::TYPE_XMLHTTPREQUEST) {
        mimeTypeGuess = EmptyCString();
      }
      else {
        MOZ_ASSERT(internalContentPolicyType ==
                   nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE,
                   "can not set mime type guess for unexpected internal type");
        mimeTypeGuess = NS_LITERAL_CSTRING(TEXT_EVENT_STREAM);
      }
      break;
    }

    case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE,
                 "type_subrequest requires requestingContext of type Element");
      break;
    }

    case nsIContentPolicy::TYPE_DTD: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                 "type_dtd requires requestingContext of type Document");
      break;
    }

    case nsIContentPolicy::TYPE_FONT: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_MEDIA: {
      if (internalContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_TRACK) {
        mimeTypeGuess = NS_LITERAL_CSTRING("text/vtt");
      }
      else {
        mimeTypeGuess = EmptyCString();
      }
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE,
                 "type_media requires requestingContext of type Element");
      break;
    }

    case nsIContentPolicy::TYPE_WEBSOCKET: {
      MOZ_ASSERT(false, "contentPolicyType not supported yet");
      break;
    }

    case nsIContentPolicy::TYPE_CSP_REPORT: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_XSLT: {
      mimeTypeGuess = NS_LITERAL_CSTRING("application/xml");
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                 "type_xslt requires requestingContext of type Document");
      break;
    }

    case nsIContentPolicy::TYPE_BEACON: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      MOZ_ASSERT(!requestingContext ||
                 requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                 "type_beacon requires requestingContext of type Document");
      break;
    }

    case nsIContentPolicy::TYPE_FETCH: {
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
      break;
    }

    case nsIContentPolicy::TYPE_IMAGESET: {
      MOZ_ASSERT(false, "contentPolicyType not supported yet");
      break;
    }

    default:
      // nsIContentPolicy::TYPE_INVALID
      MOZ_ASSERT(false, "can not perform security check without a valid contentType");
  }

  int16_t shouldLoad = nsIContentPolicy::ACCEPT;
  nsresult rv = NS_CheckContentLoadPolicy(internalContentPolicyType,
                                          aURI,
                                          aLoadInfo->LoadingPrincipal(),
                                          requestingContext,
                                          mimeTypeGuess,
                                          nullptr,        //extra,
                                          &shouldLoad,
                                          nsContentUtils::GetContentPolicy(),
                                          nsContentUtils::GetSecurityManager());
  NS_ENSURE_SUCCESS(rv, rv);
  if (NS_CP_REJECTED(shouldLoad)) {
    return NS_ERROR_CONTENT_BLOCKED;
  }
  return NS_OK;
}
nsresult
nsExpatDriver::OpenInputStreamFromExternalDTD(const PRUnichar* aFPIStr,
                                              const PRUnichar* aURLStr,
                                              const PRUnichar* aBaseURL,
                                              nsIInputStream** aStream,
                                              nsAString& aAbsURL)
{
  nsCOMPtr<nsIURI> baseURI;
  nsresult rv = NS_NewURI(getter_AddRefs(baseURI),
                          NS_ConvertUTF16toUTF8(aBaseURL));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIURI> uri;
  rv = NS_NewURI(getter_AddRefs(uri), NS_ConvertUTF16toUTF8(aURLStr), nsnull,
                 baseURI);
  NS_ENSURE_SUCCESS(rv, rv);

  // check if it is alright to load this uri
  PRBool isChrome = PR_FALSE;
  uri->SchemeIs("chrome", &isChrome);
  if (!isChrome) {
    // since the url is not a chrome url, check to see if we can map the DTD
    // to a known local DTD, or if a DTD file of the same name exists in the
    // special DTD directory
    if (aFPIStr) {
      // see if the Formal Public Identifier (FPI) maps to a catalog entry
      mCatalogData = LookupCatalogData(aFPIStr);
    }

    nsCOMPtr<nsIURI> localURI;
    GetLocalDTDURI(mCatalogData, uri, getter_AddRefs(localURI));
    if (!localURI) {
      return NS_ERROR_NOT_IMPLEMENTED;
    }

    localURI.swap(uri);
  }

  nsCOMPtr<nsIDocument> doc;
  NS_ASSERTION(mSink == nsCOMPtr<nsIExpatSink>(do_QueryInterface(mOriginalSink)),
               "In nsExpatDriver::OpenInputStreamFromExternalDTD: "
               "mOriginalSink not the same object as mSink?");
  if (mOriginalSink)
    doc = do_QueryInterface(mOriginalSink->GetTarget());
  PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
  rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_DTD,
                                uri,
                                (doc ? doc->NodePrincipal() : nsnull),
                                doc,
                                EmptyCString(), //mime guess
                                nsnull,         //extra
                                &shouldLoad);
  if (NS_FAILED(rv)) return rv;
  if (NS_CP_REJECTED(shouldLoad)) {
    // Disallowed by content policy
    return NS_ERROR_CONTENT_BLOCKED;
  }

  nsCAutoString absURL;
  uri->GetSpec(absURL);

  CopyUTF8toUTF16(absURL, aAbsURL);

  nsCOMPtr<nsIChannel> channel;
  rv = NS_NewChannel(getter_AddRefs(channel), uri);
  NS_ENSURE_SUCCESS(rv, rv);

  channel->SetContentType(NS_LITERAL_CSTRING("application/xml"));
  return channel->Open(aStream);
}
Exemple #9
0
nsresult
nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
{
    // We need a document to evaluate scripts.
    NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE);

    // Check to see if scripts has been turned off.
    if (!mEnabled || !mDocument->IsScriptEnabled()) {
        return NS_ERROR_NOT_AVAILABLE;
    }

    NS_ASSERTION(!aElement->IsMalformed(), "Executing malformed script");

    // Check that the script is not an eventhandler
    if (IsScriptEventHandler(aElement)) {
        return NS_CONTENT_SCRIPT_IS_EVENTHANDLER;
    }

    // Script evaluation can also be disabled in the current script
    // context even though it's enabled in the document.
    // XXX - still hard-coded for JS here, even though another language
    // may be specified.  Should this check be made *after* we examine
    // the attributes to locate the script-type?
    // For now though, if JS is disabled we assume every language is
    // disabled.
    // XXX is this different from the mDocument->IsScriptEnabled() call?
    nsIScriptGlobalObject *globalObject = mDocument->GetScriptGlobalObject();
    if (!globalObject) {
        return NS_ERROR_NOT_AVAILABLE;
    }

    nsIScriptContext *context = globalObject->GetScriptContext(
                                    nsIProgrammingLanguage::JAVASCRIPT);

    // If scripts aren't enabled in the current context, there's no
    // point in going on.
    if (!context || !context->GetScriptsEnabled()) {
        return NS_ERROR_NOT_AVAILABLE;
    }

    // Default script language is whatever the root content specifies
    // (which may come from a header or http-meta tag), or if there
    // is no root content, from the script global object.
    nsCOMPtr<nsIContent> rootContent = mDocument->GetRootContent();
    PRUint32 typeID = rootContent ? rootContent->GetScriptTypeID() :
                      context->GetScriptTypeID();
    PRUint32 version = 0;
    nsAutoString language, type, src;
    nsresult rv = NS_OK;

    // Check the type attribute to determine language and version.
    // If type exists, it trumps the deprecated 'language='
    aElement->GetScriptType(type);
    if (!type.IsEmpty()) {
        nsCOMPtr<nsIMIMEHeaderParam> mimeHdrParser =
            do_GetService("@mozilla.org/network/mime-hdrparam;1");
        NS_ENSURE_TRUE(mimeHdrParser, NS_ERROR_FAILURE);

        NS_ConvertUTF16toUTF8 typeAndParams(type);

        nsAutoString mimeType;
        rv = mimeHdrParser->GetParameter(typeAndParams, nsnull,
                                         EmptyCString(), PR_FALSE, nsnull,
                                         mimeType);
        NS_ENSURE_SUCCESS(rv, rv);

        // Javascript keeps the fast path, optimized for most-likely type
        // Table ordered from most to least likely JS MIME types.
        // See bug 62485, feel free to add <script type="..."> survey data to it,
        // or to a new bug once 62485 is closed.
        static const char *jsTypes[] = {
            "text/javascript",
            "text/ecmascript",
            "application/javascript",
            "application/ecmascript",
            "application/x-javascript",
            nsnull
        };

        PRBool isJavaScript = PR_FALSE;
        for (PRInt32 i = 0; jsTypes[i]; i++) {
            if (mimeType.LowerCaseEqualsASCII(jsTypes[i])) {
                isJavaScript = PR_TRUE;
                break;
            }
        }
        if (isJavaScript)
            typeID = nsIProgrammingLanguage::JAVASCRIPT;
        else {
            // Use the object factory to locate a matching language.
            nsCOMPtr<nsIScriptRuntime> runtime;
            rv = NS_GetScriptRuntime(mimeType, getter_AddRefs(runtime));
            if (NS_FAILED(rv) || runtime == nsnull) {
                // Failed to get the explicitly specified language
                NS_WARNING("Failed to find a scripting language");
                typeID = nsIProgrammingLanguage::UNKNOWN;
            } else
                typeID = runtime->GetScriptTypeID();
        }
        if (typeID != nsIProgrammingLanguage::UNKNOWN) {
            // Get the version string, and ensure the language supports it.
            nsAutoString versionName;
            rv = mimeHdrParser->GetParameter(typeAndParams, "version",
                                             EmptyCString(), PR_FALSE, nsnull,
                                             versionName);
            if (NS_FAILED(rv)) {
                // no version attribute - version remains 0.
                if (rv != NS_ERROR_INVALID_ARG)
                    return rv;
            } else {
                nsCOMPtr<nsIScriptRuntime> runtime;
                rv = NS_GetScriptRuntimeByID(typeID, getter_AddRefs(runtime));
                if (NS_FAILED(rv)) {
                    NS_ERROR("Failed to locate the language with this ID");
                    return rv;
                }
                rv = runtime->ParseVersion(versionName, &version);
                if (NS_FAILED(rv)) {
                    NS_WARNING("This script language version is not supported - ignored");
                    typeID = nsIProgrammingLanguage::UNKNOWN;
                }
            }
        }

        // Some js specifics yet to be abstracted.
        if (typeID == nsIProgrammingLanguage::JAVASCRIPT) {
            nsAutoString value;

            rv = mimeHdrParser->GetParameter(typeAndParams, "e4x",
                                             EmptyCString(), PR_FALSE, nsnull,
                                             value);
            if (NS_FAILED(rv)) {
                if (rv != NS_ERROR_INVALID_ARG)
                    return rv;
            } else {
                if (value.Length() == 1 && value[0] == '1')
                    // This means that we need to set JSOPTION_XML in the JS options.
                    // We re-use our knowledge of the implementation to reuse
                    // JSVERSION_HAS_XML as a safe version flag.
                    // If version has JSVERSION_UNKNOWN (-1), then this is still OK.
                    version |= JSVERSION_HAS_XML;
            }
        }
    } else {
        // no 'type=' element
        // "language" is a deprecated attribute of HTML, so we check it only for
        // HTML script elements.
        nsCOMPtr<nsIDOMHTMLScriptElement> htmlScriptElement =
            do_QueryInterface(aElement);
        if (htmlScriptElement) {
            htmlScriptElement->GetAttribute(NS_LITERAL_STRING("language"), language);
            if (!language.IsEmpty()) {
                if (nsParserUtils::IsJavaScriptLanguage(language, &version))
                    typeID = nsIProgrammingLanguage::JAVASCRIPT;
                else
                    typeID = nsIProgrammingLanguage::UNKNOWN;
                // IE, Opera, etc. do not respect language version, so neither should
                // we at this late date in the browser wars saga.  Note that this change
                // affects HTML but not XUL or SVG (but note also that XUL has its own
                // code to check nsParserUtils::IsJavaScriptLanguage -- that's probably
                // a separate bug, one we may not be able to fix short of XUL2).  See
                // bug 255895 (https://bugzilla.mozilla.org/show_bug.cgi?id=255895).
                NS_ASSERTION(JSVERSION_DEFAULT == 0,
                             "We rely on all languages having 0 as a version default");
                version = 0;
            }
        }
    }

    // If we don't know the language, we don't know how to evaluate
    if (typeID == nsIProgrammingLanguage::UNKNOWN) {
        return NS_ERROR_NOT_AVAILABLE;
    }
    // If not from a chrome document (which is always trusted), we need some way
    // of checking the language is "safe".  Currently the only other language
    // impl is Python, and that is *not* safe in untrusted code - so fixing
    // this isn't a priority.!
    // See also similar code in nsXULContentSink.cpp
    if (typeID != nsIProgrammingLanguage::JAVASCRIPT &&
            !nsContentUtils::IsChromeDoc(mDocument)) {
        NS_WARNING("Untrusted language called from non-chrome - ignored");
        return NS_ERROR_NOT_AVAILABLE;
    }

    nsCOMPtr<nsIContent> eltContent(do_QueryInterface(aElement));
    eltContent->SetScriptTypeID(typeID);

    // Create a request object for this script
    nsRefPtr<nsScriptLoadRequest> request = new nsScriptLoadRequest(aElement, version);
    NS_ENSURE_TRUE(request, NS_ERROR_OUT_OF_MEMORY);

    // First check to see if this is an external script
    nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
    if (scriptURI) {
        // Check that the containing page is allowed to load this URI.
        rv = nsContentUtils::GetSecurityManager()->
             CheckLoadURIWithPrincipal(mDocument->NodePrincipal(), scriptURI,
                                       nsIScriptSecurityManager::ALLOW_CHROME);

        NS_ENSURE_SUCCESS(rv, rv);

        // After the security manager, the content-policy stuff gets a veto
        PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
        rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_SCRIPT,
                                       scriptURI,
                                       mDocument->NodePrincipal(),
                                       aElement,
                                       NS_LossyConvertUTF16toASCII(type),
                                       nsnull,    //extra
                                       &shouldLoad,
                                       nsContentUtils::GetContentPolicy(),
                                       nsContentUtils::GetSecurityManager());
        if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
            if (NS_FAILED(rv) || shouldLoad != nsIContentPolicy::REJECT_TYPE) {
                return NS_ERROR_CONTENT_BLOCKED;
            }
            return NS_ERROR_CONTENT_BLOCKED_SHOW_ALT;
        }

        request->mURI = scriptURI;
        request->mIsInline = PR_FALSE;
        request->mLoading = PR_TRUE;

        nsCOMPtr<nsILoadGroup> loadGroup = mDocument->GetDocumentLoadGroup();
        nsCOMPtr<nsIStreamLoader> loader;

        nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(globalObject));
        nsIDocShell *docshell = window->GetDocShell();

        nsCOMPtr<nsIInterfaceRequestor> prompter(do_QueryInterface(docshell));

        nsCOMPtr<nsIChannel> channel;
        rv = NS_NewChannel(getter_AddRefs(channel),
                           scriptURI, nsnull, loadGroup,
                           prompter, nsIRequest::LOAD_NORMAL);
        NS_ENSURE_SUCCESS(rv, rv);

        nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
        if (httpChannel) {
            // HTTP content negotation has little value in this context.
            httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
                                          NS_LITERAL_CSTRING("*/*"),
                                          PR_FALSE);
            httpChannel->SetReferrer(mDocument->GetDocumentURI());
        }

        rv = NS_NewStreamLoader(getter_AddRefs(loader), this);
        NS_ENSURE_SUCCESS(rv, rv);

        rv = channel->AsyncOpen(loader, request);
        NS_ENSURE_SUCCESS(rv, rv);
    } else {
        request->mLoading = PR_FALSE;
        request->mIsInline = PR_TRUE;
        request->mURI = mDocument->GetDocumentURI();

        request->mLineNo = aElement->GetScriptLineNumber();

        // If we've got existing pending requests, add ourselves
        // to this list.
        if (mPendingRequests.Count() == 0 && ReadyToExecuteScripts() &&
                nsContentUtils::IsSafeToRunScript()) {
            return ProcessRequest(request);
        }
    }

    // Add the request to our pending requests list
    NS_ENSURE_TRUE(mPendingRequests.AppendObject(request),
                   NS_ERROR_OUT_OF_MEMORY);

    // If there weren't any pending requests before, and this one is
    // ready to execute, do that as soon as it's safe.
    if (mPendingRequests.Count() == 1 && !request->mLoading &&
            ReadyToExecuteScripts()) {
        nsContentUtils::AddScriptRunner(new nsRunnableMethod<nsScriptLoader>(this,
                                        &nsScriptLoader::ProcessPendingRequests));
    }

    // Added as pending request, now we can send blocking back
    return NS_ERROR_HTMLPARSER_BLOCK;
}
Exemple #10
0
FetchDriver::MainFetchOp
FetchDriver::SetTaintingAndGetNextOp(bool aCORSFlag)
{
  workers::AssertIsOnMainThread();

  nsAutoCString url;
  mRequest->GetURL(url);
  nsCOMPtr<nsIURI> requestURI;
  nsresult rv = NS_NewURI(getter_AddRefs(requestURI), url,
                          nullptr, nullptr);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return MainFetchOp(NETWORK_ERROR);
  }

  // CSP/mixed content checks.
  int16_t shouldLoad;
  rv = NS_CheckContentLoadPolicy(mRequest->ContentPolicyType(),
                                 requestURI,
                                 mPrincipal,
                                 mDocument,
                                 // FIXME(nsm): Should MIME be extracted from
                                 // Content-Type header?
                                 EmptyCString(), /* mime guess */
                                 nullptr, /* extra */
                                 &shouldLoad,
                                 nsContentUtils::GetContentPolicy(),
                                 nsContentUtils::GetSecurityManager());
  if (NS_WARN_IF(NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad))) {
    // Disallowed by content policy.
    return MainFetchOp(NETWORK_ERROR);
  }

  // Begin Step 8 of the Main Fetch algorithm
  // https://fetch.spec.whatwg.org/#fetching

  nsAutoCString scheme;
  rv = requestURI->GetScheme(scheme);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return MainFetchOp(NETWORK_ERROR);
  }

  // request's current url's origin is request's origin and the CORS flag is unset
  // request's current url's scheme is "data" and request's same-origin data-URL flag is set
  // request's current url's scheme is "about"
  rv = mPrincipal->CheckMayLoad(requestURI, false /* report */,
                                false /* allowIfInheritsPrincipal */);
  if ((!aCORSFlag && NS_SUCCEEDED(rv)) ||
      (scheme.EqualsLiteral("data") && mRequest->SameOriginDataURL()) ||
      scheme.EqualsLiteral("about")) {
    return MainFetchOp(BASIC_FETCH);
  }

  // request's mode is "same-origin"
  if (mRequest->Mode() == RequestMode::Same_origin) {
    return MainFetchOp(NETWORK_ERROR);
  }

  // request's mode is "no-cors"
  if (mRequest->Mode() == RequestMode::No_cors) {
    mRequest->SetResponseTainting(InternalRequest::RESPONSETAINT_OPAQUE);
    return MainFetchOp(BASIC_FETCH);
  }

  // request's current url's scheme is not one of "http" and "https"
  if (!scheme.EqualsLiteral("http") && !scheme.EqualsLiteral("https")) {
    return MainFetchOp(NETWORK_ERROR);
  }

  // request's mode is "cors-with-forced-preflight"
  // request's unsafe-request flag is set and either request's method is not
  // a simple method or a header in request's header list is not a simple header
  if (mRequest->Mode() == RequestMode::Cors_with_forced_preflight ||
      (mRequest->UnsafeRequest() && (!mRequest->HasSimpleMethod() ||
                                     !mRequest->Headers()->HasOnlySimpleHeaders()))) {
    mRequest->SetResponseTainting(InternalRequest::RESPONSETAINT_CORS);
    mRequest->SetRedirectMode(RequestRedirect::Error);

    // Note, the following text from Main Fetch step 8 is handled in
    // nsCORSListenerProxy when CheckRequestApproved() fails:
    //
    //  The result of performing an HTTP fetch using request with the CORS
    //  flag and CORS-preflight flag set. If the result is a network error,
    //  clear cache entries using request.

    return MainFetchOp(HTTP_FETCH, true /* cors */, true /* preflight */);
  }

  // Otherwise
  mRequest->SetResponseTainting(InternalRequest::RESPONSETAINT_CORS);
  return MainFetchOp(HTTP_FETCH, true /* cors */, false /* preflight */);
}
void
HTMLTrackElement::LoadResource()
{
  // Find our 'src' url
  nsAutoString src;
  if (!GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
    return;
  }

  nsCOMPtr<nsIURI> uri;
  nsresult rv = NewURIFromString(src, getter_AddRefs(uri));
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
  LOG(LogLevel::Info, ("%p Trying to load from src=%s", this,
      NS_ConvertUTF16toUTF8(src).get()));

  if (mChannel) {
    mChannel->Cancel(NS_BINDING_ABORTED);
    mChannel = nullptr;
  }

  rv = nsContentUtils::GetSecurityManager()->
    CheckLoadURIWithPrincipal(NodePrincipal(), uri,
                              nsIScriptSecurityManager::STANDARD);
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));

  int16_t shouldLoad = nsIContentPolicy::ACCEPT;
  rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_MEDIA,
                                 uri,
                                 NodePrincipal(),
                                 static_cast<Element*>(this),
                                 NS_LITERAL_CSTRING("text/vtt"), // mime type
                                 nullptr, // extra
                                 &shouldLoad,
                                 nsContentUtils::GetContentPolicy(),
                                 nsContentUtils::GetSecurityManager());
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
  if (NS_CP_REJECTED(shouldLoad)) {
    return;
  }

  // We may already have a TextTrack at this point if GetTrack() has already
  // been called. This happens, for instance, if script tries to get the
  // TextTrack before its mTrackElement has been bound to the DOM tree.
  if (!mTrack) {
    CreateTextTrack();
  }

  nsCOMPtr<nsIChannel> channel;
  nsCOMPtr<nsILoadGroup> loadGroup = OwnerDoc()->GetDocumentLoadGroup();
  rv = NS_NewChannel(getter_AddRefs(channel),
                     uri,
                     static_cast<Element*>(this),
                     nsILoadInfo::SEC_NORMAL,
                     nsIContentPolicy::TYPE_MEDIA,
                     loadGroup);

  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));

  mListener = new WebVTTListener(this);
  rv = mListener->LoadResource();
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
  channel->SetNotificationCallbacks(mListener);

  LOG(LogLevel::Debug, ("opening webvtt channel"));
  rv = channel->AsyncOpen(mListener, nullptr);
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));

  mChannel = channel;
}
nsresult
nsDOMWorkerScriptLoader::RunInternal()
{
  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");

  // Things we need to make all this work...
  nsCOMPtr<nsIDocument> parentDoc = mWorker->Pool()->ParentDocument();
  if (!parentDoc) {
    // Must have been canceled.
    return NS_ERROR_ABORT;
  }

  nsIPrincipal* principal;
  nsIURI* baseURI;

  if (mForWorker) {
    NS_ASSERTION(mScriptCount == 1, "Bad state!");

    nsRefPtr<nsDOMWorker> parentWorker = mWorker->GetParent();
    if (parentWorker) {
      principal = parentWorker->GetPrincipal();
      NS_ENSURE_STATE(principal);

      baseURI = parentWorker->GetURI();
      NS_ENSURE_STATE(baseURI);
    }
    else {
      principal = parentDoc->NodePrincipal();
      NS_ENSURE_STATE(principal);

      baseURI = parentDoc->GetDocBaseURI();
    }
  }
  else {
    principal = mWorker->GetPrincipal();
    baseURI = mWorker->GetURI();

    NS_ASSERTION(principal && baseURI, "Should have been set already!");
  }

  // All of these can potentially be null, but that should be ok. We'll either
  // succeed without them or fail below.
  nsCOMPtr<nsILoadGroup> loadGroup(parentDoc->GetDocumentLoadGroup());
  nsCOMPtr<nsIIOService> ios(do_GetIOService());

  for (PRUint32 index = 0; index < mScriptCount; index++) {
    ScriptLoadInfo& loadInfo = mLoadInfos[index];
    nsresult& rv = loadInfo.result;

    nsCOMPtr<nsIURI>& uri = loadInfo.finalURI;
    rv = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
                                                   loadInfo.url, parentDoc,
                                                   baseURI);
    if (NS_FAILED(rv)) {
      return rv;
    }

    nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
    NS_ENSURE_TRUE(secMan, NS_ERROR_FAILURE);

    PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
    rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_SCRIPT, uri,
                                   principal, parentDoc,
                                   NS_LITERAL_CSTRING("text/javascript"),
                                   nsnull, &shouldLoad,
                                   nsContentUtils::GetContentPolicy(), secMan);
    if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
      if (NS_FAILED(rv) || shouldLoad != nsIContentPolicy::REJECT_TYPE) {
        return NS_ERROR_CONTENT_BLOCKED;
      }
      return NS_ERROR_CONTENT_BLOCKED_SHOW_ALT;
    }

    // If this script loader is being used to make a new worker then we need to
    // do a same-origin check. Otherwise we need to clear the load with the
    // security manager.
    if (mForWorker) {
      rv = principal->CheckMayLoad(uri, PR_FALSE);
      NS_ENSURE_SUCCESS(rv, rv);

      // Set the principal and URI on the new worker.
      mWorker->SetPrincipal(principal);

      rv = mWorker->SetURI(uri);
      NS_ENSURE_SUCCESS(rv, rv);
    }
    else {
      rv = secMan->CheckLoadURIWithPrincipal(principal, uri, 0);
      NS_ENSURE_SUCCESS(rv, rv);
    }

    // We need to know which index we're on in OnStreamComplete so we know where
    // to put the result.
    nsCOMPtr<nsISupportsPRUint32> indexSupports =
      do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = indexSupports->SetData(index);
    NS_ENSURE_SUCCESS(rv, rv);

    // We don't care about progress so just use the simple stream loader for
    // OnStreamComplete notification only.
    nsCOMPtr<nsIStreamLoader> loader;
    rv = NS_NewStreamLoader(getter_AddRefs(loader), this);
    NS_ENSURE_SUCCESS(rv, rv);

    // get Content Security Policy from parent document to pass into channel
    nsCOMPtr<nsIChannelPolicy> channelPolicy;
    nsCOMPtr<nsIContentSecurityPolicy> csp;
    rv = parentDoc->NodePrincipal()->GetCsp(getter_AddRefs(csp));
    NS_ENSURE_SUCCESS(rv, rv);
    if (csp) {
        channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
        channelPolicy->SetContentSecurityPolicy(csp);
        channelPolicy->SetLoadType(nsIContentPolicy::TYPE_SCRIPT);
    }

    rv = NS_NewChannel(getter_AddRefs(loadInfo.channel),
                       uri,
                       ios,
                       loadGroup,
                       nsnull,                            // callbacks
                       nsIRequest::LOAD_NORMAL |
                       nsIChannel::LOAD_CLASSIFY_URI,     // loadFlags
                       channelPolicy);                    // CSP info
    NS_ENSURE_SUCCESS(rv, rv);

    rv = loadInfo.channel->AsyncOpen(loader, indexSupports);
    if (NS_FAILED(rv)) {
      // Null this out so we don't try to cancel it later.
      loadInfo.channel = nsnull;
      return rv;
    }
  }

  return NS_OK;
}
static nsresult
DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
{
    nsCOMPtr<nsIURI> uri;
    nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
    NS_ENSURE_SUCCESS(rv, rv);

    nsContentPolicyType contentPolicyType =
        aLoadInfo->GetExternalContentPolicyType();
    nsContentPolicyType internalContentPolicyType =
        aLoadInfo->InternalContentPolicyType();
    nsCString mimeTypeGuess;
    nsCOMPtr<nsINode> requestingContext = nullptr;

#ifdef DEBUG
    // Don't enforce TYPE_DOCUMENT assertions for loads
    // initiated by javascript tests.
    bool skipContentTypeCheck = false;
    skipContentTypeCheck = Preferences::GetBool("network.loadinfo.skip_type_assertion");
#endif

    switch(contentPolicyType) {
    case nsIContentPolicy::TYPE_OTHER: {
        mimeTypeGuess = EmptyCString();
        requestingContext = aLoadInfo->LoadingNode();
        break;
    }

    case nsIContentPolicy::TYPE_SCRIPT: {
        mimeTypeGuess = NS_LITERAL_CSTRING("application/javascript");
        requestingContext = aLoadInfo->LoadingNode();
        break;
    }

    case nsIContentPolicy::TYPE_IMAGE: {
        mimeTypeGuess = EmptyCString();
        requestingContext = aLoadInfo->LoadingNode();
        break;
    }

    case nsIContentPolicy::TYPE_STYLESHEET: {
        mimeTypeGuess = NS_LITERAL_CSTRING("text/css");
        requestingContext = aLoadInfo->LoadingNode();
        break;
    }

    case nsIContentPolicy::TYPE_OBJECT: {
        mimeTypeGuess = EmptyCString();
        requestingContext = aLoadInfo->LoadingNode();
        break;
    }

    case nsIContentPolicy::TYPE_DOCUMENT: {
        MOZ_ASSERT(skipContentTypeCheck || false, "contentPolicyType not supported yet");
        break;
    }

    case nsIContentPolicy::TYPE_SUBDOCUMENT: {
        mimeTypeGuess = NS_LITERAL_CSTRING("text/html");
        requestingContext = aLoadInfo->LoadingNode();
        MOZ_ASSERT(!requestingContext ||
                   requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                   "type_subdocument requires requestingContext of type Document");
        break;
    }

    case nsIContentPolicy::TYPE_REFRESH: {
        MOZ_ASSERT(false, "contentPolicyType not supported yet");
        break;
    }

    case nsIContentPolicy::TYPE_XBL: {
        mimeTypeGuess = EmptyCString();
        requestingContext = aLoadInfo->LoadingNode();
        break;
    }

    case nsIContentPolicy::TYPE_PING: {
        mimeTypeGuess = EmptyCString();
        requestingContext = aLoadInfo->LoadingNode();
        break;
    }

    case nsIContentPolicy::TYPE_XMLHTTPREQUEST: {
        // alias nsIContentPolicy::TYPE_DATAREQUEST:
        requestingContext = aLoadInfo->LoadingNode();
        MOZ_ASSERT(!requestingContext ||
                   requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                   "type_xml requires requestingContext of type Document");

        // We're checking for the external TYPE_XMLHTTPREQUEST here in case
        // an addon creates a request with that type.
        if (internalContentPolicyType ==
                nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST ||
                internalContentPolicyType ==
                nsIContentPolicy::TYPE_XMLHTTPREQUEST) {
            mimeTypeGuess = EmptyCString();
        }
        else {
            MOZ_ASSERT(internalContentPolicyType ==
                       nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE,
                       "can not set mime type guess for unexpected internal type");
            mimeTypeGuess = NS_LITERAL_CSTRING(TEXT_EVENT_STREAM);
        }
        break;
    }

    case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST: {
        mimeTypeGuess = EmptyCString();
        requestingContext = aLoadInfo->LoadingNode();
        MOZ_ASSERT(!requestingContext ||
                   requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE,
                   "type_subrequest requires requestingContext of type Element");
        break;
    }

    case nsIContentPolicy::TYPE_DTD: {
        mimeTypeGuess = EmptyCString();
        requestingContext = aLoadInfo->LoadingNode();
        MOZ_ASSERT(!requestingContext ||
                   requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                   "type_dtd requires requestingContext of type Document");
        break;
    }

    case nsIContentPolicy::TYPE_FONT: {
        mimeTypeGuess = EmptyCString();
        requestingContext = aLoadInfo->LoadingNode();
        break;
    }

    case nsIContentPolicy::TYPE_MEDIA: {
        if (internalContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_TRACK) {
            mimeTypeGuess = NS_LITERAL_CSTRING("text/vtt");
        }
        else {
            mimeTypeGuess = EmptyCString();
        }
        requestingContext = aLoadInfo->LoadingNode();
        MOZ_ASSERT(!requestingContext ||
                   requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE,
                   "type_media requires requestingContext of type Element");
        break;
    }

    case nsIContentPolicy::TYPE_WEBSOCKET: {
        // Websockets have to use the proxied URI:
        // ws:// instead of http:// for CSP checks
        nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal
            = do_QueryInterface(aChannel);
        MOZ_ASSERT(httpChannelInternal);
        if (httpChannelInternal) {
            httpChannelInternal->GetProxyURI(getter_AddRefs(uri));
        }
        mimeTypeGuess = EmptyCString();
        requestingContext = aLoadInfo->LoadingNode();
        break;
    }

    case nsIContentPolicy::TYPE_CSP_REPORT: {
        mimeTypeGuess = EmptyCString();
        requestingContext = aLoadInfo->LoadingNode();
        break;
    }

    case nsIContentPolicy::TYPE_XSLT: {
        mimeTypeGuess = NS_LITERAL_CSTRING("application/xml");
        requestingContext = aLoadInfo->LoadingNode();
        MOZ_ASSERT(!requestingContext ||
                   requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                   "type_xslt requires requestingContext of type Document");
        break;
    }

    case nsIContentPolicy::TYPE_BEACON: {
        mimeTypeGuess = EmptyCString();
        requestingContext = aLoadInfo->LoadingNode();
        MOZ_ASSERT(!requestingContext ||
                   requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                   "type_beacon requires requestingContext of type Document");
        break;
    }

    case nsIContentPolicy::TYPE_FETCH: {
        mimeTypeGuess = EmptyCString();
        requestingContext = aLoadInfo->LoadingNode();
        break;
    }

    case nsIContentPolicy::TYPE_IMAGESET: {
        mimeTypeGuess = EmptyCString();
        requestingContext = aLoadInfo->LoadingNode();
        break;
    }

    case nsIContentPolicy::TYPE_WEB_MANIFEST: {
        mimeTypeGuess = NS_LITERAL_CSTRING("application/manifest+json");
        requestingContext = aLoadInfo->LoadingNode();
        break;
    }

    default:
        // nsIContentPolicy::TYPE_INVALID
        MOZ_ASSERT(false, "can not perform security check without a valid contentType");
    }

    int16_t shouldLoad = nsIContentPolicy::ACCEPT;
    rv = NS_CheckContentLoadPolicy(internalContentPolicyType,
                                   uri,
                                   aLoadInfo->LoadingPrincipal(),
                                   requestingContext,
                                   mimeTypeGuess,
                                   nullptr,        //extra,
                                   &shouldLoad,
                                   nsContentUtils::GetContentPolicy(),
                                   nsContentUtils::GetSecurityManager());
    NS_ENSURE_SUCCESS(rv, rv);
    if (NS_CP_REJECTED(shouldLoad)) {
        return NS_ERROR_CONTENT_BLOCKED;
    }

    if (nsMixedContentBlocker::sSendHSTSPriming) {
        rv = nsMixedContentBlocker::MarkLoadInfoForPriming(uri,
                requestingContext,
                aLoadInfo);
        return rv;
    }

    return NS_OK;
}
Exemple #14
0
nsresult
FetchDriver::ContinueFetch(bool aCORSFlag)
{
  workers::AssertIsOnMainThread();

  nsAutoCString url;
  mRequest->GetURL(url);
  nsCOMPtr<nsIURI> requestURI;
  nsresult rv = NS_NewURI(getter_AddRefs(requestURI), url,
                          nullptr, nullptr);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return FailWithNetworkError();
  }

  // CSP/mixed content checks.
  int16_t shouldLoad;
  rv = NS_CheckContentLoadPolicy(mRequest->ContentPolicyType(),
                                 requestURI,
                                 mPrincipal,
                                 mDocument,
                                 // FIXME(nsm): Should MIME be extracted from
                                 // Content-Type header?
                                 EmptyCString(), /* mime guess */
                                 nullptr, /* extra */
                                 &shouldLoad,
                                 nsContentUtils::GetContentPolicy(),
                                 nsContentUtils::GetSecurityManager());
  if (NS_WARN_IF(NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad))) {
    // Disallowed by content policy.
    return FailWithNetworkError();
  }

  // Begin Step 4 of the Fetch algorithm
  // https://fetch.spec.whatwg.org/#fetching

  nsAutoCString scheme;
  rv = requestURI->GetScheme(scheme);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return FailWithNetworkError();
  }

  rv = mPrincipal->CheckMayLoad(requestURI, false /* report */, false /* allowIfInheritsPrincipal */);
  if ((!aCORSFlag && NS_SUCCEEDED(rv)) ||
      (scheme.EqualsLiteral("data") && mRequest->SameOriginDataURL()) ||
      scheme.EqualsLiteral("about")) {
    return BasicFetch();
  }

  if (mRequest->Mode() == RequestMode::Same_origin) {
    return FailWithNetworkError();
  }

  if (mRequest->Mode() == RequestMode::No_cors) {
    mRequest->SetResponseTainting(InternalRequest::RESPONSETAINT_OPAQUE);
    return BasicFetch();
  }

  if (!scheme.EqualsLiteral("http") && !scheme.EqualsLiteral("https")) {
    return FailWithNetworkError();
  }

  bool corsPreflight = false;
  if (mRequest->Mode() == RequestMode::Cors_with_forced_preflight ||
      (mRequest->UnsafeRequest() && (!mRequest->HasSimpleMethod() || !mRequest->Headers()->HasOnlySimpleHeaders()))) {
    corsPreflight = true;
  }

  mRequest->SetResponseTainting(InternalRequest::RESPONSETAINT_CORS);
  return HttpFetch(true /* aCORSFlag */, corsPreflight);
}
nsresult
DoContentSecurityChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo)
{
  nsContentPolicyType contentPolicyType = aLoadInfo->GetContentPolicyType();
  nsCString mimeTypeGuess;
  nsCOMPtr<nsISupports> requestingContext = nullptr;

  switch(contentPolicyType) {
    case nsIContentPolicy::TYPE_OTHER:
    case nsIContentPolicy::TYPE_SCRIPT:
    case nsIContentPolicy::TYPE_IMAGE:
    case nsIContentPolicy::TYPE_STYLESHEET:
    case nsIContentPolicy::TYPE_OBJECT:
    case nsIContentPolicy::TYPE_DOCUMENT:
    case nsIContentPolicy::TYPE_SUBDOCUMENT:
    case nsIContentPolicy::TYPE_REFRESH:
    case nsIContentPolicy::TYPE_XBL:
    case nsIContentPolicy::TYPE_PING:
    case nsIContentPolicy::TYPE_XMLHTTPREQUEST:
    // alias nsIContentPolicy::TYPE_DATAREQUEST:
    case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST:
    case nsIContentPolicy::TYPE_DTD:
    case nsIContentPolicy::TYPE_FONT:
      MOZ_ASSERT(false, "contentPolicyType not supported yet");
      break;

    case nsIContentPolicy::TYPE_MEDIA:
      mimeTypeGuess = EmptyCString();
      requestingContext = aLoadInfo->LoadingNode();
#ifdef DEBUG
      {
        nsCOMPtr<mozilla::dom::Element> element = do_QueryInterface(requestingContext);
        NS_ASSERTION(element != nullptr,
                     "type_media requires requestingContext of type Element");
      }
#endif
      break;

    case nsIContentPolicy::TYPE_WEBSOCKET:
    case nsIContentPolicy::TYPE_CSP_REPORT:
    case nsIContentPolicy::TYPE_XSLT:
    case nsIContentPolicy::TYPE_BEACON:
    case nsIContentPolicy::TYPE_FETCH:
    case nsIContentPolicy::TYPE_IMAGESET:
      MOZ_ASSERT(false, "contentPolicyType not supported yet");
      break;

    default:
      // nsIContentPolicy::TYPE_INVALID
      MOZ_ASSERT(false, "can not perform security check without a valid contentType");
  }

  int16_t shouldLoad = nsIContentPolicy::ACCEPT;
  nsresult rv = NS_CheckContentLoadPolicy(contentPolicyType,
                                          aURI,
                                          aLoadInfo->LoadingPrincipal(),
                                          requestingContext,
                                          mimeTypeGuess,
                                          nullptr,        //extra,
                                          &shouldLoad,
                                          nsContentUtils::GetContentPolicy(),
                                          nsContentUtils::GetSecurityManager());
  NS_ENSURE_SUCCESS(rv, rv);
  if (NS_CP_REJECTED(shouldLoad)) {
    return NS_ERROR_CONTENT_BLOCKED;
  }
  return NS_OK;
}
NS_IMETHODIMP
nsXMLDocument::Load(const nsAString& aUrl, bool *aReturn)
{
  bool hasHadScriptObject = true;
  nsIScriptGlobalObject* scriptObject =
    GetScriptHandlingObject(hasHadScriptObject);
  NS_ENSURE_STATE(scriptObject || !hasHadScriptObject);

  ReportUseOfDeprecatedMethod(this, "UseOfDOM3LoadMethodWarning");

  NS_ENSURE_ARG_POINTER(aReturn);
  *aReturn = false;

  nsCOMPtr<nsIDocument> callingDoc =
    do_QueryInterface(nsContentUtils::GetDocumentFromContext());

  nsIURI *baseURI = mDocumentURI;
  nsAutoCString charset;

  if (callingDoc) {
    baseURI = callingDoc->GetDocBaseURI();
    charset = callingDoc->GetDocumentCharacterSet();
  }

  // Create a new URI
  nsCOMPtr<nsIURI> uri;
  nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl, charset.get(), baseURI);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // Check to see whether the current document is allowed to load this URI.
  // It's important to use the current document's principal for this check so
  // that we don't end up in a case where code with elevated privileges is
  // calling us and changing the principal of this document.

  // Enforce same-origin even for chrome loaders to avoid someone accidentally
  // using a document that content has a reference to and turn that into a
  // chrome document.
  nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
  if (!nsContentUtils::IsSystemPrincipal(principal)) {
    rv = principal->CheckMayLoad(uri, false, false);
    NS_ENSURE_SUCCESS(rv, rv);

    int16_t shouldLoad = nsIContentPolicy::ACCEPT;
    rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_XMLHTTPREQUEST,
                                   uri,
                                   principal,
                                   callingDoc ? callingDoc.get() :
                                     static_cast<nsIDocument*>(this),
                                   NS_LITERAL_CSTRING("application/xml"),
                                   nullptr,
                                   &shouldLoad,
                                   nsContentUtils::GetContentPolicy(),
                                   nsContentUtils::GetSecurityManager());
    NS_ENSURE_SUCCESS(rv, rv);
    if (NS_CP_REJECTED(shouldLoad)) {
      return NS_ERROR_CONTENT_BLOCKED;
    }
  } else {
    // We're called from chrome, check to make sure the URI we're
    // about to load is also chrome.

    bool isChrome = false;
    if (NS_FAILED(uri->SchemeIs("chrome", &isChrome)) || !isChrome) {
      nsAutoCString spec;
      if (mDocumentURI)
        mDocumentURI->GetSpec(spec);

      nsAutoString error;
      error.AssignLiteral("Cross site loading using document.load is no "
                          "longer supported. Use XMLHttpRequest instead.");
      nsCOMPtr<nsIScriptError> errorObject =
          do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
      NS_ENSURE_SUCCESS(rv, rv);

      rv = errorObject->InitWithWindowID(error,
                                         NS_ConvertUTF8toUTF16(spec),
                                         EmptyString(),
                                         0, 0, nsIScriptError::warningFlag,
                                         "DOM",
                                         callingDoc ?
                                           callingDoc->InnerWindowID() :
                                           this->InnerWindowID());

      NS_ENSURE_SUCCESS(rv, rv);

      nsCOMPtr<nsIConsoleService> consoleService =
        do_GetService(NS_CONSOLESERVICE_CONTRACTID);
      if (consoleService) {
        consoleService->LogMessage(errorObject);
      }

      return NS_ERROR_DOM_SECURITY_ERR;
    }
  }

  // Partial Reset, need to restore principal for security reasons and
  // event listener manager so that load listeners etc. will
  // remain. This should be done before the security check is done to
  // ensure that the document is reset even if the new document can't
  // be loaded.  Note that we need to hold a strong ref to |principal|
  // here, because ResetToURI will null out our node principal before
  // setting the new one.
  nsRefPtr<nsEventListenerManager> elm(mListenerManager);
  mListenerManager = nullptr;

  // When we are called from JS we can find the load group for the page,
  // and add ourselves to it. This way any pending requests
  // will be automatically aborted if the user leaves the page.

  nsCOMPtr<nsILoadGroup> loadGroup;
  if (callingDoc) {
    loadGroup = callingDoc->GetDocumentLoadGroup();
  }

  ResetToURI(uri, loadGroup, principal);

  mListenerManager = elm;

  // Create a channel
  nsCOMPtr<nsIInterfaceRequestor> req = nsContentUtils::GetSameOriginChecker();
  NS_ENSURE_TRUE(req, NS_ERROR_OUT_OF_MEMORY);  

  nsCOMPtr<nsIChannel> channel;
  // nsIRequest::LOAD_BACKGROUND prevents throbber from becoming active,
  // which in turn keeps STOP button from becoming active  
  rv = NS_NewChannel(getter_AddRefs(channel), uri, nullptr, loadGroup, req, 
                     nsIRequest::LOAD_BACKGROUND);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // StartDocumentLoad asserts that readyState is uninitialized, so
  // uninitialize it. SetReadyStateInternal make this transition invisible to
  // Web content. But before doing that, assert that the current readyState
  // is complete as it should be after the call to ResetToURI() above.
  MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE,
             "Bad readyState");
  SetReadyStateInternal(nsIDocument::READYSTATE_UNINITIALIZED);

  // Prepare for loading the XML document "into oneself"
  nsCOMPtr<nsIStreamListener> listener;
  if (NS_FAILED(rv = StartDocumentLoad(kLoadAsData, channel, 
                                       loadGroup, nullptr, 
                                       getter_AddRefs(listener),
                                       false))) {
    NS_ERROR("nsXMLDocument::Load: Failed to start the document load.");
    return rv;
  }

  // After this point, if we error out of this method we should clear
  // mChannelIsPending.

  // Start an asynchronous read of the XML document
  rv = channel->AsyncOpen(listener, nullptr);
  if (NS_FAILED(rv)) {
    mChannelIsPending = false;
    return rv;
  }

  if (!mAsync) {
    nsCOMPtr<nsIThread> thread = do_GetCurrentThread();

    nsAutoSyncOperation sync(this);
    mLoopingForSyncLoad = true;
    while (mLoopingForSyncLoad) {
      if (!NS_ProcessNextEvent(thread))
        break;
    }

    // We set return to true unless there was a parsing error
    nsCOMPtr<nsIDOMNode> node = do_QueryInterface(GetRootElement());
    if (node) {
      nsAutoString name, ns;      
      if (NS_SUCCEEDED(node->GetLocalName(name)) &&
          name.EqualsLiteral("parsererror") &&
          NS_SUCCEEDED(node->GetNamespaceURI(ns)) &&
          ns.EqualsLiteral("http://www.mozilla.org/newlayout/xml/parsererror.xml")) {
        //return is already false
      } else {
        *aReturn = true;
      }
    }
  } else {
    *aReturn = true;
  }

  return NS_OK;
}