Bug 1873474 - Use ImageBlocker directly instead of nsIContentPolicy::ShouldProcess in ImageDocument. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D198142
This commit is contained in:
Tom Schuster 2024-01-17 09:49:32 +00:00
Родитель 7c11f39184
Коммит 58300c5e90
5 изменённых файлов: 35 добавлений и 38 удалений

Просмотреть файл

@ -23,6 +23,7 @@
#include "nsGenericHTMLElement.h"
#include "nsDocShell.h"
#include "DocumentInlines.h"
#include "ImageBlocker.h"
#include "nsDOMTokenList.h"
#include "nsIDOMEventListener.h"
#include "nsIFrame.h"
@ -76,33 +77,13 @@ ImageListener::OnStartRequest(nsIRequest* request) {
nsCOMPtr<nsPIDOMWindowOuter> domWindow = imgDoc->GetWindow();
NS_ENSURE_TRUE(domWindow, NS_ERROR_UNEXPECTED);
// Do a ShouldProcess check to see whether to keep loading the image.
// This is an image being loaded as a document, so it's not going to be
// detected by the ImageBlocker. However we don't want to call
// NS_CheckContentLoadPolicy (with an TYPE_INTERNAL_IMAGE) here, as it would
// e.g. make this image load be detectable by CSP.
nsCOMPtr<nsIURI> channelURI;
channel->GetURI(getter_AddRefs(channelURI));
nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo();
// query the corresponding arguments for the channel loadinfo and pass
// it on to the temporary loadinfo used for content policy checks.
nsCOMPtr<nsINode> requestingNode = domWindow->GetFrameElementInternal();
nsCOMPtr<nsIPrincipal> loadingPrincipal;
if (requestingNode) {
loadingPrincipal = requestingNode->NodePrincipal();
} else {
nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
channel, getter_AddRefs(loadingPrincipal));
}
nsCOMPtr<nsILoadInfo> secCheckLoadInfo = new net::LoadInfo(
loadingPrincipal, loadInfo->TriggeringPrincipal(), requestingNode,
nsILoadInfo::SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK,
nsIContentPolicy::TYPE_INTERNAL_IMAGE);
int16_t decision = nsIContentPolicy::ACCEPT;
nsresult rv =
NS_CheckContentProcessPolicy(channelURI, secCheckLoadInfo, &decision,
nsContentUtils::GetContentPolicy());
if (NS_FAILED(rv) || NS_CP_REJECTED(decision)) {
if (image::ImageBlocker::ShouldBlock(channelURI)) {
request->Cancel(NS_ERROR_CONTENT_BLOCKED);
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE html>
<html>
<body>
<iframe height="100" width="100" style="border: none;" src="bug1196784.png"></iframe>
</body>
</html>

Просмотреть файл

@ -60,6 +60,9 @@ fuzzy(0-3,0-7544) fuzzy-if(!geckoview,2-3,50-7544) == bug917595-exif-rotated.jpg
# Test imageset is using permissions.default.image
pref(permissions.default.image,1) HTTP == bug1196784-with-srcset.html bug1196784-no-srcset.html
pref(permissions.default.image,2) HTTP == bug1196784-with-srcset.html bug1196784-no-srcset.html
# Test <iframe src=image>
pref(permissions.default.image,1) HTTP == iframe-with-image-src.html bug1196784-no-srcset.html
pref(permissions.default.image,2) HTTP == iframe-with-image-src.html about:blank
# Test video with rotation information can be rotated.
fails-if(geckoview&&!swgl) == bug1228601-video-rotation-90.html bug1228601-video-rotated-ref.html # bug 1558285 for geckoview

Просмотреть файл

@ -16,8 +16,6 @@ NS_IMPL_ISUPPORTS(ImageBlocker, nsIContentPolicy)
NS_IMETHODIMP
ImageBlocker::ShouldLoad(nsIURI* aContentLocation, nsILoadInfo* aLoadInfo,
int16_t* aShouldLoad) {
ExtContentPolicyType contentType = aLoadInfo->GetExternalContentPolicyType();
*aShouldLoad = nsIContentPolicy::ACCEPT;
if (!aContentLocation) {
@ -27,20 +25,13 @@ ImageBlocker::ShouldLoad(nsIURI* aContentLocation, nsILoadInfo* aLoadInfo,
return NS_OK;
}
// we only want to check http, https
// for chrome:// and resources and others, no need to check.
nsAutoCString scheme;
aContentLocation->GetScheme(scheme);
if (!scheme.LowerCaseEqualsLiteral("http") &&
!scheme.LowerCaseEqualsLiteral("https")) {
ExtContentPolicyType contentType = aLoadInfo->GetExternalContentPolicyType();
if (contentType != ExtContentPolicy::TYPE_IMAGE &&
contentType != ExtContentPolicy::TYPE_IMAGESET) {
return NS_OK;
}
// Block loading images depending on the permissions.default.image pref.
if ((contentType == ExtContentPolicy::TYPE_IMAGE ||
contentType == ExtContentPolicy::TYPE_IMAGESET) &&
StaticPrefs::permissions_default_image() ==
nsIPermissionManager::DENY_ACTION) {
if (ImageBlocker::ShouldBlock(aContentLocation)) {
NS_SetRequestBlockingReason(
aLoadInfo, nsILoadInfo::BLOCKING_REASON_CONTENT_POLICY_CONTENT_BLOCKED);
*aShouldLoad = nsIContentPolicy::REJECT_TYPE;
@ -56,3 +47,17 @@ ImageBlocker::ShouldProcess(nsIURI* aContentLocation, nsILoadInfo* aLoadInfo,
*aShouldProcess = nsIContentPolicy::ACCEPT;
return NS_OK;
}
/* static */
bool ImageBlocker::ShouldBlock(nsIURI* aContentLocation) {
// Block loading images depending on the permissions.default.image pref.
if (StaticPrefs::permissions_default_image() !=
nsIPermissionManager::DENY_ACTION) {
return false;
}
// we only want to check http, https
// for chrome:// and resources and others, no need to check.
return aContentLocation->SchemeIs("http") ||
aContentLocation->SchemeIs("https");
}

Просмотреть файл

@ -25,6 +25,8 @@ class ImageBlocker final : public nsIContentPolicy {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICONTENTPOLICY
static bool ShouldBlock(nsIURI* aContentLocation);
};
} // namespace image