Changeset 32791 in webkit
- Timestamp:
- May 1, 2008 7:08:43 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r32785 r32791 1 2008-05-01 Sam Weinig <sam@webkit.org> 2 3 Reviewed by Geoffrey Garen. 4 5 * http/tests/security/listener/xss-JSTargetNode-onclick-addEventListener-expected.txt: 6 * http/tests/security/listener/xss-JSTargetNode-onclick-shortcut-expected.txt: 7 * http/tests/security/listener/xss-XMLHttpRequest-addEventListener-expected.txt: 8 * http/tests/security/listener/xss-XMLHttpRequest-shortcut-expected.txt: 9 * http/tests/security/listener/xss-window-onclick-addEventListener-expected.txt: 10 * http/tests/security/listener/xss-window-onclick-shortcut-expected.txt: 11 * http/tests/security/xss-eval-expected.txt: 12 1 13 2008-05-01 Anders Carlsson <andersca@apple.com> 2 14 -
trunk/LayoutTests/http/tests/security/listener/xss-JSTargetNode-onclick-addEventListener-expected.txt
r25249 r32791 1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe.html from frame with URL http://127.0.0.1:8000/security/listener/resources/ childWithButton.html. Domains, protocols and ports must match.1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe.html from frame with URL http://127.0.0.1:8000/security/listener/resources/targetChild-JSTargetNode-onclick-addEventListener.html. Domains, protocols and ports must match. 2 2 3 3 CONSOLE MESSAGE: line 6: Value undefined (result of expression alert) is not object. -
trunk/LayoutTests/http/tests/security/listener/xss-JSTargetNode-onclick-shortcut-expected.txt
r25249 r32791 1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe.html from frame with URL http://127.0.0.1:8000/security/listener/resources/ childWithButton.html. Domains, protocols and ports must match.1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe.html from frame with URL http://127.0.0.1:8000/security/listener/resources/targetChild-JSTargetNode-onclick-shortcut.html. Domains, protocols and ports must match. 2 2 3 3 CONSOLE MESSAGE: line 6: Value undefined (result of expression alert) is not object. -
trunk/LayoutTests/http/tests/security/listener/xss-XMLHttpRequest-addEventListener-expected.txt
r25284 r32791 1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe.html from frame with URL http://127.0.0.1:8000/security/listener/resources/ childWithXMLHttpRequest.html. Domains, protocols and ports must match.1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe.html from frame with URL http://127.0.0.1:8000/security/listener/resources/targetChild-XMLHttpRequest-addEventListener.html. Domains, protocols and ports must match. 2 2 3 3 CONSOLE MESSAGE: line 6: Value undefined (result of expression alert) is not object. -
trunk/LayoutTests/http/tests/security/listener/xss-XMLHttpRequest-shortcut-expected.txt
r25284 r32791 1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe.html from frame with URL http://127.0.0.1:8000/security/listener/resources/ childWithXMLHttpRequest.html. Domains, protocols and ports must match.1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe.html from frame with URL http://127.0.0.1:8000/security/listener/resources/targetChild-XMLHttpRequest-shortcut.html. Domains, protocols and ports must match. 2 2 3 3 CONSOLE MESSAGE: line 6: Value undefined (result of expression alert) is not object. -
trunk/LayoutTests/http/tests/security/listener/xss-window-onclick-addEventListener-expected.txt
r25249 r32791 1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe.html from frame with URL http://127.0.0.1:8000/security/listener/resources/ childWindow.html. Domains, protocols and ports must match.1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe.html from frame with URL http://127.0.0.1:8000/security/listener/resources/targetChild-window-onclick-addEventListener.html. Domains, protocols and ports must match. 2 2 3 3 CONSOLE MESSAGE: line 6: Value undefined (result of expression alert) is not object. -
trunk/LayoutTests/http/tests/security/listener/xss-window-onclick-shortcut-expected.txt
r25249 r32791 1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe.html from frame with URL http://127.0.0.1:8000/security/listener/resources/ childWindow.html. Domains, protocols and ports must match.1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe.html from frame with URL http://127.0.0.1:8000/security/listener/resources/targetChild-window-onclick-shortcut.html. Domains, protocols and ports must match. 2 2 3 3 CONSOLE MESSAGE: line 6: Value undefined (result of expression alert) is not object. -
trunk/LayoutTests/http/tests/security/xss-eval-expected.txt
r30871 r32791 1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/xss-eval3.html from frame with URL http://127.0.0.1:8000/security/ xss-eval.html. Domains, protocols and ports must match.1 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/xss-eval3.html from frame with URL http://127.0.0.1:8000/security/resources/xss-eval2.html. Domains, protocols and ports must match. 2 2 3 3 This page verifies that you can't use eval to subvert cross-domain checks. -
trunk/WebCore/ChangeLog
r32790 r32791 1 2008-05-01 Sam Weinig <sam@webkit.org> 2 3 Reviewed by Geoffrey Garen. 4 5 Fixes: 6 - https://bugs.webkit.org/show_bug.cgi?id=17249 7 Incorrect lexical scope after navigation leads to UXSS 8 <rdar://problem/5738497> 9 10 - https://bugs.webkit.org/show_bug.cgi?id=16824 11 Script authorization should follow lexical (not dynamic) scope 12 <rdar://problem/5683032> 13 14 This patch changes us to perform same-origin checks based on the lexical global object) 15 rather than dynamic global object, which is now possible we don't re-use the window on 16 navigations, but rather switch in a new one and re-use the outer shell. This is both 17 more secure and conforms with the HTML5 specification. Now that all the checks are 18 done based on the lexical global object, we can remove the SecurityOrigin::Reason 19 concept, as it was only around to work around an ebay.com bug that required the check to 20 be done that way. 21 22 An important thing to note is that we currently implement a stricter than necessary policy 23 and perform the same-origin check based on the currently active global object to avoid leaking 24 the document in cases when the target frame is navigated before access. This will be fixed in 25 an upcoming patch. 26 27 * bindings/js/JSDOMWindowBase.cpp: 28 (WebCore::JSDOMWindowBase::allowsAccessFrom): 29 (WebCore::JSDOMWindowBase::allowsAccessFromNoErrorMessage): 30 (WebCore::JSDOMWindowBase::allowsAccessFromPrivate): 31 (WebCore::JSDOMWindowBase::crossDomainAccessErrorMessage): 32 (WebCore::JSDOMWindowBase::printErrorMessage): 33 (WebCore::asJSDOMWindow): 34 * bindings/js/JSDOMWindowBase.h: 35 * html/CanvasRenderingContext2D.cpp: 36 (WebCore::CanvasRenderingContext2D::checkOrigin): 37 (WebCore::CanvasRenderingContext2D::createPattern): 38 * loader/FrameLoader.cpp: 39 (WebCore::FrameLoader::begin): 40 (WebCore::FrameLoader::write): 41 (WebCore::FrameLoader::setOpener): 42 (WebCore::FrameLoader::shouldAllowNavigation): 43 * page/DOMWindow.h: 44 (WebCore::DOMWindow::setSecurityOrigin): 45 (WebCore::DOMWindow::securityOrigin): 46 (WebCore::DOMWindow::setURL): 47 (WebCore::DOMWindow::url): 48 * platform/SecurityOrigin.cpp: 49 (WebCore::SecurityOrigin::canAccess): 50 (WebCore::SecurityOrigin::isSecureTransitionTo): 51 * platform/SecurityOrigin.h: 52 1 53 2008-05-01 Anders Carlsson <andersca@apple.com> 2 54 -
trunk/WebCore/bindings/js/JSDOMWindowBase.cpp
r32786 r32791 734 734 bool JSDOMWindowBase::allowsAccessFrom(const JSGlobalObject* other) const 735 735 { 736 SecurityOrigin::Reason reason; 737 if (allowsAccessFromPrivate(other, reason)) 736 if (allowsAccessFromPrivate(other)) 738 737 return true; 739 printErrorMessage(crossDomainAccessErrorMessage(other , reason));738 printErrorMessage(crossDomainAccessErrorMessage(other)); 740 739 return false; 741 740 } … … 743 742 bool JSDOMWindowBase::allowsAccessFrom(ExecState* exec) const 744 743 { 745 SecurityOrigin::Reason reason; 746 if (allowsAccessFromPrivate(exec, reason)) 744 if (allowsAccessFromPrivate(exec->lexicalGlobalObject())) 747 745 return true; 748 printErrorMessage(crossDomainAccessErrorMessage(exec-> dynamicGlobalObject(), reason));746 printErrorMessage(crossDomainAccessErrorMessage(exec->lexicalGlobalObject())); 749 747 return false; 750 748 } … … 752 750 bool JSDOMWindowBase::allowsAccessFromNoErrorMessage(ExecState* exec) const 753 751 { 754 SecurityOrigin::Reason reason; 755 return allowsAccessFromPrivate(exec, reason); 752 return allowsAccessFromPrivate(exec->lexicalGlobalObject()); 756 753 } 757 754 758 755 bool JSDOMWindowBase::allowsAccessFrom(ExecState* exec, String& message) const 759 756 { 760 SecurityOrigin::Reason reason; 761 if (allowsAccessFromPrivate(exec, reason)) 757 if (allowsAccessFromPrivate(exec->lexicalGlobalObject())) 762 758 return true; 763 message = crossDomainAccessErrorMessage(exec-> dynamicGlobalObject(), reason);759 message = crossDomainAccessErrorMessage(exec->lexicalGlobalObject()); 764 760 return false; 765 761 } 766 762 767 ALWAYS_INLINE bool JSDOMWindowBase::allowsAccessFromPrivate(const ExecState* exec, SecurityOrigin::Reason& reason) const 768 { 769 if (allowsAccessFromPrivate(exec->dynamicGlobalObject(), reason)) 763 ALWAYS_INLINE bool JSDOMWindowBase::allowsAccessFromPrivate(const JSGlobalObject* other) const 764 { 765 const JSDOMWindow* originWindow = asJSDOMWindow(other); 766 const JSDOMWindow* targetWindow = toJSDOMWindow(impl()->frame()); 767 768 if (originWindow == targetWindow) 770 769 return true; 771 if (reason == SecurityOrigin::DomainSetInDOMMismatch) {772 // If the only reason the access failed was a domainSetInDOM bit mismatch, try again against773 // lexical global object <rdar://problem/5698200>774 if (allowsAccessFromPrivate(exec->lexicalGlobalObject(), reason))775 return true;776 }777 return false;778 }779 780 ALWAYS_INLINE bool JSDOMWindowBase::allowsAccessFromPrivate(const JSGlobalObject* other, SecurityOrigin::Reason& reason) const781 {782 const Frame* originFrame = static_cast<const JSDOMWindowBase*>(other)->impl()->frame();783 if (!originFrame) {784 reason = SecurityOrigin::GenericMismatch;785 return false;786 }787 788 const Frame* targetFrame = impl()->frame();789 790 if (originFrame == targetFrame)791 return true;792 793 if (!targetFrame) {794 reason = SecurityOrigin::GenericMismatch;795 return false;796 }797 798 Document* targetDocument = targetFrame->document();799 770 800 771 // JS may be attempting to access the "window" object, which should be valid, 801 772 // even if the document hasn't been constructed yet. If the document doesn't 802 773 // exist yet allow JS to access the window object. 803 if (! targetDocument)774 if (!originWindow->impl()->document()) 804 775 return true; 805 776 806 Document* originDocument = originFrame->document(); 807 808 const SecurityOrigin* originSecurityOrigin = originDocument->securityOrigin(); 809 const SecurityOrigin* targetSecurityOrigin = targetDocument->securityOrigin(); 810 811 if (originSecurityOrigin->canAccess(targetSecurityOrigin, reason)) 812 return true; 813 814 return false; 815 } 816 817 String JSDOMWindowBase::crossDomainAccessErrorMessage(const JSGlobalObject* other, SecurityOrigin::Reason) const 818 { 819 const Frame* originFrame = static_cast<const JSDOMWindowBase*>(other)->impl()->frame(); 820 const Frame* targetFrame = impl()->frame(); 821 if (!originFrame || !targetFrame) 777 const SecurityOrigin* originSecurityOrigin = originWindow->impl()->securityOrigin(); 778 const SecurityOrigin* targetSecurityOrigin = targetWindow->impl()->securityOrigin(); 779 780 return originSecurityOrigin->canAccess(targetSecurityOrigin); 781 } 782 783 String JSDOMWindowBase::crossDomainAccessErrorMessage(const JSGlobalObject* other) const 784 { 785 KURL originURL = asJSDOMWindow(other)->impl()->url(); 786 KURL targetURL = impl()->frame()->document()->url(); 787 if (originURL.isNull() || targetURL.isNull()) 822 788 return String(); 823 Document* targetDocument = targetFrame->document(); 824 Document* originDocument = originFrame->document(); 825 if (!originDocument || !targetDocument) 826 return String(); 789 827 790 // FIXME: this error message should contain more specifics of why the same origin check has failed. 828 791 return String::format("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains, protocols and ports must match.\n", 829 target Document->url().string().utf8().data(), originDocument->url().string().utf8().data());792 targetURL.string().utf8().data(), originURL.string().utf8().data()); 830 793 } 831 794 … … 845 808 printf("%s", message.utf8().data()); 846 809 847 frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, message, 1, String()); // FIXME: provide a real line number and source URL.810 impl()->console()->addMessage(JSMessageSource, ErrorMessageLevel, message, 1, String()); // FIXME: provide a real line number and source URL. 848 811 } 849 812 … … 1427 1390 } 1428 1391 1392 const JSDOMWindow* asJSDOMWindow(const JSGlobalObject* globalObject) 1393 { 1394 return static_cast<const JSDOMWindow*>(globalObject); 1395 } 1396 1429 1397 } // namespace WebCore -
trunk/WebCore/bindings/js/JSDOMWindowBase.h
r32786 r32791 22 22 23 23 #include "PlatformString.h" 24 #include "SecurityOrigin.h"25 24 #include "kjs_binding.h" 26 25 #include <kjs/protect.h> … … 41 40 class PausedTimeouts; 42 41 class ScheduledAction; 42 class SecurityOrigin; 43 43 44 44 class JSDOMWindowBasePrivate; … … 149 149 int installTimeout(ScheduledAction*, int interval, bool singleShot); 150 150 151 bool allowsAccessFromPrivate(const KJS::JSGlobalObject*, SecurityOrigin::Reason&) const; 152 bool allowsAccessFromPrivate(const KJS::ExecState*, SecurityOrigin::Reason&) const; 153 String crossDomainAccessErrorMessage(const KJS::JSGlobalObject*, SecurityOrigin::Reason) const; 151 bool allowsAccessFromPrivate(const KJS::JSGlobalObject*) const; 152 String crossDomainAccessErrorMessage(const KJS::JSGlobalObject*) const; 154 153 155 154 RefPtr<DOMWindow> m_impl; … … 176 175 177 176 JSDOMWindow* asJSDOMWindow(KJS::JSGlobalObject*); 177 const JSDOMWindow* asJSDOMWindow(const KJS::JSGlobalObject*); 178 178 179 179 } // namespace WebCore -
trunk/WebCore/html/CanvasRenderingContext2D.cpp
r32700 r32791 946 946 { 947 947 RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url); 948 SecurityOrigin::Reason reason; 949 if (!m_canvas->document()->securityOrigin()->canAccess(origin.get(), reason)) 948 if (!m_canvas->document()->securityOrigin()->canAccess(origin.get())) 950 949 m_canvas->setOriginTainted(); 951 950 } … … 1098 1097 KURL url(cachedImage->url()); 1099 1098 RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url); 1100 SecurityOrigin::Reason reason; 1101 originClean = m_canvas->document()->securityOrigin()->canAccess(origin.get(), reason); 1099 originClean = m_canvas->document()->securityOrigin()->canAccess(origin.get()); 1102 1100 } 1103 1101 return new CanvasPattern(image->cachedImage(), repeatX, repeatY, originClean); -
trunk/WebCore/loader/FrameLoader.cpp
r32666 r32791 938 938 document->setSecurityOrigin(forcedSecurityOrigin.get()); 939 939 940 m_frame->domWindow()->setURL(document->url()); 941 m_frame->domWindow()->setSecurityOrigin(document->securityOrigin()); 942 940 943 updatePolicyBaseURL(); 941 944 … … 989 992 if (m_encoding.isEmpty()) { 990 993 Frame* parentFrame = m_frame->tree()->parent(); 991 SecurityOrigin::Reason reason; 992 if (parentFrame && parentFrame->document()->securityOrigin()->canAccess(m_frame->document()->securityOrigin(), reason)) 994 if (parentFrame && parentFrame->document()->securityOrigin()->canAccess(m_frame->document()->securityOrigin())) 993 995 m_decoder->setEncoding(parentFrame->document()->inputEncoding(), TextResourceDecoder::DefaultEncoding); 994 996 } else { … … 1773 1775 m_opener = opener; 1774 1776 1775 if (m_frame->document()) 1777 if (m_frame->document()) { 1776 1778 m_frame->document()->initSecurityOrigin(); 1779 m_frame->domWindow()->setSecurityOrigin(m_frame->document()->securityOrigin()); 1780 } 1777 1781 } 1778 1782 … … 2445 2449 return true; 2446 2450 2447 SecurityOrigin::Reason reason;2448 2451 const SecurityOrigin* ancestorSecurityOrigin = ancestorDocument->securityOrigin(); 2449 if (activeSecurityOrigin->canAccess(ancestorSecurityOrigin , reason))2452 if (activeSecurityOrigin->canAccess(ancestorSecurityOrigin)) 2450 2453 return true; 2451 2454 } -
trunk/WebCore/page/DOMWindow.h
r32597 r32791 27 27 #define DOMWindow_h 28 28 29 #include "KURL.h" 29 30 #include "PlatformString.h" 31 #include "SecurityOrigin.h" 32 #include <wtf/Forward.h> 30 33 #include <wtf/RefCounted.h> 31 #include <wtf/Forward.h>32 34 #include <wtf/RefPtr.h> 33 35 … … 68 70 69 71 void clear(); 72 73 void setSecurityOrigin(SecurityOrigin* securityOrigin) { m_securityOrigin = securityOrigin; } 74 SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); } 75 76 void setURL(const KURL& url) { m_url = url; } 77 KURL url() const { return m_url; } 70 78 71 79 static void adjustWindowRect(const FloatRect& screen, FloatRect& window, const FloatRect& pendingChanges); … … 200 208 DOMApplicationCache* optionalApplicationCache() const { return m_applicationCache.get(); } 201 209 #endif 202 210 203 211 private: 204 212 DOMWindow(Frame*); 205 213 214 RefPtr<SecurityOrigin> m_securityOrigin; 215 KURL m_url; 216 206 217 Frame* m_frame; 207 218 mutable RefPtr<Screen> m_screen; -
trunk/WebCore/platform/SecurityOrigin.cpp
r32597 r32791 136 136 } 137 137 138 bool SecurityOrigin::canAccess(const SecurityOrigin* other , Reason& reason) const138 bool SecurityOrigin::canAccess(const SecurityOrigin* other) const 139 139 { 140 140 if (FrameLoader::shouldTreatSchemeAsLocal(m_protocol)) 141 141 return true; 142 142 143 if (m_noAccess || other->m_noAccess) { 144 reason = SecurityOrigin::GenericMismatch; 145 return false; 146 } 143 if (m_noAccess || other->m_noAccess) 144 return false; 147 145 148 146 // Here are three cases where we should permit access: … … 179 177 return true; 180 178 } else { 181 if (m_host == other->m_host && m_port == other->m_port) { 182 reason = DomainSetInDOMMismatch; 179 if (m_host == other->m_host && m_port == other->m_port) 183 180 return false; 184 }185 181 } 186 182 } 187 183 188 reason = SecurityOrigin::GenericMismatch;189 184 return false; 190 185 } … … 197 192 198 193 RefPtr<SecurityOrigin> other = SecurityOrigin::create(url); 199 Reason reason; 200 return canAccess(other.get(), reason); 194 return canAccess(other.get()); 201 195 } 202 196 -
trunk/WebCore/platform/SecurityOrigin.h
r32597 r32791 55 55 String domain() const { return m_domain; } 56 56 unsigned short port() const { return m_port; } 57 58 enum Reason { 59 GenericMismatch, 60 DomainSetInDOMMismatch 61 }; 62 bool canAccess(const SecurityOrigin*, Reason&) const; 57 58 bool canAccess(const SecurityOrigin*) const; 63 59 bool isSecureTransitionTo(const KURL&) const; 64 60
Note: See TracChangeset
for help on using the changeset viewer.