Bug 1040181 - Use an opaque wrapper rather than failing in Rewrap. r=gabor

This commit is contained in:
Bobby Holley 2014-07-20 10:03:58 -06:00
Родитель e40e32e01c
Коммит 71765487c1
4 изменённых файлов: 26 добавлений и 13 удалений

Просмотреть файл

@ -19,6 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=601277
<![CDATA[
/** Tests for document.domain. **/
const Cu = Components.utils;
SimpleTest.waitForExplicitFinish();
// Wait for the frames to load.
@ -50,6 +51,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=601277
win1A.storeReference(win1B);
win1B.storeReference(win1A);
ok(win1A.tryToAccessStored(), "Stored references work when same-origin");
win1A.evalFromB = Cu.unwaiveXrays(win1B.eval); // Crashtest for bug 1040181.
win1B.functionFromA = Cu.unwaiveXrays(win1A.Function); // Crashtest for bug 1040181.
ok(!win1A.invokingFunctionThrowsSecurityException('evalFromB'), "Should allow before document.domain");
ok(!win1B.invokingFunctionThrowsSecurityException('functionFromA'), "Should allow before document.domain");
// Set document.domain on test1A. This should grant no access, since nobody
// else set it.
@ -60,6 +65,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=601277
ok(!win1A.tryToAccessStored(), "No longer same-origin");
ok(!win1B.tryToAccess(win1A), "No longer same-origin");
ok(!win1B.tryToAccessStored(), "No longer same-origin");
ok(win1A.invokingFunctionThrowsSecurityException('evalFromB'), "No longer same-origin");
ok(win1B.invokingFunctionThrowsSecurityException('functionFromA'), "No longer same-origin");
// Set document.domain on test1B. Now we're cooking with gas.
win1B.setDomain('example.org');

Просмотреть файл

@ -25,6 +25,13 @@
} catch (e) { return false; }
}
function invokingFunctionThrowsSecurityException(name) {
try {
window[name]();
return false;
} catch (e) { return /insecure|denied/.test(e); }
}
</script>
</head>

Просмотреть файл

@ -5,20 +5,20 @@
const Cu = Components.utils;
function run_test() {
let unprivilegedSb = new Cu.Sandbox('http://www.example.com');
function checkCantWrap(val) {
function checkOpaqueWrapper(val) {
unprivilegedSb.prop = val;
try {
unprivilegedSb.prop = val;
do_check_true(false);
Cu.evalInSandbox('prop();', sb);
} catch (e) {
do_check_true(/denied|insecure|/.test(e));
}
}
let xoSb = new Cu.Sandbox('http://www.example.net');
let epSb = new Cu.Sandbox(['http://www.example.com']);
checkCantWrap(eval);
checkCantWrap(xoSb.eval);
checkCantWrap(epSb.eval);
checkCantWrap(Function);
checkCantWrap(xoSb.Function);
checkCantWrap(epSb.Function);
checkOpaqueWrapper(eval);
checkOpaqueWrapper(xoSb.eval);
checkOpaqueWrapper(epSb.eval);
checkOpaqueWrapper(Function);
checkOpaqueWrapper(xoSb.Function);
checkOpaqueWrapper(epSb.Function);
}

Просмотреть файл

@ -525,11 +525,10 @@ WrapperFactory::Rewrap(JSContext *cx, HandleObject existing, HandleObject obj,
if (!targetSubsumesOrigin) {
// Do a belt-and-suspenders check against exposing eval()/Function() to
// non-subsuming content.
JSFunction *fun = JS_GetObjectFunction(obj);
if (fun) {
if (JSFunction *fun = JS_GetObjectFunction(obj)) {
if (JS_IsBuiltinEvalFunction(fun) || JS_IsBuiltinFunctionConstructor(fun)) {
JS_ReportError(cx, "Permission denied to expose eval or Function to non-subsuming content");
return nullptr;
NS_WARNING("Trying to expose eval or Function to non-subsuming content!");
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>::singleton;
}
}
}