Bug 800915 - Clarify and refine the semantics of SecurityWrapper so that it is used if and only if unwrapping is unsafe. r=mrbkap

The naming scheme for Xray typedefs is the concatenation of the tuple:
({SC,}, {Security,Permissive}, Xray, {XPCWN,DOM}). This is admittedly a bit
much, but I think it's still better than explicitly doing the "typdef Foo Xray"
everywhere. Moreover, once the new DOM bindings are done, the last component
in the tuple will go away.
This commit is contained in:
Bobby Holley 2012-11-14 09:56:25 -08:00
parent 14b993064f
commit 1bc19ac093
4 changed files with 57 additions and 63 deletions

View File

@ -133,20 +133,13 @@ FilteringWrapper<Base, Policy>::enter(JSContext *cx, JSObject *wrapper, jsid id,
#define SOW FilteringWrapper<CrossCompartmentSecurityWrapper, OnlyIfSubjectIsSystem>
#define SCSOW FilteringWrapper<SameCompartmentSecurityWrapper, OnlyIfSubjectIsSystem>
#define XOW FilteringWrapper<XrayWrapper<CrossCompartmentSecurityWrapper>, \
CrossOriginAccessiblePropertiesOnly>
#define DXOW FilteringWrapper<XrayDOM, \
CrossOriginAccessiblePropertiesOnly>
#define NNXOW FilteringWrapper<CrossCompartmentSecurityWrapper, \
CrossOriginAccessiblePropertiesOnly>
#define LW FilteringWrapper<XrayWrapper<SameCompartmentSecurityWrapper>, \
LocationPolicy>
#define XLW FilteringWrapper<XrayWrapper<CrossCompartmentSecurityWrapper>, \
LocationPolicy>
#define CW FilteringWrapper<SameCompartmentSecurityWrapper, \
ComponentsObjectPolicy>
#define XCW FilteringWrapper<CrossCompartmentSecurityWrapper, \
ComponentsObjectPolicy>
#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 |
WrapperFactory::SOW_FLAG);
template<> SCSOW SCSOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |

View File

@ -323,10 +323,9 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
// Native objects must be wrapped into an X-ray wrapper.
XrayType type = GetXrayType(obj);
if (type == XrayForDOMObject) {
wrapper = &XrayDOM::singleton;
wrapper = &PermissiveXrayDOM::singleton;
} else if (type == XrayForWrappedNative) {
typedef XrayWrapper<CrossCompartmentWrapper> Xray;
wrapper = &Xray::singleton;
wrapper = &PermissiveXrayXPCWN::singleton;
} else {
wrapper = &CrossCompartmentWrapper::singleton;
}
@ -347,13 +346,12 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
if (targetdata &&
(wn = GetWrappedNative(cx, obj)) &&
wn->HasProto() && wn->GetProto()->ClassIsDOMObject()) {
typedef XrayWrapper<CrossCompartmentSecurityWrapper> Xray;
if (IsLocationObject(obj))
wrapper = &FilteringWrapper<Xray, LocationPolicy>::singleton;
wrapper = &FilteringWrapper<SecurityXrayXPCWN, LocationPolicy>::singleton;
else
wrapper = &FilteringWrapper<Xray, CrossOriginAccessiblePropertiesOnly>::singleton;
wrapper = &FilteringWrapper<SecurityXrayXPCWN, CrossOriginAccessiblePropertiesOnly>::singleton;
} else if (mozilla::dom::UseDOMXray(obj)) {
wrapper = &FilteringWrapper<XrayDOM, CrossOriginAccessiblePropertiesOnly>::singleton;
wrapper = &FilteringWrapper<SecurityXrayDOM, CrossOriginAccessiblePropertiesOnly>::singleton;
} else if (IsComponentsObject(obj)) {
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
ComponentsObjectPolicy>::singleton;
@ -408,8 +406,7 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
OnlyIfSubjectIsSystem>::singleton;
} else if (IsLocationObject(obj)) {
typedef XrayWrapper<CrossCompartmentSecurityWrapper> Xray;
wrapper = &FilteringWrapper<Xray, LocationPolicy>::singleton;
wrapper = &FilteringWrapper<SecurityXrayXPCWN, LocationPolicy>::singleton;
} else if (IsComponentsObject(obj)) {
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
ComponentsObjectPolicy>::singleton;
@ -417,10 +414,9 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
(type = GetXrayType(obj)) == NotXray) {
wrapper = &CrossCompartmentWrapper::singleton;
} else if (type == XrayForDOMObject) {
wrapper = &XrayDOM::singleton;
wrapper = &PermissiveXrayDOM::singleton;
} else {
typedef XrayWrapper<CrossCompartmentWrapper> Xray;
wrapper = &Xray::singleton;
wrapper = &PermissiveXrayXPCWN::singleton;
}
} else {
NS_ASSERTION(!AccessCheck::needsSystemOnlyWrapper(obj),
@ -433,18 +429,16 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *existing, JSObject *obj,
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
CrossOriginAccessiblePropertiesOnly>::singleton;
} else if (type == XrayForDOMObject) {
wrapper = &FilteringWrapper<XrayDOM,
wrapper = &FilteringWrapper<SecurityXrayDOM,
CrossOriginAccessiblePropertiesOnly>::singleton;
} else {
typedef XrayWrapper<CrossCompartmentSecurityWrapper> Xray;
// Location objects can become same origin after navigation, so we might
// have to grant transparent access later on.
if (IsLocationObject(obj)) {
wrapper = &FilteringWrapper<Xray, LocationPolicy>::singleton;
wrapper = &FilteringWrapper<SecurityXrayXPCWN, LocationPolicy>::singleton;
} else {
wrapper = &FilteringWrapper<Xray,
CrossOriginAccessiblePropertiesOnly>::singleton;
wrapper = &FilteringWrapper<SecurityXrayXPCWN,
CrossOriginAccessiblePropertiesOnly>::singleton;
}
}
}
@ -474,8 +468,6 @@ WrapperFactory::WrapForSameCompartment(JSContext *cx, JSObject *obj)
return wn->GetSameCompartmentSecurityWrapper(cx);
}
typedef FilteringWrapper<XrayWrapper<SameCompartmentSecurityWrapper>, LocationPolicy> LW;
bool
WrapperFactory::IsLocationObject(JSObject *obj)
{
@ -489,7 +481,8 @@ 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), &LW::singleton);
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
@ -564,9 +557,9 @@ WrapperFactory::WrapForSameCompartmentXray(JSContext *cx, JSObject *obj)
// Select the appropriate proxy handler.
Wrapper *wrapper = NULL;
if (type == XrayForWrappedNative)
wrapper = &XrayWrapper<Wrapper>::singleton;
wrapper = &SCPermissiveXrayXPCWN::singleton;
else if (type == XrayForDOMObject)
wrapper = &XrayWrapper<Wrapper, DOMXrayTraits>::singleton;
wrapper = &SCPermissiveXrayDOM::singleton;
else
MOZ_NOT_REACHED("Bad Xray type");

View File

@ -1702,37 +1702,39 @@ XrayWrapper<Base, Traits>::construct(JSContext *cx, JSObject *wrapper, unsigned
return Traits::construct(cx, wrapper, argc, argv, rval);
}
/*
* The Permissive / Security variants should be used depending on whether the
* compartment of the wrapper is guranteed to subsume the compartment of the
* wrapped object (i.e. - whether it is safe from a security perspective to
* unwrap the wrapper).
*/
#define XRAY XrayWrapper<CrossCompartmentSecurityWrapper, XPCWrappedNativeXrayTraits >
template <> XRAY XRAY::singleton(0);
template class XRAY;
#undef XRAY
template<>
PermissiveXrayXPCWN PermissiveXrayXPCWN::singleton(0);
template class PermissiveXrayXPCWN;
#define XRAY XrayWrapper<SameCompartmentSecurityWrapper, XPCWrappedNativeXrayTraits >
template <> XRAY XRAY::singleton(0);
template class XRAY;
#undef XRAY
template<>
SecurityXrayXPCWN SecurityXrayXPCWN::singleton(0);
template class SecurityXrayXPCWN;
#define XRAY XrayWrapper<CrossCompartmentWrapper, XPCWrappedNativeXrayTraits >
template <> XRAY XRAY::singleton(0);
template class XRAY;
#undef XRAY
template<>
PermissiveXrayDOM PermissiveXrayDOM::singleton(0);
template class PermissiveXrayDOM;
#define XRAY XrayWrapper<CrossCompartmentWrapper, DOMXrayTraits >
template <> XRAY XRAY::singleton(0);
template class XRAY;
#undef XRAY
template<>
SecurityXrayDOM SecurityXrayDOM::singleton(0);
template class SecurityXrayDOM;
/* Same-compartment non-filtering versions. */
template<>
SCPermissiveXrayXPCWN SCPermissiveXrayXPCWN::singleton(0);
template class SCPermissiveXrayXPCWN;
#define XRAY XrayWrapper<Wrapper, XPCWrappedNativeXrayTraits >
template <> XRAY XRAY::singleton(0);
template class XRAY;
#undef XRAY
template<>
SCSecurityXrayXPCWN SCSecurityXrayXPCWN::singleton(0);
template class SCSecurityXrayXPCWN;
#define XRAY XrayWrapper<Wrapper, DOMXrayTraits >
template <> XRAY XRAY::singleton(0);
template class XRAY;
#undef XRAY
template<>
SCPermissiveXrayDOM SCPermissiveXrayDOM::singleton(0);
template class SCPermissiveXrayDOM;
}

View File

@ -93,7 +93,13 @@ class XrayWrapper : public Base {
JS::AutoIdVector &props);
};
typedef XrayWrapper<js::CrossCompartmentWrapper, DOMXrayTraits > XrayDOM;
#define PermissiveXrayXPCWN xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::XPCWrappedNativeXrayTraits>
#define SecurityXrayXPCWN xpc::XrayWrapper<js::CrossCompartmentSecurityWrapper, xpc::XPCWrappedNativeXrayTraits>
#define PermissiveXrayDOM xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::DOMXrayTraits>
#define SecurityXrayDOM xpc::XrayWrapper<js::CrossCompartmentSecurityWrapper, xpc::DOMXrayTraits>
#define SCSecurityXrayXPCWN xpc::XrayWrapper<js::SameCompartmentSecurityWrapper, xpc::XPCWrappedNativeXrayTraits>
#define SCPermissiveXrayXPCWN xpc::XrayWrapper<js::Wrapper, xpc::XPCWrappedNativeXrayTraits>
#define SCPermissiveXrayDOM xpc::XrayWrapper<js::Wrapper, xpc::DOMXrayTraits>
class SandboxProxyHandler : public js::Wrapper {
public: