Bug 853571 - Add some belt-and-suspenders checks for sketchy scripted caller detection. r=bz

This commit is contained in:
Bobby Holley 2013-03-24 09:27:09 -07:00
Родитель c5dfe5a176
Коммит 172185a82e
2 изменённых файлов: 25 добавлений и 1 удалений

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

@ -6370,9 +6370,24 @@ JSObject* nsGlobalWindow::CallerGlobal()
return nullptr;
}
return JS_GetScriptedGlobal(cx);
// If somebody does sameOriginIframeWindow.postMessage(...), they probably
// expect the .source attribute of the resulting message event to be |window|
// rather than |sameOriginIframeWindow|, even though the transparent wrapper
// semantics of same-origin access will cause us to be in the iframe's cx at
// the time of the call. So we do some nasty poking in the JS engine and
// retrieve the global corresponding to the innermost scripted frame. Then,
// we verify that its principal is subsumed by the subject principal. If it
// isn't, something is screwy, and we want to clamp to the cx global.
JSObject *scriptedGlobal = JS_GetScriptedGlobal(cx);
JSObject *cxGlobal = JS_GetGlobalForScopeChain(cx);
if (!xpc::AccessCheck::subsumes(cxGlobal, scriptedGlobal)) {
NS_WARNING("Something nasty is happening! Applying countermeasures...");
return cxGlobal;
}
return scriptedGlobal;
}
nsGlobalWindow*
nsGlobalWindow::CallerInnerWindow()
{

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

@ -2218,6 +2218,15 @@ JS_GetGlobalForCompartmentOrNull(JSContext *cx, JSCompartment *c);
extern JS_PUBLIC_API(JSObject *)
JS_GetGlobalForScopeChain(JSContext *cx);
/*
* This method returns the global corresponding to the most recent scripted
* frame, which may not match the cx's current compartment. This is extremely
* dangerous, because it can bypass compartment security invariants in subtle
* ways. To use it safely, the caller must perform a subsequent security
* check. There is currently only one consumer of this function in Gecko, and
* it should probably stay that way. If you'd like to use it, please consult
* the XPConnect module owner first.
*/
extern JS_PUBLIC_API(JSObject *)
JS_GetScriptedGlobal(JSContext *cx);