Closed
Bug 82495
Opened 24 years ago
Closed 24 years ago
The view-source protocol handler is having troubles with security
Categories
(Core :: Security: CAPS, defect, P1)
Tracking
()
VERIFIED
FIXED
mozilla0.9.4
People
(Reporter: rbs, Assigned: security-bugs)
References
()
Details
(Whiteboard: patch)
Attachments
(1 file)
In:
===
NS_IMETHODIMP
nsScriptSecurityManager::CheckLoadURI()
the following assertion is firing when clicling on a view-source URL (see
example above):
===============
NS_WARN_IF_FALSE(PR_FALSE, "unknown protocol in
nsScriptSecurityManager::CheckLoadURI");
The full code of CheckLoadURI() is as follows:
==============================================
NS_IMETHODIMP
nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
PRUint32 aFlags)
{
nsCOMPtr<nsIJARURI> jarURI;
nsCOMPtr<nsIURI> sourceUri(aSourceURI);
while((jarURI = do_QueryInterface(sourceUri)))
jarURI->GetJARFile(getter_AddRefs(sourceUri));
if (!sourceUri) return NS_ERROR_FAILURE;
nsXPIDLCString sourceScheme;
if (NS_FAILED(sourceUri->GetScheme(getter_Copies(sourceScheme))))
return NS_ERROR_FAILURE;
// Some loads are not allowed from mail/news messages
if ((aFlags & nsIScriptSecurityManager::DISALLOW_FROM_MAIL) &&
(nsCRT::strcasecmp(sourceScheme, "mailbox") == 0 ||
nsCRT::strcasecmp(sourceScheme, "imap") == 0 ||
nsCRT::strcasecmp(sourceScheme, "news") == 0))
{
return NS_ERROR_DOM_BAD_URI;
}
nsCOMPtr<nsIURI> targetUri(aTargetURI);
while((jarURI = do_QueryInterface(targetUri)))
jarURI->GetJARFile(getter_AddRefs(targetUri));
if (!targetUri) return NS_ERROR_FAILURE;
nsXPIDLCString targetScheme;
if (NS_FAILED(targetUri->GetScheme(getter_Copies(targetScheme))))
return NS_ERROR_FAILURE;
if (nsCRT::strcasecmp(targetScheme, sourceScheme) == 0)
{
// every scheme can access another URI from the same scheme
return NS_OK;
}
enum Action { AllowProtocol, DenyProtocol, PrefControlled, ChromeProtocol,
AboutProtocol };
static const struct {
const char *name;
Action action;
} protocolList[] = {
//-- Keep the most commonly used protocols at the top of the list
// to increase performance
{ "http", AllowProtocol },
{ "file", PrefControlled },
{ "https", AllowProtocol },
{ "chrome", ChromeProtocol },
{ "mailbox", DenyProtocol },
{ "pop", AllowProtocol },
{ "imap", DenyProtocol },
{ "pop3", DenyProtocol },
{ "news", AllowProtocol },
{ "javascript", AllowProtocol },
{ "ftp", AllowProtocol },
{ "about", AboutProtocol },
{ "mailto", AllowProtocol },
{ "aim", AllowProtocol },
{ "data", AllowProtocol },
{ "keyword", DenyProtocol },
{ "resource", ChromeProtocol },
{ "gopher", AllowProtocol },
{ "datetime", DenyProtocol },
{ "finger", AllowProtocol },
{ "res", DenyProtocol }
};
nsXPIDLCString targetSpec;
const char* targetPage;
for (unsigned i=0; i < sizeof(protocolList)/sizeof(protocolList[0]); i++) {
if (nsCRT::strcasecmp(targetScheme, protocolList[i].name) == 0) {
PRBool doCheck = PR_FALSE;
switch (protocolList[i].action) {
case AllowProtocol:
// everyone can access these schemes.
return NS_OK;
case PrefControlled:
// Allow access if pref is false
mPrefs->GetBoolPref("security.checkloaduri", &doCheck);
return doCheck ? ReportErrorToConsole(aTargetURI) : NS_OK;
case ChromeProtocol:
if (aFlags & nsIScriptSecurityManager::ALLOW_CHROME)
return NS_OK;
// resource: and chrome: are equivalent, securitywise
if ((PL_strcmp(sourceScheme, "chrome") == 0) ||
(PL_strcmp(sourceScheme, "resource") == 0))
return NS_OK;
return ReportErrorToConsole(aTargetURI);
case AboutProtocol:
// Allow loading about:blank, otherwise deny
if(NS_FAILED(targetUri->GetSpec(getter_Copies(targetSpec))))
return NS_ERROR_FAILURE;
targetPage = targetSpec.get() + sizeof("about:") - 1;
return (PL_strcmp(targetPage, "blank") == 0) ||
(PL_strcmp(targetPage, "") == 0) ||
(PL_strcmp(targetPage, "mozilla") == 0) ||
(PL_strcmp(targetPage, "credits") == 0) ?
NS_OK : ReportErrorToConsole(aTargetURI);
case DenyProtocol:
// Deny access
return ReportErrorToConsole(aTargetURI);
}
}
}
// If we reach here, we have an unknown protocol. Warn, but allow.
// This is risky from a security standpoint, but allows flexibility
// in installing new protocol handlers after initial ship.
NS_WARN_IF_FALSE(PR_FALSE, "unknown protocol in
nsScriptSecurityManager::CheckLoadURI");
return NS_OK;
}
Assignee | ||
Comment 1•24 years ago
|
||
I will add view-source to the list of recognized protocols; thanks for catching
this. In the meantime, ignore the assertion; it does not indicate a lapse in
security.
Status: NEW → ASSIGNED
Target Milestone: --- → mozilla0.9.2
Also, what do you think of the checking order below? I have bumped the rank of
'chrome' and 'resource' because in the mainstream cases (i.e, non-developer
releases), most people will be browsing the web and reading e-mails and
particularly interacting with the UI (changing menus/prefs...). Moreover,
since main stream folks don't usually edit html files for themselves, I pushed
'file' further down the check list. There could be futher tweaks if the
checking order is that much important performance-wise (for example, 'https'
is rarely used compared to some of the other protocols).
{ "http", AllowProtocol },
{ "chrome", ChromeProtocol },
{ "resource", ChromeProtocol },
{ "https", AllowProtocol },
{ "mailbox", DenyProtocol },
{ "pop", AllowProtocol },
{ "imap", DenyProtocol },
{ "pop3", DenyProtocol },
{ "news", AllowProtocol },
{ "javascript", AllowProtocol },
{ "file", PrefControlled },
{ "ftp", AllowProtocol },
{ "about", AboutProtocol },
{ "mailto", AllowProtocol },
{ "aim", AllowProtocol },
{ "data", AllowProtocol },
{ "keyword", DenyProtocol },
{ "gopher", AllowProtocol },
{ "datetime", DenyProtocol },
{ "finger", AllowProtocol },
{ "res", DenyProtocol }
Assignee | ||
Comment 3•24 years ago
|
||
You're probably right about file:, but keep pop: and pop3: towards the bottom as
they're almost never used (possibly not at all, but they are in the source). The
real pop protocol is mailbox:.
Note to myself:
When this is fixed, check if special-casing view-source could be removed in:
NS_IMETHODIMP
CSSLoaderImpl::LoadStyleLink(...)
[...]
//-- Make sure this page is allowed to load this URL
// If we are doing view-source, no need to check...
PRBool isForViewSource = PR_FALSE;
if (aParserToUnblock) {
nsAutoString command;
aParserToUnblock->GetCommand(command);
isForViewSource = command.Equals(NS_LITERAL_STRING("view-source"));
}
if (!isForViewSource) {
nsresult rv;
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
nsIURI* docURI;
rv = mDocument->GetBaseURL(docURI);
if (NS_FAILED(rv) || !docURI) return NS_ERROR_FAILURE;
rv = secMan->CheckLoadURI(docURI, aURL,
nsIScriptSecurityManager::ALLOW_CHROME);
NS_IF_RELEASE(docURI);
if (NS_FAILED(rv)) return rv;
}
[...]
}
Assignee | ||
Updated•24 years ago
|
Priority: -- → P3
Target Milestone: mozilla0.9.2 → mozilla0.9.3
Assignee | ||
Comment 5•24 years ago
|
||
Assignee | ||
Updated•24 years ago
|
Whiteboard: patch
Comment 6•24 years ago
|
||
r=jesse
Assignee | ||
Comment 7•24 years ago
|
||
Target is now 0.9.4, Priority P1.
Priority: P3 → P1
Target Milestone: mozilla0.9.3 → mozilla0.9.4
Assignee | ||
Comment 8•24 years ago
|
||
Fix checked in.
Status: ASSIGNED → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•