зеркало из https://github.com/mozilla/gecko-dev.git
Bug 808608 - Remove specialized Location security wrappers. r=mrbkap
This commit is contained in:
Родитель
660ca5d5cf
Коммит
11d6106099
|
@ -1592,18 +1592,10 @@ XPCWrappedNative::ReparentWrapperIfFound(XPCCallContext& ccx,
|
|||
JSObject *ww = wrapper->GetWrapper();
|
||||
if (ww) {
|
||||
JSObject *newwrapper;
|
||||
MOZ_ASSERT(!xpc::WrapperFactory::IsComponentsObject(flat),
|
||||
"Components object should never get here");
|
||||
if (xpc::WrapperFactory::IsLocationObject(flat)) {
|
||||
newwrapper = xpc::WrapperFactory::WrapLocationObject(ccx, newobj);
|
||||
if (!newwrapper)
|
||||
MOZ_CRASH();
|
||||
} else {
|
||||
NS_ASSERTION(wrapper->NeedsSOW(), "weird wrapper wrapper");
|
||||
newwrapper = xpc::WrapperFactory::WrapSOWObject(ccx, newobj);
|
||||
if (!newwrapper)
|
||||
MOZ_CRASH();
|
||||
}
|
||||
MOZ_ASSERT(wrapper->NeedsSOW(), "weird wrapper wrapper");
|
||||
newwrapper = xpc::WrapperFactory::WrapSOWObject(ccx, newobj);
|
||||
if (!newwrapper)
|
||||
MOZ_CRASH();
|
||||
|
||||
// Ok, now we do the special object-plus-wrapper transplant.
|
||||
ww = xpc::TransplantObjectWithWrapper(ccx, flat, ww, newobj,
|
||||
|
@ -2213,11 +2205,7 @@ XPCWrappedNative::GetSameCompartmentSecurityWrapper(JSContext *cx)
|
|||
// Check the possibilities. Note that we need to check for null in each
|
||||
// case in order to distinguish between the 'no need for wrapper' and
|
||||
// 'wrapping failed' cases.
|
||||
if (xpc::WrapperFactory::IsLocationObject(flat)) {
|
||||
wrapper = xpc::WrapperFactory::WrapLocationObject(cx, flat);
|
||||
if (!wrapper)
|
||||
return NULL;
|
||||
} else if (NeedsSOW()) {
|
||||
if (NeedsSOW()) {
|
||||
wrapper = xpc::WrapperFactory::WrapSOWObject(cx, flat);
|
||||
if (!wrapper)
|
||||
return NULL;
|
||||
|
|
|
@ -79,32 +79,6 @@ AccessCheck::wrapperSubsumes(JSObject *wrapper)
|
|||
js::GetObjectCompartment(wrapped));
|
||||
}
|
||||
|
||||
bool
|
||||
AccessCheck::isLocationObjectSameOrigin(JSContext *cx, JSObject *wrapper)
|
||||
{
|
||||
// The caller must ensure that the given wrapper wraps a Location object.
|
||||
MOZ_ASSERT(WrapperFactory::IsLocationObject(js::UnwrapObject(wrapper)));
|
||||
|
||||
// Location objects are parented to the outer window for which they
|
||||
// were created. This gives us an easy way to determine whether our
|
||||
// object is same origin with the current inner window:
|
||||
|
||||
// Grab the outer window...
|
||||
JSObject *obj = js::GetObjectParent(js::UnwrapObject(wrapper));
|
||||
if (!js::GetObjectClass(obj)->ext.innerObject) {
|
||||
// ...which might be wrapped in a security wrapper.
|
||||
obj = js::UnwrapObject(obj);
|
||||
MOZ_ASSERT(js::GetObjectClass(obj)->ext.innerObject);
|
||||
}
|
||||
|
||||
// Now innerize it to find the *current* inner window for our outer.
|
||||
obj = JS_ObjectToInnerObject(cx, obj);
|
||||
|
||||
// Which lets us compare the current compartment against the old one.
|
||||
return obj && subsumes(js::GetObjectCompartment(wrapper),
|
||||
js::GetObjectCompartment(obj));
|
||||
}
|
||||
|
||||
bool
|
||||
AccessCheck::isChrome(JSCompartment *compartment)
|
||||
{
|
||||
|
@ -299,9 +273,7 @@ AccessCheck::isScriptAccessOnly(JSContext *cx, JSObject *wrapper)
|
|||
return true; // script-only
|
||||
}
|
||||
|
||||
// Allow non-script access to same-origin location objects and any other
|
||||
// objects.
|
||||
return WrapperFactory::IsLocationObject(obj) && !isLocationObjectSameOrigin(cx, wrapper);
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -29,7 +29,6 @@ class AccessCheck {
|
|||
js::Wrapper::Action act);
|
||||
static bool callerIsXBL(JSContext *cx);
|
||||
static bool isSystemOnlyAccessPermitted(JSContext *cx);
|
||||
static bool isLocationObjectSameOrigin(JSContext *cx, JSObject *wrapper);
|
||||
|
||||
static bool needsSystemOnlyWrapper(JSObject *obj);
|
||||
|
||||
|
@ -58,8 +57,6 @@ struct OnlyIfSubjectIsSystem : public Policy {
|
|||
// across origins.
|
||||
struct CrossOriginAccessiblePropertiesOnly : public Policy {
|
||||
static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act) {
|
||||
// Location objects should always use LocationPolicy.
|
||||
MOZ_ASSERT(!WrapperFactory::IsLocationObject(js::UnwrapObject(wrapper)));
|
||||
return AccessCheck::isCrossOriginAccessPermitted(cx, wrapper, id, act);
|
||||
}
|
||||
static bool deny(JSContext *cx, jsid id, js::Wrapper::Action act) {
|
||||
|
@ -68,46 +65,6 @@ struct CrossOriginAccessiblePropertiesOnly : public Policy {
|
|||
}
|
||||
};
|
||||
|
||||
// We need a special security policy for Location objects.
|
||||
//
|
||||
// Location objects are special because their effective principal is that of
|
||||
// the outer window, not the inner window. So while the security characteristics
|
||||
// of most objects can be inferred from their compartments, those of the Location
|
||||
// object cannot. This has two implications:
|
||||
//
|
||||
// 1 - Same-compartment access of Location objects is not necessarily allowed.
|
||||
// This means that objects must see a security wrapper around Location objects
|
||||
// in their own compartment.
|
||||
// 2 - Cross-origin access of Location objects is not necessarily forbidden.
|
||||
// Since the security decision depends on the current state of the outer window,
|
||||
// we can't make it at wrap time. Instead, we need to make it at the time of
|
||||
// access.
|
||||
//
|
||||
// So for any Location object access, be it same-compartment or cross-compartment,
|
||||
// we need to do a dynamic security check to determine whether the outer window is
|
||||
// same-origin with the caller.
|
||||
//
|
||||
// So this policy first checks whether the access is something that any code,
|
||||
// same-origin or not, is allowed to make. If it isn't, it _also_ checks the
|
||||
// state of the outer window to determine whether we happen to be same-origin
|
||||
// at the moment.
|
||||
struct LocationPolicy : public Policy {
|
||||
static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act) {
|
||||
// We should only be dealing with Location objects here.
|
||||
MOZ_ASSERT(WrapperFactory::IsLocationObject(js::UnwrapObject(wrapper)));
|
||||
|
||||
if ((AccessCheck::isCrossOriginAccessPermitted(cx, wrapper, id, act) ||
|
||||
AccessCheck::isLocationObjectSameOrigin(cx, wrapper))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static bool deny(JSContext *cx, jsid id, js::Wrapper::Action act) {
|
||||
AccessCheck::deny(cx, id);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// This policy only permits access to properties if they appear in the
|
||||
// objects exposed properties list.
|
||||
struct ExposedPropertiesOnly : public Policy {
|
||||
|
|
|
@ -136,8 +136,6 @@ FilteringWrapper<Base, Policy>::enter(JSContext *cx, JSObject *wrapper, jsid id,
|
|||
#define XOW FilteringWrapper<SecurityXrayXPCWN, CrossOriginAccessiblePropertiesOnly>
|
||||
#define DXOW FilteringWrapper<SecurityXrayDOM, CrossOriginAccessiblePropertiesOnly>
|
||||
#define NNXOW FilteringWrapper<CrossCompartmentSecurityWrapper, CrossOriginAccessiblePropertiesOnly>
|
||||
#define LW FilteringWrapper<SCSecurityXrayXPCWN, LocationPolicy>
|
||||
#define XLW FilteringWrapper<SecurityXrayXPCWN, LocationPolicy>
|
||||
#define CW FilteringWrapper<SameCompartmentSecurityWrapper, ComponentsObjectPolicy>
|
||||
#define XCW FilteringWrapper<CrossCompartmentSecurityWrapper, ComponentsObjectPolicy>
|
||||
template<> SOW SOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
|
||||
|
@ -147,8 +145,6 @@ template<> SCSOW SCSOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
|
|||
template<> XOW XOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG);
|
||||
template<> DXOW DXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG);
|
||||
template<> NNXOW NNXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG);
|
||||
template<> LW LW::singleton(WrapperFactory::SHADOWING_FORBIDDEN);
|
||||
template<> XLW XLW::singleton(WrapperFactory::SHADOWING_FORBIDDEN);
|
||||
|
||||
template<> CW CW::singleton(0);
|
||||
template<> XCW XCW::singleton(0);
|
||||
|
@ -157,7 +153,5 @@ template class SOW;
|
|||
template class XOW;
|
||||
template class DXOW;
|
||||
template class NNXOW;
|
||||
template class LW;
|
||||
template class XLW;
|
||||
template class ChromeObjectWrapperBase;
|
||||
}
|
||||
|
|
|
@ -301,8 +301,7 @@ DEBUG_CheckUnwrapSafety(JSObject *obj, js::Wrapper *handler,
|
|||
if (AccessCheck::isChrome(target) || xpc::IsUniversalXPConnectEnabled(target)) {
|
||||
// If the caller is chrome (or effectively so), unwrap should always be allowed.
|
||||
MOZ_ASSERT(handler->isSafeToUnwrap());
|
||||
} else if (WrapperFactory::IsLocationObject(obj) ||
|
||||
WrapperFactory::IsComponentsObject(obj) ||
|
||||
} else if (WrapperFactory::IsComponentsObject(obj) ||
|
||||
handler == &XSOW::singleton)
|
||||
{
|
||||
// This is an object that is restricted regardless of origin.
|
||||
|
@ -371,10 +370,7 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
|
|||
if (targetdata &&
|
||||
(wn = GetWrappedNative(cx, obj)) &&
|
||||
wn->HasProto() && wn->GetProto()->ClassIsDOMObject()) {
|
||||
if (IsLocationObject(obj))
|
||||
wrapper = &FilteringWrapper<SecurityXrayXPCWN, LocationPolicy>::singleton;
|
||||
else
|
||||
wrapper = &FilteringWrapper<SecurityXrayXPCWN, CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
wrapper = &FilteringWrapper<SecurityXrayXPCWN, CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
} else if (mozilla::dom::UseDOMXray(obj)) {
|
||||
wrapper = &FilteringWrapper<SecurityXrayDOM, CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
} else if (IsComponentsObject(obj)) {
|
||||
|
@ -419,7 +415,6 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
|
|||
// For the same-origin case we use a transparent wrapper, unless one
|
||||
// of the following is true:
|
||||
// * The object is flagged as needing a SOW.
|
||||
// * The object is a Location object.
|
||||
// * The object is a Components object.
|
||||
// * The context compartment specifically requested Xray vision into
|
||||
// same-origin compartments.
|
||||
|
@ -430,8 +425,6 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
|
|||
if (AccessCheck::needsSystemOnlyWrapper(obj)) {
|
||||
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
|
||||
OnlyIfSubjectIsSystem>::singleton;
|
||||
} else if (IsLocationObject(obj)) {
|
||||
wrapper = &FilteringWrapper<SecurityXrayXPCWN, LocationPolicy>::singleton;
|
||||
} else if (IsComponentsObject(obj)) {
|
||||
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
|
||||
ComponentsObjectPolicy>::singleton;
|
||||
|
@ -457,14 +450,8 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
|
|||
wrapper = &FilteringWrapper<SecurityXrayDOM,
|
||||
CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
} else {
|
||||
// Location objects can become same origin after navigation, so we might
|
||||
// have to grant transparent access later on.
|
||||
if (IsLocationObject(obj)) {
|
||||
wrapper = &FilteringWrapper<SecurityXrayXPCWN, LocationPolicy>::singleton;
|
||||
} else {
|
||||
wrapper = &FilteringWrapper<SecurityXrayXPCWN,
|
||||
CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
}
|
||||
wrapper = &FilteringWrapper<SecurityXrayXPCWN,
|
||||
CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -497,23 +484,6 @@ WrapperFactory::WrapForSameCompartment(JSContext *cx, JSObject *obj)
|
|||
return wrapper;
|
||||
}
|
||||
|
||||
bool
|
||||
WrapperFactory::IsLocationObject(JSObject *obj)
|
||||
{
|
||||
const char *name = js::GetObjectClass(obj)->name;
|
||||
return name[0] == 'L' && !strcmp(name, "Location");
|
||||
}
|
||||
|
||||
JSObject *
|
||||
WrapperFactory::WrapLocationObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSObject *proto;
|
||||
if (!js::GetObjectProto(cx, obj, &proto))
|
||||
return nullptr;
|
||||
return Wrapper::New(cx, obj, proto, js::GetObjectParent(obj),
|
||||
&FilteringWrapper<SCSecurityXrayXPCWN, LocationPolicy>::singleton);
|
||||
}
|
||||
|
||||
// Call WaiveXrayAndWrap when you have a JS object that you don't want to be
|
||||
// wrapped in an Xray wrapper. cx->compartment is the compartment that will be
|
||||
// using the returned object. If the object to be wrapped is already in the
|
||||
|
|
|
@ -69,12 +69,6 @@ class WrapperFactory {
|
|||
static JSObject *WrapForSameCompartment(JSContext *cx,
|
||||
JSObject *obj);
|
||||
|
||||
// Return true if this is a location object.
|
||||
static bool IsLocationObject(JSObject *obj);
|
||||
|
||||
// Wrap a location object.
|
||||
static JSObject *WrapLocationObject(JSContext *cx, JSObject *obj);
|
||||
|
||||
// Wrap wrapped object into a waiver wrapper and then re-wrap it.
|
||||
static bool WaiveXrayAndWrap(JSContext *cx, jsval *vp);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче