Bug 13570
| Summary: | Potential security problem in Window::isSafeScript | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | Feng Qian <ian.eng.webkit> |
| Component: | WebCore JavaScript | Assignee: | Nobody <webkit-unassigned> |
| Status: | RESOLVED FIXED | ||
| Severity: | Normal | CC: | ggaren, mrowe |
| Priority: | P2 | Keywords: | InRadar |
| Version: | 523.x (Safari 3) | ||
| Hardware: | Mac | ||
| OS: | OS X 10.4 | ||
Feng Qian
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.
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
David Kilzer (:ddkilzer)
<rdar://problem/5319479>
Sam Weinig
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.