зеркало из https://github.com/mozilla/gecko-dev.git
Bug 515460 - enforce CSP during image redirects, r=joe
This commit is contained in:
Родитель
6f2c9d9235
Коммит
576c1b9813
|
@ -198,6 +198,9 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
|
||||||
#include "jstypedarray.h"
|
#include "jstypedarray.h"
|
||||||
#include "xpcprivate.h"
|
#include "xpcprivate.h"
|
||||||
#include "nsScriptSecurityManager.h"
|
#include "nsScriptSecurityManager.h"
|
||||||
|
#include "nsIChannelPolicy.h"
|
||||||
|
#include "nsChannelPolicy.h"
|
||||||
|
#include "nsIContentSecurityPolicy.h"
|
||||||
|
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
|
@ -2327,12 +2330,23 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
||||||
|
|
||||||
nsIURI *documentURI = aLoadingDocument->GetDocumentURI();
|
nsIURI *documentURI = aLoadingDocument->GetDocumentURI();
|
||||||
|
|
||||||
|
// check for a Content Security Policy to pass down to the channel that
|
||||||
|
// will get created to load the image
|
||||||
|
nsCOMPtr<nsIChannelPolicy> channelPolicy;
|
||||||
|
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||||
|
if (aLoadingPrincipal) {
|
||||||
|
nsresult rv = aLoadingPrincipal->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_IMAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Make the URI immutable so people won't change it under us
|
// Make the URI immutable so people won't change it under us
|
||||||
NS_TryToSetImmutable(aURI);
|
NS_TryToSetImmutable(aURI);
|
||||||
|
|
||||||
// We don't use aLoadingPrincipal for anything here yet... but we
|
|
||||||
// will. See bug 377092.
|
|
||||||
|
|
||||||
// XXXbz using "documentURI" for the initialDocumentURI is not quite
|
// XXXbz using "documentURI" for the initialDocumentURI is not quite
|
||||||
// right, but the best we can do here...
|
// right, but the best we can do here...
|
||||||
return sImgLoader->LoadImage(aURI, /* uri to load */
|
return sImgLoader->LoadImage(aURI, /* uri to load */
|
||||||
|
@ -2344,6 +2358,7 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
||||||
aLoadFlags, /* load flags */
|
aLoadFlags, /* load flags */
|
||||||
nsnull, /* cache key */
|
nsnull, /* cache key */
|
||||||
nsnull, /* existing request*/
|
nsnull, /* existing request*/
|
||||||
|
channelPolicy, /* CSP info */
|
||||||
aRequest);
|
aRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ var page = "/tests/content/base/test/file_csp_redirects_page.sjs";
|
||||||
|
|
||||||
var tests = { "font-src": thisSite+page+"?testid=font-src&csp=1",
|
var tests = { "font-src": thisSite+page+"?testid=font-src&csp=1",
|
||||||
"frame-src": thisSite+page+"?testid=frame-src&csp=1",
|
"frame-src": thisSite+page+"?testid=frame-src&csp=1",
|
||||||
// "img-src": thisSite+page+"?testid=img-src&csp=1",
|
"img-src": thisSite+page+"?testid=img-src&csp=1",
|
||||||
"media-src": thisSite+page+"?testid=media-src&csp=1",
|
"media-src": thisSite+page+"?testid=media-src&csp=1",
|
||||||
"object-src": thisSite+page+"?testid=object-src&csp=1",
|
"object-src": thisSite+page+"?testid=object-src&csp=1",
|
||||||
"script-src": thisSite+page+"?testid=script-src&csp=1",
|
"script-src": thisSite+page+"?testid=script-src&csp=1",
|
||||||
|
|
|
@ -83,8 +83,8 @@ var testExpectedResults = { "font-src": true,
|
||||||
"font-src-redir": false,
|
"font-src-redir": false,
|
||||||
"frame-src": true,
|
"frame-src": true,
|
||||||
"frame-src-redir": false,
|
"frame-src-redir": false,
|
||||||
// "img-src": true,
|
"img-src": true,
|
||||||
// "img-src-redir": false,
|
"img-src-redir": false,
|
||||||
"media-src": true,
|
"media-src": true,
|
||||||
"media-src-redir": false,
|
"media-src-redir": false,
|
||||||
"object-src": true,
|
"object-src": true,
|
||||||
|
|
|
@ -59,6 +59,11 @@
|
||||||
#include "nsIDOMCSSPrimitiveValue.h"
|
#include "nsIDOMCSSPrimitiveValue.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsUnicharUtils.h"
|
#include "nsUnicharUtils.h"
|
||||||
|
#include "nsIDocument.h"
|
||||||
|
#include "nsIPrincipal.h"
|
||||||
|
#include "nsIChannelPolicy.h"
|
||||||
|
#include "nsIContentSecurityPolicy.h"
|
||||||
|
#include "nsIContentPolicy.h"
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// class nsContextMenuInfo
|
// class nsContextMenuInfo
|
||||||
|
@ -299,6 +304,22 @@ nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode *aDOMNode, imgIR
|
||||||
nsCOMPtr<nsIDOMCSSPrimitiveValue> primitiveValue;
|
nsCOMPtr<nsIDOMCSSPrimitiveValue> primitiveValue;
|
||||||
nsAutoString bgStringValue;
|
nsAutoString bgStringValue;
|
||||||
|
|
||||||
|
// get Content Security Policy to pass to LoadImage
|
||||||
|
nsCOMPtr<nsIDocument> doc(do_QueryInterface(document));
|
||||||
|
nsCOMPtr<nsIPrincipal> principal;
|
||||||
|
nsCOMPtr<nsIChannelPolicy> channelPolicy;
|
||||||
|
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||||
|
if (doc) {
|
||||||
|
principal = doc->NodePrincipal();
|
||||||
|
nsresult rv = principal->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_IMAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (PR_TRUE) {
|
while (PR_TRUE) {
|
||||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(domNode));
|
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(domNode));
|
||||||
// bail for the parent node of the root element or null argument
|
// bail for the parent node of the root element or null argument
|
||||||
|
@ -326,7 +347,7 @@ nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode *aDOMNode, imgIR
|
||||||
|
|
||||||
return il->LoadImage(bgUri, nsnull, nsnull, nsnull, nsnull, nsnull,
|
return il->LoadImage(bgUri, nsnull, nsnull, nsnull, nsnull, nsnull,
|
||||||
nsIRequest::LOAD_NORMAL, nsnull, nsnull,
|
nsIRequest::LOAD_NORMAL, nsnull, nsnull,
|
||||||
aRequest);
|
channelPolicy, aRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1671,6 +1671,7 @@ nsImageFrame::LoadIcon(const nsAString& aSpec,
|
||||||
loadFlags,
|
loadFlags,
|
||||||
nsnull,
|
nsnull,
|
||||||
nsnull,
|
nsnull,
|
||||||
|
nsnull, /* channel policy not needed */
|
||||||
aRequest);
|
aRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ interface nsIStreamListener;
|
||||||
interface nsIURI;
|
interface nsIURI;
|
||||||
|
|
||||||
interface nsISimpleEnumerator;
|
interface nsISimpleEnumerator;
|
||||||
|
interface nsIChannelPolicy;
|
||||||
|
|
||||||
#include "nsIRequest.idl" // for nsLoadFlags
|
#include "nsIRequest.idl" // for nsLoadFlags
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ interface nsISimpleEnumerator;
|
||||||
* @version 0.3
|
* @version 0.3
|
||||||
* @see imagelib2
|
* @see imagelib2
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(d2f50c69-1064-4ce3-a92d-01dc5f5b4842)]
|
[scriptable, uuid(7b776f98-3faf-40f9-b352-3283a884cb98)]
|
||||||
interface imgILoader : nsISupports
|
interface imgILoader : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -89,7 +90,8 @@ interface imgILoader : nsISupports
|
||||||
in nsISupports aCX,
|
in nsISupports aCX,
|
||||||
in nsLoadFlags aLoadFlags,
|
in nsLoadFlags aLoadFlags,
|
||||||
in nsISupports cacheKey,
|
in nsISupports cacheKey,
|
||||||
in imgIRequest aRequest);
|
in imgIRequest aRequest,
|
||||||
|
in nsIChannelPolicy channelPolicy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the load and decode of an image.
|
* Start the load and decode of an image.
|
||||||
|
|
|
@ -74,6 +74,8 @@
|
||||||
// so we can associate the document URI with the load group.
|
// so we can associate the document URI with the load group.
|
||||||
// until this point, we have an evil hack:
|
// until this point, we have an evil hack:
|
||||||
#include "nsIHttpChannelInternal.h"
|
#include "nsIHttpChannelInternal.h"
|
||||||
|
#include "nsIContentSecurityPolicy.h"
|
||||||
|
#include "nsIChannelPolicy.h"
|
||||||
|
|
||||||
#include "mozilla/FunctionTimer.h"
|
#include "mozilla/FunctionTimer.h"
|
||||||
|
|
||||||
|
@ -293,7 +295,8 @@ static nsresult NewImageChannel(nsIChannel **aResult,
|
||||||
nsIURI *aReferringURI,
|
nsIURI *aReferringURI,
|
||||||
nsILoadGroup *aLoadGroup,
|
nsILoadGroup *aLoadGroup,
|
||||||
const nsCString& aAcceptHeader,
|
const nsCString& aAcceptHeader,
|
||||||
nsLoadFlags aLoadFlags)
|
nsLoadFlags aLoadFlags,
|
||||||
|
nsIChannelPolicy *aPolicy)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsIChannel> newChannel;
|
nsCOMPtr<nsIChannel> newChannel;
|
||||||
|
@ -323,7 +326,8 @@ static nsresult NewImageChannel(nsIChannel **aResult,
|
||||||
nsnull, // Cached IOService
|
nsnull, // Cached IOService
|
||||||
nsnull, // LoadGroup
|
nsnull, // LoadGroup
|
||||||
callbacks, // Notification Callbacks
|
callbacks, // Notification Callbacks
|
||||||
aLoadFlags);
|
aLoadFlags,
|
||||||
|
aPolicy);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
|
@ -984,7 +988,8 @@ PRBool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
|
||||||
nsISupports *aCX,
|
nsISupports *aCX,
|
||||||
nsLoadFlags aLoadFlags,
|
nsLoadFlags aLoadFlags,
|
||||||
imgIRequest *aExistingRequest,
|
imgIRequest *aExistingRequest,
|
||||||
imgIRequest **aProxyRequest)
|
imgIRequest **aProxyRequest,
|
||||||
|
nsIChannelPolicy *aPolicy)
|
||||||
{
|
{
|
||||||
// now we need to insert a new channel request object inbetween the real
|
// now we need to insert a new channel request object inbetween the real
|
||||||
// request and the proxy that basically delays loading the image until it
|
// request and the proxy that basically delays loading the image until it
|
||||||
|
@ -1012,7 +1017,8 @@ PRBool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
|
||||||
aReferrerURI,
|
aReferrerURI,
|
||||||
aLoadGroup,
|
aLoadGroup,
|
||||||
mAcceptHeader,
|
mAcceptHeader,
|
||||||
aLoadFlags);
|
aLoadFlags,
|
||||||
|
aPolicy);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1072,7 +1078,8 @@ PRBool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
|
||||||
nsLoadFlags aLoadFlags,
|
nsLoadFlags aLoadFlags,
|
||||||
PRBool aCanMakeNewChannel,
|
PRBool aCanMakeNewChannel,
|
||||||
imgIRequest *aExistingRequest,
|
imgIRequest *aExistingRequest,
|
||||||
imgIRequest **aProxyRequest)
|
imgIRequest **aProxyRequest,
|
||||||
|
nsIChannelPolicy *aPolicy = nsnull)
|
||||||
{
|
{
|
||||||
LOG_SCOPE(gImgLog, "imgLoader::ValidateEntry");
|
LOG_SCOPE(gImgLog, "imgLoader::ValidateEntry");
|
||||||
|
|
||||||
|
@ -1186,7 +1193,7 @@ PRBool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
|
||||||
return ValidateRequestWithNewChannel(request, aURI, aInitialDocumentURI,
|
return ValidateRequestWithNewChannel(request, aURI, aInitialDocumentURI,
|
||||||
aReferrerURI, aLoadGroup, aObserver,
|
aReferrerURI, aLoadGroup, aObserver,
|
||||||
aCX, aLoadFlags, aExistingRequest,
|
aCX, aLoadFlags, aExistingRequest,
|
||||||
aProxyRequest);
|
aProxyRequest, aPolicy);
|
||||||
}
|
}
|
||||||
|
|
||||||
return !validateRequest;
|
return !validateRequest;
|
||||||
|
@ -1327,6 +1334,7 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
|
||||||
nsLoadFlags aLoadFlags,
|
nsLoadFlags aLoadFlags,
|
||||||
nsISupports *aCacheKey,
|
nsISupports *aCacheKey,
|
||||||
imgIRequest *aRequest,
|
imgIRequest *aRequest,
|
||||||
|
nsIChannelPolicy *aPolicy,
|
||||||
imgIRequest **_retval)
|
imgIRequest **_retval)
|
||||||
{
|
{
|
||||||
VerifyCacheSizes();
|
VerifyCacheSizes();
|
||||||
|
@ -1382,8 +1390,9 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
|
||||||
imgCacheTable &cache = GetCache(aURI);
|
imgCacheTable &cache = GetCache(aURI);
|
||||||
|
|
||||||
if (cache.Get(spec, getter_AddRefs(entry)) && entry) {
|
if (cache.Get(spec, getter_AddRefs(entry)) && entry) {
|
||||||
if (ValidateEntry(entry, aURI, aInitialDocumentURI, aReferrerURI, aLoadGroup, aObserver, aCX,
|
if (ValidateEntry(entry, aURI, aInitialDocumentURI, aReferrerURI,
|
||||||
requestFlags, PR_TRUE, aRequest, _retval)) {
|
aLoadGroup, aObserver, aCX, requestFlags, PR_TRUE,
|
||||||
|
aRequest, _retval, aPolicy)) {
|
||||||
request = getter_AddRefs(entry->GetRequest());
|
request = getter_AddRefs(entry->GetRequest());
|
||||||
|
|
||||||
// If this entry has no proxies, its request has no reference to the entry.
|
// If this entry has no proxies, its request has no reference to the entry.
|
||||||
|
@ -1422,7 +1431,8 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
|
||||||
aReferrerURI,
|
aReferrerURI,
|
||||||
aLoadGroup,
|
aLoadGroup,
|
||||||
mAcceptHeader,
|
mAcceptHeader,
|
||||||
requestFlags);
|
requestFlags,
|
||||||
|
aPolicy);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "prtypes.h"
|
#include "prtypes.h"
|
||||||
#include "imgRequest.h"
|
#include "imgRequest.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
|
#include "nsIChannelPolicy.h"
|
||||||
|
|
||||||
#ifdef LOADER_THREADSAFE
|
#ifdef LOADER_THREADSAFE
|
||||||
#include "prlock.h"
|
#include "prlock.h"
|
||||||
|
@ -300,7 +301,8 @@ private: // methods
|
||||||
imgIDecoderObserver *aObserver, nsISupports *aCX,
|
imgIDecoderObserver *aObserver, nsISupports *aCX,
|
||||||
nsLoadFlags aLoadFlags, PRBool aCanMakeNewChannel,
|
nsLoadFlags aLoadFlags, PRBool aCanMakeNewChannel,
|
||||||
imgIRequest *aExistingRequest,
|
imgIRequest *aExistingRequest,
|
||||||
imgIRequest **aProxyRequest);
|
imgIRequest **aProxyRequest,
|
||||||
|
nsIChannelPolicy *aPolicy);
|
||||||
PRBool ValidateRequestWithNewChannel(imgRequest *request, nsIURI *aURI,
|
PRBool ValidateRequestWithNewChannel(imgRequest *request, nsIURI *aURI,
|
||||||
nsIURI *aInitialDocumentURI,
|
nsIURI *aInitialDocumentURI,
|
||||||
nsIURI *aReferrerURI,
|
nsIURI *aReferrerURI,
|
||||||
|
@ -308,7 +310,8 @@ private: // methods
|
||||||
imgIDecoderObserver *aObserver,
|
imgIDecoderObserver *aObserver,
|
||||||
nsISupports *aCX, nsLoadFlags aLoadFlags,
|
nsISupports *aCX, nsLoadFlags aLoadFlags,
|
||||||
imgIRequest *aExistingRequest,
|
imgIRequest *aExistingRequest,
|
||||||
imgIRequest **aProxyRequest);
|
imgIRequest **aProxyRequest,
|
||||||
|
nsIChannelPolicy *aPolicy);
|
||||||
|
|
||||||
nsresult CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup *aLoadGroup,
|
nsresult CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup *aLoadGroup,
|
||||||
imgIDecoderObserver *aObserver,
|
imgIDecoderObserver *aObserver,
|
||||||
|
|
|
@ -266,7 +266,7 @@ nsAlertsIconListener::StartRequest(const nsAString & aImageUrl)
|
||||||
|
|
||||||
return il->LoadImage(imageUri, nsnull, nsnull, nsnull, this,
|
return il->LoadImage(imageUri, nsnull, nsnull, nsnull, this,
|
||||||
nsnull, nsIRequest::LOAD_NORMAL, nsnull, nsnull,
|
nsnull, nsIRequest::LOAD_NORMAL, nsnull, nsnull,
|
||||||
getter_AddRefs(mIconRequest));
|
nsnull, getter_AddRefs(mIconRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -337,8 +337,10 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconURI)
|
||||||
[mNativeMenuItem setImage:sPlaceholderIconImage];
|
[mNativeMenuItem setImage:sPlaceholderIconImage];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Passing in null for channelPolicy here since nsMenuItemIconX::LoadIcon is
|
||||||
|
// not exposed to web content
|
||||||
rv = loader->LoadImage(aIconURI, nsnull, nsnull, loadGroup, this,
|
rv = loader->LoadImage(aIconURI, nsnull, nsnull, loadGroup, this,
|
||||||
nsnull, nsIRequest::LOAD_NORMAL, nsnull,
|
nsnull, nsIRequest::LOAD_NORMAL, nsnull, nsnull,
|
||||||
nsnull, getter_AddRefs(mIconRequest));
|
nsnull, getter_AddRefs(mIconRequest));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче