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

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

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

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

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

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

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