зеркало из https://github.com/mozilla/gecko-dev.git
Bug 995943 - Allow access to file:// URIs from pref-whitelisted sites. r=bz
This commit is contained in:
Родитель
d290b8b81b
Коммит
293af2c9f3
|
@ -20,7 +20,7 @@
|
|||
#include <stdint.h>
|
||||
|
||||
class nsIDocShell;
|
||||
class nsString;
|
||||
class nsCString;
|
||||
class nsIClassInfo;
|
||||
class nsIIOService;
|
||||
class nsIStringBundle;
|
||||
|
@ -139,9 +139,13 @@ private:
|
|||
inline void
|
||||
ScriptSecurityPrefChanged();
|
||||
|
||||
inline void
|
||||
AddSitesToFileURIWhitelist(const nsCString& aSiteList);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> mSystemPrincipal;
|
||||
bool mPrefInitialized;
|
||||
bool mIsJavaScriptEnabled;
|
||||
nsTArray<nsCOMPtr<nsIURI>> mFileURIWhitelist;
|
||||
|
||||
// This machinery controls new-style domain policies. The old-style
|
||||
// policy machinery will be removed soon.
|
||||
|
|
|
@ -722,6 +722,14 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
|||
&hasFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasFlags) {
|
||||
// Allow domains that were whitelisted in the prefs. In 99.9% of cases,
|
||||
// this array is empty.
|
||||
for (size_t i = 0; i < mFileURIWhitelist.Length(); ++i) {
|
||||
if (SecurityCompareURIs(mFileURIWhitelist[i], sourceURI)) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// resource: and chrome: are equivalent, securitywise
|
||||
// That's bogus!! Fix this. But watch out for
|
||||
// the view-source stylesheet?
|
||||
|
@ -1142,6 +1150,7 @@ const char sFileOriginPolicyPrefName[] =
|
|||
static const char* kObservedPrefs[] = {
|
||||
sJSEnabledPrefName,
|
||||
sFileOriginPolicyPrefName,
|
||||
"capability.policy.",
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
@ -1260,6 +1269,31 @@ nsScriptSecurityManager::SystemPrincipalSingletonConstructor()
|
|||
return static_cast<nsSystemPrincipal*>(sysprin);
|
||||
}
|
||||
|
||||
struct IsWhitespace {
|
||||
static bool Test(char aChar) { return NS_IsAsciiWhitespace(aChar); };
|
||||
};
|
||||
struct IsWhitespaceOrComma {
|
||||
static bool Test(char aChar) { return aChar == ',' || NS_IsAsciiWhitespace(aChar); };
|
||||
};
|
||||
|
||||
template <typename Predicate>
|
||||
uint32_t SkipPast(const nsCString& str, uint32_t base)
|
||||
{
|
||||
while (base < str.Length() && Predicate::Test(str[base])) {
|
||||
++base;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
template <typename Predicate>
|
||||
uint32_t SkipUntil(const nsCString& str, uint32_t base)
|
||||
{
|
||||
while (base < str.Length() && !Predicate::Test(str[base])) {
|
||||
++base;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
inline void
|
||||
nsScriptSecurityManager::ScriptSecurityPrefChanged()
|
||||
{
|
||||
|
@ -1268,6 +1302,65 @@ nsScriptSecurityManager::ScriptSecurityPrefChanged()
|
|||
Preferences::GetBool(sJSEnabledPrefName, mIsJavaScriptEnabled);
|
||||
sStrictFileOriginPolicy =
|
||||
Preferences::GetBool(sFileOriginPolicyPrefName, false);
|
||||
|
||||
//
|
||||
// Rebuild the set of principals for which we allow file:// URI loads. This
|
||||
// implements a small subset of an old pref-based CAPS people that people
|
||||
// have come to depend on. See bug 995943.
|
||||
//
|
||||
|
||||
mFileURIWhitelist.Clear();
|
||||
auto policies = mozilla::Preferences::GetCString("capability.policy.policynames");
|
||||
for (uint32_t base = SkipPast<IsWhitespaceOrComma>(policies, 0), bound = 0;
|
||||
base < policies.Length();
|
||||
base = SkipPast<IsWhitespaceOrComma>(policies, bound))
|
||||
{
|
||||
// Grab the current policy name.
|
||||
bound = SkipUntil<IsWhitespaceOrComma>(policies, base);
|
||||
auto policyName = Substring(policies, base, bound - base);
|
||||
|
||||
// Figure out if this policy allows loading file:// URIs. If not, we can skip it.
|
||||
nsCString checkLoadURIPrefName = NS_LITERAL_CSTRING("capability.policy.") +
|
||||
policyName +
|
||||
NS_LITERAL_CSTRING(".checkloaduri.enabled");
|
||||
if (!Preferences::GetString(checkLoadURIPrefName.get()).LowerCaseEqualsLiteral("allaccess")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Grab the list of domains associated with this policy.
|
||||
nsCString domainPrefName = NS_LITERAL_CSTRING("capability.policy.") +
|
||||
policyName +
|
||||
NS_LITERAL_CSTRING(".sites");
|
||||
auto siteList = Preferences::GetCString(domainPrefName.get());
|
||||
AddSitesToFileURIWhitelist(siteList);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsScriptSecurityManager::AddSitesToFileURIWhitelist(const nsCString& aSiteList)
|
||||
{
|
||||
for (uint32_t base = SkipPast<IsWhitespace>(aSiteList, 0), bound = 0;
|
||||
base < aSiteList.Length();
|
||||
base = SkipPast<IsWhitespace>(aSiteList, bound))
|
||||
{
|
||||
// Grab the current site.
|
||||
bound = SkipUntil<IsWhitespace>(aSiteList, base);
|
||||
auto site = Substring(aSiteList, base, bound - base);
|
||||
|
||||
// Convert it to a URI and add it to our list.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), site, nullptr, nullptr, sIOService);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mFileURIWhitelist.AppendElement(uri);
|
||||
} else {
|
||||
nsCOMPtr<nsIConsoleService> console(do_GetService("@mozilla.org/consoleservice;1"));
|
||||
if (console) {
|
||||
nsAutoString msg = NS_LITERAL_STRING("Unable to to add site to file:// URI whitelist: ") +
|
||||
NS_ConvertASCIItoUTF16(site);
|
||||
console->LogStringMessage(msg.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
support-files =
|
||||
file_disableScript.html
|
||||
|
||||
[test_bug995943.xul]
|
||||
[test_disableScript.xul]
|
||||
[test_principal_jarprefix_origin_appid_appstatus.html]
|
||||
# jarPrefix test doesn't work on Windows, see bug 776296.
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=995943
|
||||
-->
|
||||
<window title="Mozilla Bug 995943"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=995943"
|
||||
target="_blank">Mozilla Bug 995943</a>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
function debug(msg) { info(msg); }
|
||||
|
||||
/** Test for CAPS file:// URI prefs. **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var profileDir = "file://" + Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties)
|
||||
.get("ProfD", Ci.nsILocalFile).path;
|
||||
|
||||
function checkLoadFileURI(domain, shouldLoad) {
|
||||
debug("Invoking checkLoadFileURI with domain: " + domain + ", shouldLoad: " + shouldLoad);
|
||||
return new Promise(function(resolve, reject) {
|
||||
$('ifr').addEventListener('load', function l1() {
|
||||
$('ifr').removeEventListener('load', l1);
|
||||
function l2() {
|
||||
$('ifr').removeEventListener('load', l2);
|
||||
ok(shouldLoad, "Successfully loaded file:// URI for domain: " + domain);
|
||||
resolve();
|
||||
}
|
||||
$('ifr').addEventListener('load', l2);
|
||||
try {
|
||||
window[0].wrappedJSObject.location = profileDir;
|
||||
} catch (e) {
|
||||
ok(!shouldLoad && /denied|insecure/.test(e),
|
||||
"Prevented loading of file:// URI for domain: " + domain + " - " + e);
|
||||
$('ifr').removeEventListener('load', l2);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
let targetURI = domain + '/tests/js/xpconnect/tests/mochitest/file_empty.html';
|
||||
debug("Navigating iframe to " + targetURI);
|
||||
$('ifr').contentWindow.location = targetURI;
|
||||
});
|
||||
}
|
||||
|
||||
function pushPrefs(prefs) {
|
||||
return new Promise(function(resolve) { SpecialPowers.pushPrefEnv({ set: prefs }, resolve); });
|
||||
}
|
||||
|
||||
function popPrefs() {
|
||||
return new Promise(function(resolve) { SpecialPowers.popPrefEnv(resolve); });
|
||||
}
|
||||
|
||||
function go() {
|
||||
checkLoadFileURI('http://example.com', false).then(
|
||||
pushPrefs.bind(null, [['capability.policy.policynames', ' somepolicy '],
|
||||
['capability.policy.somepolicy.checkloaduri.enabled', 'AlLAcCeSs'],
|
||||
['capability.policy.somepolicy.sites', 'http://example.com']]))
|
||||
.then(checkLoadFileURI.bind(null, 'http://example.com', true))
|
||||
.then(popPrefs)
|
||||
.then(checkLoadFileURI.bind(null, 'http://example.com', false))
|
||||
.then(
|
||||
pushPrefs.bind(null, [['capability.policy.policynames', ',somepolicy, someotherpolicy, '],
|
||||
['capability.policy.somepolicy.checkloaduri.enabled', 'allaccess'],
|
||||
['capability.policy.someotherpolicy.checkloaduri.enabled', 'nope'],
|
||||
['capability.policy.somepolicy.sites', ' http://example.org https://example.com'],
|
||||
['capability.policy.someotherpolicy.sites', 'http://example.net ']]))
|
||||
.then(checkLoadFileURI.bind(null, 'http://example.org', true))
|
||||
.then(checkLoadFileURI.bind(null, 'http://example.com', false))
|
||||
.then(checkLoadFileURI.bind(null, 'https://example.com', true))
|
||||
.then(checkLoadFileURI.bind(null, 'http://example.net', false))
|
||||
.then(pushPrefs.bind(null, [['capability.policy.someotherpolicy.checkloaduri.enabled', 'allAccess']]))
|
||||
.then(checkLoadFileURI.bind(null, 'http://example.net', true))
|
||||
.then(popPrefs)
|
||||
.then(popPrefs)
|
||||
.then(checkLoadFileURI.bind(null, 'http://example.net', false))
|
||||
.then(SimpleTest.finish.bind(SimpleTest));
|
||||
|
||||
}
|
||||
addLoadEvent(go);
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<iframe id="ifr" type="content" />
|
||||
</window>
|
|
@ -21,11 +21,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=758258
|
|||
/** Test for Bug 758258 **/
|
||||
|
||||
var Ci = Components.interfaces;
|
||||
|
||||
if (navigator.platform.startsWith("Mac")) {
|
||||
SimpleTest.expectAssertions(2);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче