mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1172165 - check all nested URI schemes in CAPS. Make view-source dangerous to load, and about: URIs use per-URI flags so they keep working, r=bz
Also, add an opt-out for crashtest/reftest for the view-source thing so they don't all break, r=bz --HG-- extra : commitid : 8NqvmbphSgh extra : rebase_source : bbe0b6f11a77d7e6241a5733931d9baa95bb3fed
This commit is contained in:
parent
1839ec6c66
commit
ef04fd0f90
@ -629,6 +629,42 @@ EqualOrSubdomain(nsIURI* aProbeArg, nsIURI* aBase)
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
AllSchemesMatch(nsIURI* aURI, nsIURI* aOtherURI)
|
||||
{
|
||||
nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(aURI);
|
||||
nsCOMPtr<nsINestedURI> nestedOtherURI = do_QueryInterface(aOtherURI);
|
||||
auto stringComparator = nsCaseInsensitiveCStringComparator();
|
||||
if (!nestedURI && !nestedOtherURI) {
|
||||
// Neither of the URIs is nested, compare their schemes directly:
|
||||
nsAutoCString scheme, otherScheme;
|
||||
aURI->GetScheme(scheme);
|
||||
aOtherURI->GetScheme(otherScheme);
|
||||
return scheme.Equals(otherScheme, stringComparator);
|
||||
}
|
||||
while (nestedURI && nestedOtherURI) {
|
||||
nsCOMPtr<nsIURI> currentURI = do_QueryInterface(nestedURI);
|
||||
nsCOMPtr<nsIURI> currentOtherURI = do_QueryInterface(nestedOtherURI);
|
||||
nsAutoCString scheme, otherScheme;
|
||||
currentURI->GetScheme(scheme);
|
||||
currentOtherURI->GetScheme(otherScheme);
|
||||
if (!scheme.Equals(otherScheme, stringComparator)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nestedURI->GetInnerURI(getter_AddRefs(currentURI));
|
||||
nestedOtherURI->GetInnerURI(getter_AddRefs(currentOtherURI));
|
||||
nestedURI = do_QueryInterface(currentURI);
|
||||
nestedOtherURI = do_QueryInterface(currentOtherURI);
|
||||
}
|
||||
if (!!nestedURI != !!nestedOtherURI) {
|
||||
// If only one of the scheme chains runs out at one point, clearly the chains
|
||||
// aren't of the same length, so we bail:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
nsIURI *aTargetURI,
|
||||
@ -729,14 +765,30 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
rv = sourceBaseURI->GetScheme(sourceScheme);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// When comparing schemes, if the relevant pref is set, view-source URIs
|
||||
// are reachable from same-protocol (so e.g. file: can link to
|
||||
// view-source:file). This is required for reftests.
|
||||
static bool sViewSourceReachableFromInner = false;
|
||||
static bool sCachedViewSourcePref = false;
|
||||
if (!sCachedViewSourcePref) {
|
||||
sCachedViewSourcePref = true;
|
||||
mozilla::Preferences::AddBoolVarCache(&sViewSourceReachableFromInner,
|
||||
"security.view-source.reachable-from-inner-protocol");
|
||||
}
|
||||
|
||||
bool targetIsViewSource = false;
|
||||
|
||||
if (sourceScheme.LowerCaseEqualsLiteral(NS_NULLPRINCIPAL_SCHEME)) {
|
||||
// A null principal can target its own URI.
|
||||
if (sourceURI == aTargetURI) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
else if (targetScheme.Equals(sourceScheme,
|
||||
nsCaseInsensitiveCStringComparator()))
|
||||
else if (AllSchemesMatch(sourceURI, aTargetURI) ||
|
||||
(sViewSourceReachableFromInner &&
|
||||
sourceScheme.EqualsIgnoreCase(targetScheme.get()) &&
|
||||
NS_SUCCEEDED(aTargetURI->SchemeIs("view-source", &targetIsViewSource)) &&
|
||||
targetIsViewSource))
|
||||
{
|
||||
// every scheme can access another URI from the same scheme,
|
||||
// as long as they don't represent null principals...
|
||||
@ -785,7 +837,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
// at the flags for our one URI.
|
||||
|
||||
// Check for system target URI
|
||||
rv = DenyAccessIfURIHasFlags(targetBaseURI,
|
||||
rv = DenyAccessIfURIHasFlags(aTargetURI,
|
||||
nsIProtocolHandler::URI_DANGEROUS_TO_LOAD);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Deny access, since the origin principal is not system
|
||||
@ -853,7 +905,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
}
|
||||
|
||||
// Check for target URI pointing to a file
|
||||
rv = NS_URIChainHasFlags(targetBaseURI,
|
||||
rv = NS_URIChainHasFlags(aTargetURI,
|
||||
nsIProtocolHandler::URI_IS_LOCAL_FILE,
|
||||
&hasFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -1639,3 +1691,4 @@ nsScriptSecurityManager::PolicyAllowsScript(nsIURI* aURI, bool *aRv)
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -64,3 +64,7 @@
|
||||
|
||||
// Allow XUL and XBL files to be opened from file:// URIs
|
||||
branch.setBoolPref("dom.allow_XUL_XBL_for_file", true);
|
||||
|
||||
// Allow view-source URIs to be opened from URIs that share
|
||||
// their protocol with the inner URI of the view-source URI
|
||||
branch.setBoolPref("security.view-source.reachable-from-inner-protocol", true);
|
||||
|
@ -2025,6 +2025,10 @@ pref("security.cert_pinning.enforcement_level", 0);
|
||||
// for tests.
|
||||
pref("security.cert_pinning.process_headers_from_non_builtin_roots", false);
|
||||
|
||||
// If set to true, allow view-source URIs to be opened from URIs that share
|
||||
// their protocol with the inner URI of the view-source URI
|
||||
pref("security.view-source.reachable-from-inner-protocol", false);
|
||||
|
||||
// Modifier key prefs: default to Windows settings,
|
||||
// menu access key = alt, accelerator key = control.
|
||||
// Use 17 for Ctrl, 18 for Alt, 224 for Meta, 91 for Win, 0 for none. Mac settings in macprefs.js
|
||||
|
@ -39,7 +39,8 @@ static bool IsSafeToLinkForUntrustedContent(nsIAboutModule *aModule, nsIURI *aUR
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAboutProtocolHandler, nsIProtocolHandler, nsISupportsWeakReference)
|
||||
NS_IMPL_ISUPPORTS(nsAboutProtocolHandler, nsIProtocolHandler,
|
||||
nsIProtocolHandlerWithDynamicFlags, nsISupportsWeakReference)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIProtocolHandler methods:
|
||||
@ -65,6 +66,33 @@ nsAboutProtocolHandler::GetProtocolFlags(uint32_t *result)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAboutProtocolHandler::GetFlagsForURI(nsIURI* aURI, uint32_t* aFlags)
|
||||
{
|
||||
// First use the default (which is "unsafe for content"):
|
||||
GetProtocolFlags(aFlags);
|
||||
|
||||
// Now try to see if this URI overrides the default:
|
||||
nsCOMPtr<nsIAboutModule> aboutMod;
|
||||
nsresult rv = NS_GetAboutModule(aURI, getter_AddRefs(aboutMod));
|
||||
if (NS_FAILED(rv)) {
|
||||
// Swallow this and just tell the consumer the default:
|
||||
return NS_OK;
|
||||
}
|
||||
uint32_t aboutModuleFlags = 0;
|
||||
rv = aboutMod->GetURIFlags(aURI, &aboutModuleFlags);
|
||||
// This should never happen, so pass back the error:
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If marked as safe, and not marked unlinkable, pass 'safe' flags.
|
||||
if ((aboutModuleFlags & nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT) &&
|
||||
!(aboutModuleFlags & nsIAboutModule::MAKE_UNLINKABLE)) {
|
||||
*aFlags = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE |
|
||||
URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAboutProtocolHandler::NewURI(const nsACString &aSpec,
|
||||
const char *aCharset, // ignore charset info
|
||||
|
@ -13,7 +13,8 @@
|
||||
|
||||
class nsIURI;
|
||||
|
||||
class nsAboutProtocolHandler : public nsIProtocolHandler
|
||||
class nsAboutProtocolHandler : public nsIProtocolHandlerWithDynamicFlags
|
||||
, public nsIProtocolHandler
|
||||
, public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
@ -21,6 +22,7 @@ public:
|
||||
|
||||
// nsIProtocolHandler methods:
|
||||
NS_DECL_NSIPROTOCOLHANDLER
|
||||
NS_DECL_NSIPROTOCOLHANDLERWITHDYNAMICFLAGS
|
||||
|
||||
// nsAboutProtocolHandler methods:
|
||||
nsAboutProtocolHandler() {}
|
||||
|
@ -35,7 +35,7 @@ nsViewSourceHandler::GetDefaultPort(int32_t *result)
|
||||
NS_IMETHODIMP
|
||||
nsViewSourceHandler::GetProtocolFlags(uint32_t *result)
|
||||
{
|
||||
*result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE |
|
||||
*result = URI_NORELATIVE | URI_NOAUTH | URI_DANGEROUS_TO_LOAD |
|
||||
URI_NON_PERSISTABLE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ skip-if = e10s
|
||||
[test_user_agent_updates.html]
|
||||
skip-if = e10s
|
||||
[test_user_agent_updates_reset.html]
|
||||
[test_viewsource_unlinkable.html]
|
||||
[test_xhr_method_case.html]
|
||||
[test_signed_web_packaged_app.html]
|
||||
skip-if = e10s || buildapp != 'browser'
|
||||
|
27
netwerk/test/mochitests/test_viewsource_unlinkable.html
Normal file
27
netwerk/test/mochitests/test_viewsource_unlinkable.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
-->
|
||||
<head>
|
||||
<title>Test for view-source linkability</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
function runTest() {
|
||||
SimpleTest.doesThrow(function() {
|
||||
window.open('view-source:' + location.href, "_blank");
|
||||
}, "Trying to access view-source URL from unprivileged code should throw.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="runTest();">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user