Here is a code snippet from Window::isSafeScript(const ScriptInterpreter*, const ScriptInterpreter*) in kjs_window.cpp: WebCore::String targetDomain = targetDocument->domain(); // Always allow local pages to execute any JS. if (targetDomain.isNull()) return true; WebCore::String originDomain = originDocument->domain(); // if this document is being initially loaded as empty by its parent // or opener, allow access from any document in the same domain as // the parent or opener. if (shouldLoadAsEmptyDocument(targetFrame->loader()->url())) { Frame* ancestorFrame = targetFrame->loader()->opener() ? targetFrame->loader()->opener() : targetFrame->tree()->parent(); while (ancestorFrame && shouldLoadAsEmptyDocument(ancestorFrame->loader()->url())) ancestorFrame = ancestorFrame->tree()->parent(); if (ancestorFrame) originDomain = ancestorFrame->document()->domain(); } if ( targetDomain == originDomain ) return true; ...... return false; Let's imagine that A is a window displaying www.evil.com, and B is a window displaying www.bank.com. JavaScript code in B opens a new window C of www.bank.com. A plugin in A tries to access DOM objects in C. It has to go through NS_jsObject::_isSafeScript, which eventually invokes Window.isSafeScript(A, C). Window::isSafeScript sets 'originDomain' to A's domain "www.evil.com", and sets "targetDomain" to C's domain "www.bank.com". Then it finds C has an opener B, and it updates "originDomain" to B's domain "www.bank.com". Finally it compares "targetDomain" and "originDomain", and returns true. This will let A access C's DOM object. if (ancestorFrame) originDomain = ancestorFrame->document()->domain(); looks like a typo, it should update "targetDomain" instead of "originDomain" to ancester's domain. I cannot create a test case because I know nothing about scripting plugins. Someone please verify it.
<rdar://problem/5319479>
This is no longer an issue as the plugin same origin check has been merged with the normal one which doesn't suffer from this issue.