From a96ed5e3575d74ee11cf256879d474dc7fa53fc2 Mon Sep 17 00:00:00 2001 From: "nick.kreeger%park.edu" Date: Wed, 25 Apr 2007 18:34:55 +0000 Subject: [PATCH] Fixing bug 367055, Cmd-Click and 'Open Link in New foo' should not open file URLS from non-local pages. Use URI checking. Landing trunk version, Camino only. r=smorgan, sr=pink. git-svn-id: svn://10.0.0.236/trunk@225024 18797224-902f-48f8-a5cc-f745e15eee43 --- .../src/browser/BrowserWindowController.mm | 21 +++++++++++++++++++ .../src/browser/ContentClickListener.mm | 3 +++ mozilla/camino/src/extensions/GeckoUtils.cpp | 21 +++++++++++++++++++ mozilla/camino/src/extensions/GeckoUtils.h | 5 +++++ 4 files changed, 50 insertions(+) diff --git a/mozilla/camino/src/browser/BrowserWindowController.mm b/mozilla/camino/src/browser/BrowserWindowController.mm index 038150860b2..3a65ca990a9 100644 --- a/mozilla/camino/src/browser/BrowserWindowController.mm +++ b/mozilla/camino/src/browser/BrowserWindowController.mm @@ -4027,6 +4027,7 @@ enum BWCOpenDest { BOOL showFrameItems = NO; BOOL showSpellingItems = NO; BOOL needsAlternates = NO; + BOOL isUnsafeLink = NO; NSArray* emailAddresses = nil; unsigned numEmailAddresses = 0; @@ -4066,6 +4067,16 @@ enum BWCOpenDest { if (emailAddresses != nil) numEmailAddresses = [emailAddresses count]; + // Verify that it is safe to open this link. + NSString* referrerURL = [[mBrowserView getBrowserView] getFocusedURLString]; + nsCOMPtr linkElement; + nsAutoString hrefURL; + GeckoUtils::GetEnclosingLinkElementAndHref(mDataOwner->mContextMenuNode, + getter_AddRefs(linkElement), + hrefURL); + if (!GeckoUtils::IsSafeToOpenURIFromReferrer(NS_ConvertUTF16toUTF8(hrefURL).get(), [referrerURL UTF8String])) + isUnsafeLink = YES; + if ((contextMenuFlags & nsIContextMenuListener::CONTEXT_IMAGE) != 0) { if (numEmailAddresses > 0) menuPrototype = mImageMailToLinkMenu; @@ -4136,6 +4147,16 @@ enum BWCOpenDest { // our only copy of the menu NSMenu* result = [[menuPrototype copy] autorelease]; + if (isUnsafeLink) { + // To avoid updating the BrowserWindow.nib close to release time, the + // menu items to remove will be removed from index 0 three times. After + // the 1.1 release, this needs to be changed (see bug 378081). The first + // two remove calls will pull out the "Open Link in *" menu items. + [result removeItemAtIndex:0]; + [result removeItemAtIndex:0]; + [result removeItemAtIndex:0]; // remove separator + } + // validate View Page/Frame Source BrowserWrapper* browser = [self getBrowserWrapper]; if ([browser isInternalURI] || ![[browser getBrowserView] isTextBasedContent]) { diff --git a/mozilla/camino/src/browser/ContentClickListener.mm b/mozilla/camino/src/browser/ContentClickListener.mm index cc63ad97b88..2193afeb84b 100644 --- a/mozilla/camino/src/browser/ContentClickListener.mm +++ b/mozilla/camino/src/browser/ContentClickListener.mm @@ -107,6 +107,9 @@ ContentClickListener::MouseClick(nsIDOMEvent* aEvent) else hrefScheme = @"file"; // implicitly file:// if no colon is found + if (!GeckoUtils::IsSafeToOpenURIFromReferrer([hrefStr UTF8String], [referrer UTF8String])) + return NS_OK; + // The Command key is down or we got a middle-click. // Open the link in a new window or tab if it's an internally handled, non-Javascript link. if (![hrefScheme isEqualToString:@"javascript"] && GeckoUtils::isProtocolInternal([hrefScheme UTF8String])) { diff --git a/mozilla/camino/src/extensions/GeckoUtils.cpp b/mozilla/camino/src/extensions/GeckoUtils.cpp index d5ac7021304..84778517c0f 100644 --- a/mozilla/camino/src/extensions/GeckoUtils.cpp +++ b/mozilla/camino/src/extensions/GeckoUtils.cpp @@ -55,6 +55,8 @@ #include "nsIProtocolHandler.h" #include "nsIServiceManager.h" #include "nsIExternalProtocolHandler.h" +#include "nsIScriptSecurityManager.h" +#include "nsNetUtil.h" #include "nsIEditor.h" #include "nsISelection.h" @@ -226,6 +228,25 @@ void GeckoUtils::GetURIForDocShell(nsIDocShell* aDocShell, nsACString& aURI) uri->GetSpec(aURI); } +/* static */ +PRBool +GeckoUtils::IsSafeToOpenURIFromReferrer(const char* aTargetUri, const char* aReferrerUri) +{ + PRBool isUnsafeLink = PR_TRUE; + nsCOMPtr referrerUri; + nsCOMPtr targetUri; + NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri); + NS_NewURI(getter_AddRefs(targetUri), aTargetUri); + + nsCOMPtr secManager = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID); + if (secManager&& referrerUri && targetUri) { + nsresult rv = secManager->CheckLoadURI(referrerUri, targetUri, 0); + isUnsafeLink = NS_SUCCEEDED(rv); + } + + return isUnsafeLink; +} + // NOTE: this addrefs the result! /* static */ void GeckoUtils::FindDocShellForURI (nsIURI *aURI, nsIDocShell *aRoot, nsIDocShell **outMatch) diff --git a/mozilla/camino/src/extensions/GeckoUtils.h b/mozilla/camino/src/extensions/GeckoUtils.h index 16d6ef3772d..333bbbd8c3a 100644 --- a/mozilla/camino/src/extensions/GeckoUtils.h +++ b/mozilla/camino/src/extensions/GeckoUtils.h @@ -64,6 +64,11 @@ class GeckoUtils /* Ouputs the docshell |aDocShell|'s URI as a nsACString. */ static void GetURIForDocShell(nsIDocShell* aDocShell, nsACString& aURI); + + // Find out if a URI is safe to load given the referrer URI. + // An unsafe URI could be a 'file://' or 'chrome://' from a referrer of a different URI scheme. + // For more info, see http://developer.mozilla.org/en/docs/Safely_loading_URIs + static PRBool IsSafeToOpenURIFromReferrer(const char* aTargetUri, const char* aReferrerUri); // Finds the anchor node for the selection in the given editor static void GetAnchorNodeFromSelection(nsIEditor* inEditor, nsIDOMNode** outAnchorNode, PRInt32* outAnchorOffset);