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
This commit is contained in:
nick.kreeger%park.edu 2007-04-25 18:34:55 +00:00
parent 03af169f9c
commit a96ed5e357
4 changed files with 50 additions and 0 deletions

View File

@ -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<nsIDOMElement> 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]) {

View File

@ -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])) {

View File

@ -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<nsIURI> referrerUri;
nsCOMPtr<nsIURI> targetUri;
NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri);
NS_NewURI(getter_AddRefs(targetUri), aTargetUri);
nsCOMPtr<nsIScriptSecurityManager> 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)

View File

@ -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);