Changeset 29266 in webkit
- Timestamp:
- Jan 7, 2008, 5:30:27 PM (17 years ago)
- Location:
- trunk
- Files:
-
- 11 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r29257 r29266 1 2008-01-07 Adam Barth <hk9565@gmail.com> 2 3 Reviewed by Sam Weinig. 4 5 Fixes: http://bugs.webkit.org/show_bug.cgi?id=16523 6 7 Adds new LayoutTests for scripting from about:blank windows. These 8 windows should inherit its SecurityOrigin from its opener and should 9 refuse to change their origins when their opener changes exogenously 10 (the navigate-opener tests) or explicitly (the set-opener test). 11 12 * http/tests/security/aboutBlank: Added. 13 * http/tests/security/aboutBlank/xss-DENIED-navigate-opener-document-write-expected.txt: Added. 14 * http/tests/security/aboutBlank/xss-DENIED-navigate-opener-document-write.html: Added. 15 * http/tests/security/aboutBlank/xss-DENIED-navigate-opener-javascript-url-expected.txt: Added. 16 * http/tests/security/aboutBlank/xss-DENIED-navigate-opener-javascript-url.html: Added. 17 * http/tests/security/aboutBlank/xss-DENIED-set-opener-expected.txt: Added. 18 * http/tests/security/aboutBlank/xss-DENIED-set-opener.html: Added. 19 * http/tests/security/resources/innocent-victim-with-notify.html: Added. 20 * http/tests/security/resources/innocent-victim.html: Added. 21 * http/tests/security/resources/libwrapjs.js: Added. 22 * http/tests/security/resources/open-window.html: Added. 23 1 24 2008-01-07 Adele Peterson <adele@apple.com> 2 25 -
trunk/LayoutTests/platform/win/Skipped
r29254 r29266 197 197 http/tests/security/javascriptURL/xss-DENIED-from-javascript-url-in-foreign-domain-window-open.html 198 198 http/tests/security/javascriptURL/xss-DENIED-to-javascript-url-in-foreign-domain-window-open.html 199 http/tests/security/aboutBlank/xss-DENIED-set-opener.html 200 http/tests/security/aboutBlank/xss-DENIED-navigate-opener-document-write.html 201 http/tests/security/aboutBlank/xss-DENIED-navigate-opener-javascript-url.html 199 202 200 203 # DRT is not fully implemented in boomer <rdar://problem/5128261> -
trunk/WebCore/ChangeLog
r29265 r29266 1 2008-01-07 Adam Barth <hk9565@gmail.com> 2 3 Reviewed by Sam Weinig 4 5 Fixes: http://bugs.webkit.org/show_bug.cgi?id=16523 6 <rdar://problem/5657447> 7 8 When a frame is created with the URL "about:blank" or "", it should 9 inherit its SecurityOrigin from its opener. However, once it has 10 decided on that SecurityOrigin, it should not change its mind. 11 Prior to this patch, several events could induce the frame to change 12 its SecurityOrigin, permitting an attacker to inject script into an 13 arbitrary SecurityOrigin. 14 15 This patch makes several changes: 16 17 1) Documents refuse to change from one SecurityOrigin to another 18 unless explicitly instructed to do so. 19 20 2) Navigating to a JavaScript URL that produces a value 21 preserves the current SecurityOrigin explicitly instead of 22 relying on the URL to preserve the origin (which fails for 23 about:blank URLs and SecurityOrigins with document.domain set). 24 25 Ideally, we should not preserve the URL at all. Instead, the 26 frame's URL should be the JavaScript URL, as in Firefox, but this 27 would require changes that are too risky for this patch. I'll 28 file this as a separate issue. 29 30 3) Various methods of navigating to JavaScript URLs were not 31 properly handling JavaScript that returned a value (and should 32 therefore replace the current document). This patch unifies 33 those code paths with the path that works. 34 35 There are still a handful of bugs relating to the handling of 36 JavaScript URLs, but I'll file those as separate issues. 37 38 Tests: http/tests/security/aboutBlank/xss-DENIED-navigate-opener-document-write.html 39 http/tests/security/aboutBlank/xss-DENIED-navigate-opener-javascript-url.html 40 http/tests/security/aboutBlank/xss-DENIED-set-opener.html 41 42 * dom/Document.cpp: 43 (WebCore::Document::initSecurityOrigin): 44 * dom/Document.h: 45 (WebCore::Document::setSecurityOrigin): 46 * loader/FrameLoader.cpp: 47 (WebCore::FrameLoader::changeLocation): 48 (WebCore::FrameLoader::urlSelected): 49 (WebCore::FrameLoader::requestFrame): 50 (WebCore::FrameLoader::submitForm): 51 (WebCore::FrameLoader::executeIfJavaScriptURL): 52 (WebCore::FrameLoader::begin): 53 * loader/FrameLoader.h: 54 * platform/SecurityOrigin.cpp: 55 (WebCore::SecurityOrigin::setForURL): 56 (WebCore::SecurityOrigin::createForFrame): 57 * platform/SecurityOrigin.h: 58 1 59 2008-01-07 Adele Peterson <adele@apple.com> 2 60 -
trunk/WebCore/dom/Document.cpp
r29033 r29266 3717 3717 void Document::initSecurityOrigin() 3718 3718 { 3719 if (m_securityOrigin && !m_securityOrigin->isEmpty()) 3720 return; // m_securityOrigin has already been initialized. 3721 3719 3722 m_securityOrigin = SecurityOrigin::createForFrame(m_frame); 3720 3723 } -
trunk/WebCore/dom/Document.h
r28912 r29266 850 850 SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); } 851 851 852 // Explicitly override the security origin for this document. 853 // Note: It is dangerous to change the security origin of a document 854 // that already contains content. 855 void setSecurityOrigin(SecurityOrigin* o) { m_securityOrigin = o; } 856 852 857 bool processingLoadEvent() const { return m_processingLoadEvent; } 853 858 -
trunk/WebCore/loader/FrameLoader.cpp
r29086 r29266 375 375 void FrameLoader::changeLocation(const KURL& url, const String& referrer, bool lockHistory, bool userGesture) 376 376 { 377 if (url.deprecatedString().find("javascript:", 0, false) == 0) {378 String script = KURL::decode_string(url.deprecatedString().mid(strlen("javascript:")));379 JSValue* result = executeScript(script, userGesture);380 String scriptResult;381 if (getString(result, scriptResult)) {382 begin(m_URL);383 write(scriptResult);384 end();385 }386 return;387 }388 389 377 ResourceRequestCachePolicy policy = (m_cachePolicy == CachePolicyReload) || (m_cachePolicy == CachePolicyRefresh) 390 378 ? ReloadIgnoringCacheData : UseProtocolCachePolicy; … … 396 384 void FrameLoader::urlSelected(const ResourceRequest& request, const String& _target, Event* triggeringEvent, bool lockHistory, bool userGesture) 397 385 { 386 if (executeIfJavaScriptURL(request.url(), userGesture)) 387 return; 388 398 389 String target = _target; 399 390 if (target.isEmpty() && m_frame->document()) 400 391 target = m_frame->document()->baseTarget(); 401 402 const KURL& url = request.url();403 if (url.deprecatedString().startsWith("javascript:", false)) {404 executeScript(KURL::decode_string(url.deprecatedString().mid(strlen("javascript:"))), true);405 return;406 }407 392 408 393 FrameLoadRequest frameRequest(request, target); … … 443 428 444 429 if (!scriptURL.isEmpty()) 445 frame->loader()-> replaceContentsWithScriptResult(scriptURL);430 frame->loader()->executeIfJavaScriptURL(scriptURL); 446 431 447 432 return true; … … 519 504 if (urlString.startsWith("javascript:", false)) { 520 505 m_isExecutingJavaScriptFormAction = true; 521 execute Script(KURL::decode_string(urlString.mid(strlen("javascript:"))));506 executeIfJavaScriptURL(u); 522 507 m_isExecutingJavaScriptFormAction = false; 523 508 return; … … 728 713 } 729 714 730 void FrameLoader::replaceContentsWithScriptResult(const KURL& url) 731 { 732 JSValue* result = executeScript(KURL::decode_string(url.deprecatedString().mid(strlen("javascript:")))); 715 bool FrameLoader::executeIfJavaScriptURL(const KURL& url, bool userGesture) 716 { 717 if (!url.deprecatedString().startsWith("javascript:", false)) 718 return false; 719 720 String script = KURL::decode_string(url.deprecatedString().mid(strlen("javascript:"))); 721 JSValue* result = executeScript(script, userGesture); 722 733 723 String scriptResult; 734 724 if (!getString(result, scriptResult)) 735 return; 736 begin(); 725 return true; 726 727 SecurityOrigin* currentSecurityOrigin = 0; 728 if (m_frame->document()) 729 currentSecurityOrigin = m_frame->document()->securityOrigin(); 730 731 begin(m_URL, true, currentSecurityOrigin); 737 732 write(scriptResult); 738 733 end(); 734 735 return true; 739 736 } 740 737 … … 875 872 } 876 873 877 void FrameLoader::begin(const KURL& url, bool dispatch) 878 { 874 void FrameLoader::begin(const KURL& url, bool dispatch, SecurityOrigin* origin) 875 { 876 // We need to take a reference to the security origin because |clear| 877 // might destroy the document that owns it. 878 RefPtr<SecurityOrigin> forcedSecurityOrigin = origin; 879 879 880 bool resetScripting = !(m_isDisplayingInitialEmptyDocument && m_frame->document() && m_frame->document()->securityOrigin()->isSecureTransitionTo(url)); 880 881 clear(resetScripting, resetScripting); … … 908 909 if (m_decoder) 909 910 document->setDecoder(m_decoder.get()); 911 if (forcedSecurityOrigin) 912 document->setSecurityOrigin(forcedSecurityOrigin.get()); 910 913 911 914 updatePolicyBaseURL(); -
trunk/WebCore/loader/FrameLoader.h
r28639 r29266 76 76 class ResourceRequest; 77 77 class ResourceResponse; 78 class SecurityOrigin; 78 79 class SharedBuffer; 79 80 class SubstituteData; … … 310 311 311 312 void begin(); 312 void begin(const KURL&, bool dispatchWindowObjectAvailable = true );313 void begin(const KURL&, bool dispatchWindowObjectAvailable = true, SecurityOrigin* forcedSecurityOrigin = 0); 313 314 314 315 void write(const char* str, int len = -1, bool flush = false); … … 319 320 void setEncoding(const String& encoding, bool userChosen); 320 321 String encoding() const; 322 323 // Returns true if url is a JavaScript URL. 324 bool executeIfJavaScriptURL(const KURL& url, bool userGesture = false); 321 325 322 326 KJS::JSValue* executeScript(const String& url, int baseLine, const String& script); … … 477 481 void setPolicyBaseURL(const String&); 478 482 479 void replaceContentsWithScriptResult(const KURL&);480 481 483 // Also not cool. 482 484 void stopLoadingSubframes(); -
trunk/WebCore/platform/SecurityOrigin.cpp
r28912 r29266 40 40 namespace WebCore { 41 41 42 SecurityOrigin::SecurityOrigin( )42 SecurityOrigin::SecurityOrigin(const KURL& url) 43 43 : m_port(0) 44 44 , m_portSet(false) … … 46 46 , m_domainWasSetInDOM(false) 47 47 { 48 } 48 if (url.isEmpty()) 49 return; 49 50 50 void SecurityOrigin::clear() 51 { 52 m_protocol = String(); 53 m_host = String(); 54 m_port = 0; 55 m_portSet = false; 56 m_noAccess = false; 57 m_domainWasSetInDOM = false; 51 m_protocol = url.protocol().lower(); 52 53 // These protocols do not represent principals. 54 if (m_protocol == "about" || m_protocol == "javascript") 55 m_protocol = String(); 56 57 if (m_protocol.isEmpty()) 58 return; 59 60 // data: URLs are not allowed access to anything other than themselves. 61 if (m_protocol == "data") 62 m_noAccess = true; 63 64 m_host = url.host().lower(); 65 m_port = url.port(); 66 67 if (m_port) 68 m_portSet = true; 58 69 } 59 70 … … 63 74 } 64 75 65 void SecurityOrigin::setForURL(const KURL& url)66 {67 clear();68 69 if (url.isEmpty())70 return;71 72 m_protocol = url.protocol().lower();73 m_host = url.host().lower();74 m_port = url.port();75 76 if (m_port)77 m_portSet = true;78 79 // data: URLs are not allowed access to anything other than themselves.80 if (m_protocol == "data")81 m_noAccess = true;82 }83 84 76 PassRefPtr<SecurityOrigin> SecurityOrigin::createForFrame(Frame* frame) 85 77 { 86 RefPtr<SecurityOrigin> origin = new SecurityOrigin(); 78 if (!frame) 79 return new SecurityOrigin(KURL()); 87 80 88 if (!frame) 81 FrameLoader* loader = frame->loader(); 82 83 RefPtr<SecurityOrigin> origin = new SecurityOrigin(loader->url()); 84 if (!origin->isEmpty()) 89 85 return origin; 90 86 91 FrameLoader* loader = frame->loader(); 92 const KURL& securityPolicyURL = loader->url(); 93 94 origin->setForURL(securityPolicyURL); 95 96 if (!origin->isEmpty() && origin->m_protocol != "about") 97 return origin; 98 99 // In the case of about:blank or javascript: URLs (which create 100 // documents using the "about" protocol) do we want to use the 101 // parent or openers origin. 87 // If we do not obtain a principal from the URL, then we try to find a 88 // principal via the frame hierarchy. 102 89 103 90 Frame* openerFrame = frame->tree()->parent(); -
trunk/WebCore/platform/SecurityOrigin.h
r28912 r29266 51 51 bool isSecureTransitionTo(const KURL&) const; 52 52 53 bool isEmpty() const; 53 54 String toString() const; 54 55 … … 56 57 57 58 private: 58 SecurityOrigin(); 59 bool isEmpty() const; 60 61 void clear(); 62 void setForURL(const KURL& url); 59 SecurityOrigin(const KURL& url); 63 60 64 61 String m_protocol;
Note:
See TracChangeset
for help on using the changeset viewer.