Closed Bug 730431 Opened 12 years ago Closed 12 years ago

cross-origin Location object can be toString()-ed in the web console

Categories

(Core :: Security: CAPS, defect)

defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: bholley, Unassigned)

References

Details

window.myframe = document.createElement('iframe')
myframe.src = 'http://www.other.com';
document.body.appendChild(myframe);

// This throws
myframe.contentWindow.location.href

// This doesn't
myframe.contentWindow.location
This is probably bug 720619.
Group: core-security
Depends on: CVE-2012-4193
Keywords: sec-other
Whiteboard: [sg:dupe 720619?]
nope, can't be bug 720619 because that's now fixed on trunk and I still see these symptoms: myframe.contentWindow.location can read a cross-origin location (in the web console)
Comment 1 is private: false
Whiteboard: [sg:dupe 720619?]
Keywords: sec-other
It's not clear to what extent this is a bug.

What's going on here is that when you run code in the console it runs in a page-privilege sandbox and hands its result out to chrome script.  The chrome script then does the toString conversion.  This is necessary so that the chrome script can show objects in a meaningful way, etc.

Of course chrome can stringify any Location object.
Yeah, that all sounds reasonable. Boris, that analysis in confirmed by experiment, not just theory, right? If so, I think we can open up this bug.
> Boris, that analysis in confirmed by experiment, not just theory, right?

Breakpoint 1, nsLocation::ToString (this=0x11d44de20, aReturn=@0x11101f560) at nsLocation.cpp:927
927       return GetHref(aReturn);
(gdb) bt
#0  nsLocation::ToString (this=0x11d44de20, aReturn=@0x11101f560) at nsLocation.cpp:927
#1  0x0000000104a91859 in NS_InvokeByIndex_P (that=0x11d44de20, methodIndex=22, paramCount=1, params=0x7fff5fbedf40) at xptcinvoke_x86_64_unix.cpp:162
#2  0x0000000103dc5ed4 in CallMethodHelper::Invoke (this=0x7fff5fbedf00) at XPCWrappedNative.cpp:3108
#3  0x0000000103dc41dc in CallMethodHelper::Call (this=0x7fff5fbedf00) at XPCWrappedNative.cpp:2442
#4  0x0000000103dc0691 in XPCWrappedNative::CallMethod (ccx=@0x7fff5fbee108, mode=XPCWrappedNative::CALL_METHOD) at XPCWrappedNative.cpp:2408
#5  0x0000000103dcd97a in XPC_WN_Shared_Convert (cx=0x10cfa4360, obj={<js::HandleBase<JSObject *>> = {<No data fields>}, ptr = 0x7fff5fbee2c8}, type=JSTYPE_VOID, vp={<js::MutableHandleBase<JS::Value>> = {<js::MutableValueOperations<JS::MutableHandle<JS::Value> >> = {<js::ValueOperations<JS::MutableHandle<JS::Value> >> = {<No data fields>}, <No data fields>}, <No data fields>}, ptr = 0x7fff5fbee2b0}) at XPCWrappedNativeJSOps.cpp:541
#6  0x0000000101050423 in JSObject::defaultValue (cx=0x10cfa4360, obj={<js::HandleBase<JSObject *>> = {<No data fields>}, ptr = 0x7fff5fbee2c8}, hint=JSTYPE_VOID, vp={<js::MutableHandleBase<JS::Value>> = {<js::MutableValueOperations<JS::MutableHandle<JS::Value> >> = {<js::ValueOperations<JS::MutableHandle<JS::Value> >> = {<No data fields>}, <No data fields>}, <No data fields>}, ptr = 0x7fff5fbee2b0}) at jsobjinlines.h:69
#7  0x0000000101200bb6 in js::ToPrimitive () at jsproxy.cpp:533
#8  0x0000000101200a8d in js::IndirectProxyHandler::defaultValue (this=0x106be40b0, cx=0x10cfa4360, proxy=0x10e962180, hint=JSTYPE_VOID, vp=0x7fff5fbee640) at jsproxy.cpp:531
#9  0x00000001012ee1ef in js::DirectWrapper::defaultValue (this=0x106be40a0, cx=0x10cfa4360, wrapper_=0x10e962180, hint=JSTYPE_VOID, vp=0x7fff5fbee640) at jswrapper.cpp:336
#10 0x00000001012ee275 in non-virtual thunk to js::DirectWrapper::defaultValue(JSContext*, JSObject*, JSType, JS::Value*) () at jswrapper.cpp:337
#11 0x000000010120f648 in js::Proxy::defaultValue (cx=0x10cfa4360, proxy_=0x10e962180, hint=JSTYPE_VOID, vp=0x7fff5fbee640) at jsproxy.cpp:2541
#12 0x000000010120f8b9 in proxy_Convert (cx=0x10cfa4360, proxy={<js::HandleBase<JSObject *>> = {<No data fields>}, ptr = 0x7fff5fbee658}, hint=JSTYPE_VOID, vp={<js::MutableHandleBase<JS::Value>> = {<js::MutableValueOperations<JS::MutableHandle<JS::Value> >> = {<js::ValueOperations<JS::MutableHandle<JS::Value> >> = {<No data fields>}, <No data fields>}, <No data fields>}, ptr = 0x7fff5fbee640}) at jsproxy.cpp:2868
#13 0x0000000101050423 in JSObject::defaultValue (cx=0x10cfa4360, obj={<js::HandleBase<JSObject *>> = {<No data fields>}, ptr = 0x7fff5fbee658}, hint=JSTYPE_VOID, vp={<js::MutableHandleBase<JS::Value>> = {<js::MutableValueOperations<JS::MutableHandle<JS::Value> >> = {<js::ValueOperations<JS::MutableHandle<JS::Value> >> = {<No data fields>}, <No data fields>}, <No data fields>}, ptr = 0x7fff5fbee640}) at jsobjinlines.h:69
#14 0x0000000101200bb6 in js::ToPrimitive () at jsproxy.cpp:533
#15 0x0000000101200a8d in js::IndirectProxyHandler::defaultValue (this=0x106be40d8, cx=0x10cfa4360, proxy=0x14f2eb080, hint=JSTYPE_VOID, vp=0x7fff5fbeea20) at jsproxy.cpp:531
#16 0x00000001012ee1ef in js::DirectWrapper::defaultValue (this=0x106be40c8, cx=0x10cfa4360, wrapper_=0x14f2eb080, hint=JSTYPE_VOID, vp=0x7fff5fbeea20) at jswrapper.cpp:336
#17 0x00000001012f219e in js::CrossCompartmentWrapper::defaultValue (this=0x106be40c8, cx=0x10cfa4360, wrapper=0x14f2eb080, hint=JSTYPE_VOID, vp=0x7fff5fbeea20) at jswrapper.cpp:829
#18 0x00000001012f2225 in non-virtual thunk to js::CrossCompartmentWrapper::defaultValue(JSContext*, JSObject*, JSType, JS::Value*) () at jswrapper.cpp:832
#19 0x000000010120f648 in js::Proxy::defaultValue (cx=0x10cfa4360, proxy_=0x14f2eb080, hint=JSTYPE_VOID, vp=0x7fff5fbeea20) at jsproxy.cpp:2541
#20 0x000000010120f8b9 in proxy_Convert (cx=0x10cfa4360, proxy={<js::HandleBase<JSObject *>> = {<No data fields>}, ptr = 0x7fff5fbeea38}, hint=JSTYPE_VOID, vp={<js::MutableHandleBase<JS::Value>> = {<js::MutableValueOperations<JS::MutableHandle<JS::Value> >> = {<js::ValueOperations<JS::MutableHandle<JS::Value> >> = {<No data fields>}, <No data fields>}, <No data fields>}, ptr = 0x7fff5fbeea20}) at jsproxy.cpp:2868
#21 0x0000000101050423 in JSObject::defaultValue (cx=0x10cfa4360, obj={<js::HandleBase<JSObject *>> = {<No data fields>}, ptr = 0x7fff5fbeea38}, hint=JSTYPE_VOID, vp={<js::MutableHandleBase<JS::Value>> = {<js::MutableValueOperations<JS::MutableHandle<JS::Value> >> = {<js::ValueOperations<JS::MutableHandle<JS::Value> >> = {<No data fields>}, <No data fields>}, <No data fields>}, ptr = 0x7fff5fbeea20}) at jsobjinlines.h:69
#22 0x0000000101170746 in js::ToPrimitive () at jsinterp.cpp:642
#23 0x0000000101172543 in js::AddOperation (cx=0x10cfa4360, script={<js::HandleBase<JSScript *>> = {<No data fields>}, ptr = 0x7fff5fbf0e30}, pc=0x14ef8f8f7 "\033\f�", lhs=@0x7fff5fbf0918, rhs=@0x7fff5fbf0910, res=0x10def25f0) at jsinterpinlines.h:545
#24 0x000000010116485e in js::Interpret (cx=0x10cfa4360, entryFrame=0x10def24c8, interpMode=js::JSINTERP_NORMAL) at jsinterp.cpp:1985
(gdb) frame 23
#23 0x0000000101172543 in js::AddOperation (cx=0x10cfa4360, script={<js::HandleBase<JSScript *>> = {<No data fields>}, ptr = 0x7fff5fbf0e30}, pc=0x14ef8f8f7 "\033\f�", lhs=@0x7fff5fbf0918, rhs=@0x7fff5fbf0910, res=0x10def25f0) at jsinterpinlines.h:545
545             if (!ToPrimitive(cx, lval.address()))
(gdb) fini
Run till exit from #23 0x0000000101172543 in js::AddOperation (cx=0x10cfa4360, script={<js::HandleBase<JSScript *>> = {<No data fields>}, ptr = 0x7fff5fbf0e30}, pc=0x14ef8f8f7 "\033\f�", lhs=@0x7fff5fbf0918, rhs=@0x7fff5fbf0910, res=0x10def25f0) at jsinterpinlines.h:545
0x000000010116485e in js::Interpret (cx=0x10cfa4360, entryFrame=0x10def24c8, interpMode=js::JSINTERP_NORMAL) at jsinterp.cpp:1985
1985        if (!AddOperation(cx, script, regs.pc, lval, rval, &regs.sp[-2]))
Value returned is $1 = true
(gdb) jsstack 
0 WCF_getObjectClassName() ["resource://gre/modules/devtools/WebConsoleUtils.jsm":780]
    this = [object Object]
1 WCU_getObjectGrip() ["resource://gre/modules/devtools/WebConsoleUtils.jsm":561]
    this = [object Object]
2 WCOA_grip() ["chrome://global/content/devtools/dbg-webconsole-actors.js":879]
    this = [object Object]
3 WCA_createObjectActor() ["chrome://global/content/devtools/dbg-webconsole-actors.js":254]
    this = [object Object]
4 WCU_createValueGrip() ["resource://gre/modules/devtools/WebConsoleUtils.jsm":598]
    this = [object Object]
5 WCA_createValueGrip() ["chrome://global/content/devtools/dbg-webconsole-actors.js":236]
    this = [object Object]
6 WCA_onEvaluateJS() ["chrome://global/content/devtools/dbg-webconsole-actors.js":517]
    this = [object Object]
7 DSC_onPacket() ["chrome://global/content/devtools/dbg-server.js":555]
    this = [object Object]
8 anonymous() ["chrome://global/content/devtools/dbg-transport.js":212]
    this = [object Object]

Does that count?
Though actually, the one that produces the string in the console is the second call, and goes through this JS stack:

(gdb) jsstack 
0 WCU_formatResult() ["resource://gre/modules/devtools/WebConsoleUtils.jsm":245]
    this = [object Object]
1 WCU_getObjectGrip() ["resource://gre/modules/devtools/WebConsoleUtils.jsm":562]
    this = [object Object]
2 WCOA_grip() ["chrome://global/content/devtools/dbg-webconsole-actors.js":879]
    this = [object Object]
3 WCA_createObjectActor() ["chrome://global/content/devtools/dbg-webconsole-actors.js":254]
    this = [object Object]
4 WCU_createValueGrip() ["resource://gre/modules/devtools/WebConsoleUtils.jsm":598]
    this = [object Object]
5 WCA_createValueGrip() ["chrome://global/content/devtools/dbg-webconsole-actors.js":236]
    this = [object Object]
6 WCA_onEvaluateJS() ["chrome://global/content/devtools/dbg-webconsole-actors.js":517]
    this = [object Object]
7 DSC_onPacket() ["chrome://global/content/devtools/dbg-server.js":555]
    this = [object Object]
8 anonymous() ["chrome://global/content/devtools/dbg-transport.js":212]
    this = [object Object]

while the C++ stack is the same.
so that sounds like an INVALID or WONTFIX.
Group: core-security
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.