Changeset 37317 in webkit
- Timestamp:
- Oct 5, 2008 12:12:30 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 30 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r37315 r37317 1 2008-10-05 Adam Barth <abarth@webkit.org> 2 3 Reviewed by Darin Adler. 4 5 Tests for the new Origin header. 6 7 https://bugs.webkit.org/show_bug.cgi?id=20792 8 9 Collin Jackson <collinj@webkit.org> also contributed to this patch. 10 11 * http/tests/security/originHeader: Added. 12 * http/tests/security/originHeader/origin-header-for-data-expected.txt: Added. 13 * http/tests/security/originHeader/origin-header-for-data.html: Added. 14 * http/tests/security/originHeader/origin-header-for-empty-expected.txt: Added. 15 * http/tests/security/originHeader/origin-header-for-empty.html: Added. 16 * http/tests/security/originHeader/origin-header-for-get-expected.txt: Added. 17 * http/tests/security/originHeader/origin-header-for-get.html: Added. 18 * http/tests/security/originHeader/origin-header-for-https-expected.txt: Added. 19 * http/tests/security/originHeader/origin-header-for-https.html: Added. 20 * http/tests/security/originHeader/origin-header-for-post-expected.txt: Added. 21 * http/tests/security/originHeader/origin-header-for-post.html: Added. 22 * http/tests/security/originHeader/origin-header-for-xmlhttprequest-expected.txt: Added. 23 * http/tests/security/originHeader/origin-header-for-xmlhttprequest.html: Added. 24 * http/tests/security/originHeader/resources: Added. 25 * http/tests/security/originHeader/resources/origin-header-post-to-http.html: Added. 26 * http/tests/security/originHeader/resources/print-origin.cgi: Added. 27 1 28 2008-10-05 Oliver Hunt <oliver@apple.com> 2 29 -
trunk/WebCore/ChangeLog
r37315 r37317 1 2008-10-05 Adam Barth <abarth@webkit.org> 2 3 Reviewed by Darin Alder. 4 5 Attach the Origin header to POST requests to help defend against 6 cross-site request forgery. 7 8 https://bugs.webkit.org/show_bug.cgi?id=20792 9 10 Collin Jackson <collinj@webkit.org> also contributed to this patch. 11 12 Tests: http/tests/security/originHeader/origin-header-for-data.html 13 http/tests/security/originHeader/origin-header-for-empty.html 14 http/tests/security/originHeader/origin-header-for-get.html 15 http/tests/security/originHeader/origin-header-for-https.html 16 http/tests/security/originHeader/origin-header-for-post.html 17 18 * bindings/js/JSDOMWindowBase.cpp: 19 (WebCore::createWindow): 20 * loader/FrameLoader.cpp: 21 (WebCore::FrameLoader::createWindow): 22 (WebCore::FrameLoader::urlSelected): 23 (WebCore::FrameLoader::submitForm): 24 (WebCore::FrameLoader::outgoingOrigin): 25 (WebCore::FrameLoader::loadURL): 26 (WebCore::FrameLoader::addExtraFieldsToRequest): 27 (WebCore::FrameLoader::loadPostRequest): 28 (WebCore::FrameLoader::loadResourceSynchronously): 29 (WebCore::FrameLoader::loadItem): 30 * loader/FrameLoader.h: 31 * loader/SubresourceLoader.cpp: 32 (WebCore::SubresourceLoader::create): 33 * loader/loader.cpp: 34 (WebCore::Loader::Host::servePendingRequests): 35 * platform/SecurityOrigin.cpp: 36 (WebCore::SecurityOrigin::toHTTPOrigin): 37 * platform/SecurityOrigin.h: 38 * platform/network/ResourceRequestBase.h: 39 (WebCore::ResourceRequestBase::httpOrigin): 40 (WebCore::ResourceRequestBase::setHTTPOrigin): 41 (WebCore::ResourceRequestBase::clearHTTPOrigin): 42 * xml/XMLHttpRequest.cpp: 43 (WebCore::XMLHttpRequest::makeSimpleCrossSiteAccessRequest): 44 (WebCore::XMLHttpRequest::makeCrossSiteAccessRequestWithPreflight): 45 (WebCore::XMLHttpRequest::handleAsynchronousPreflightResult): 46 (WebCore::XMLHttpRequest::didReceiveResponsePreflight): 47 1 48 2008-10-04 Oliver Hunt <oliver@apple.com> 2 49 -
trunk/WebCore/bindings/js/JSDOMWindowBase.cpp
r37257 r37317 273 273 274 274 request.setHTTPReferrer(activeFrame->loader()->outgoingReferrer()); 275 FrameLoader::addHTTPOriginIfNeeded(request, activeFrame->loader()->outgoingOrigin()); 275 276 FrameLoadRequest frameRequest(request, frameName); 276 277 -
trunk/WebCore/loader/FrameLoader.cpp
r37112 r37317 331 331 FrameLoadRequest requestWithReferrer = request; 332 332 requestWithReferrer.resourceRequest().setHTTPReferrer(m_outgoingReferrer); 333 addHTTPOriginIfNeeded(requestWithReferrer.resourceRequest(), outgoingOrigin()); 333 334 334 335 Page* oldPage = m_frame->page(); … … 400 401 if (copy.resourceRequest().httpReferrer().isEmpty()) 401 402 copy.resourceRequest().setHTTPReferrer(m_outgoingReferrer); 403 addHTTPOriginIfNeeded(copy.resourceRequest(), outgoingOrigin()); 402 404 403 405 loadFrameRequestWithFormAndValues(copy, lockHistory, event, 0, HashMap<String, String>()); … … 575 577 576 578 frameRequest.resourceRequest().setURL(u); 579 addHTTPOriginIfNeeded(frameRequest.resourceRequest(), outgoingOrigin()); 577 580 578 581 submitForm(frameRequest, event); … … 1783 1786 { 1784 1787 return m_outgoingReferrer; 1788 } 1789 1790 String FrameLoader::outgoingOrigin() const 1791 { 1792 if (m_frame->document()) 1793 return m_frame->document()->securityOrigin()->toHTTPOrigin(); 1794 1795 return SecurityOrigin::createEmpty()->toHTTPOrigin(); 1785 1796 } 1786 1797 … … 2125 2136 2126 2137 ResourceRequest request(newURL); 2127 if (!referrer.isEmpty()) 2138 if (!referrer.isEmpty()) { 2128 2139 request.setHTTPReferrer(referrer); 2140 RefPtr<SecurityOrigin> referrerOrigin = SecurityOrigin::createFromString(referrer); 2141 addHTTPOriginIfNeeded(request, referrerOrigin->toHTTPOrigin()); 2142 } 2129 2143 addExtraFieldsToRequest(request, true, event || isFormSubmission); 2130 2144 if (newLoadType == FrameLoadTypeReload) … … 3406 3420 if (mainResource) 3407 3421 request.setHTTPAccept("application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); 3422 3423 // Make sure we send the Origin header. 3424 addHTTPOriginIfNeeded(request, String()); 3425 } 3426 3427 void FrameLoader::addHTTPOriginIfNeeded(ResourceRequest& request, String origin) 3428 { 3429 if (!request.httpOrigin().isEmpty()) 3430 return; // Request already has an Origin header. 3431 3432 // Don't send an Origin header for GET or HEAD to avoid privacy issues. 3433 // For example, if an intranet page has a hyperlink to an external web 3434 // site, we don't want to include the Origin of the request because it 3435 // will leak the internal host name. Similar privacy concerns have lead 3436 // to the widespread suppression of the Referer header at the network 3437 // layer. 3438 if (request.httpMethod() == "GET" || request.httpMethod() == "HEAD") 3439 return; 3440 3441 // For non-GET and non-HEAD methods, always send an Origin header so the 3442 // server knows we support this feature. 3443 3444 if (origin.isEmpty()) { 3445 // If we don't know what origin header to attach, we attach the value 3446 // for an empty origin. 3447 origin = SecurityOrigin::createEmpty()->toHTTPOrigin(); 3448 } 3449 3450 request.setHTTPOrigin(origin); 3408 3451 } 3409 3452 … … 3433 3476 RefPtr<FormData> formData = inRequest.httpBody(); 3434 3477 const String& contentType = inRequest.httpContentType(); 3478 String origin = inRequest.httpOrigin(); 3435 3479 3436 3480 ResourceRequest workingResourceRequest(url); 3437 addExtraFieldsToRequest(workingResourceRequest, true, true);3438 3481 3439 3482 if (!referrer.isEmpty()) 3440 3483 workingResourceRequest.setHTTPReferrer(referrer); 3484 workingResourceRequest.setHTTPOrigin(origin); 3441 3485 workingResourceRequest.setHTTPMethod("POST"); 3442 3486 workingResourceRequest.setHTTPBody(formData); 3443 3487 workingResourceRequest.setHTTPContentType(contentType); 3488 addExtraFieldsToRequest(workingResourceRequest, true, true); 3444 3489 3445 3490 NavigationAction action(url, FrameLoadTypeStandard, true, event); … … 3483 3528 if (!referrer.isEmpty()) 3484 3529 initialRequest.setHTTPReferrer(referrer); 3530 addHTTPOriginIfNeeded(initialRequest, outgoingOrigin()); 3485 3531 3486 3532 if (Page* page = m_frame->page()) … … 4294 4340 ResourceRequest request(itemURL); 4295 4341 4296 addExtraFieldsToRequest(request, true, formData);4297 4298 4342 // If this was a repost that failed the page cache, we might try to repost the form. 4299 4343 NavigationAction action; … … 4306 4350 request.setHTTPBody(formData); 4307 4351 request.setHTTPContentType(item->formContentType()); 4352 RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::createFromString(item->formReferrer()); 4353 addHTTPOriginIfNeeded(request, securityOrigin->toHTTPOrigin()); 4308 4354 4309 4355 // FIXME: Slight hack to test if the NSURL cache contains the page we're going to. … … 4346 4392 } 4347 4393 4394 addExtraFieldsToRequest(request, true, formData); 4348 4395 loadWithNavigationAction(request, action, loadType, 0); 4349 4396 } -
trunk/WebCore/loader/FrameLoader.h
r37112 r37317 194 194 String referrer() const; 195 195 String outgoingReferrer() const; 196 String outgoingOrigin() const; 196 197 void loadEmptyDocumentSynchronously(); 197 198 … … 278 279 279 280 void addExtraFieldsToRequest(ResourceRequest&, bool isMainResource, bool alwaysFromRequest); 281 static void addHTTPOriginIfNeeded(ResourceRequest&, String origin); 280 282 281 283 FrameLoaderClient* client() const; -
trunk/WebCore/loader/SubresourceLoader.cpp
r35435 r37317 94 94 else if (!request.httpReferrer()) 95 95 newRequest.setHTTPReferrer(fl->outgoingReferrer()); 96 FrameLoader::addHTTPOriginIfNeeded(newRequest, fl->outgoingOrigin()); 96 97 97 98 // Use the original request's cache policy for two reasons: -
trunk/WebCore/loader/loader.cpp
r36132 r37317 37 37 #include "ResourceRequest.h" 38 38 #include "ResourceResponse.h" 39 #include "SecurityOrigin.h" 39 40 #include "SubresourceLoader.h" 40 41 #include <wtf/Assertions.h> … … 240 241 referrer.setPath("/"); 241 242 resourceRequest.setHTTPReferrer(referrer.string()); 243 FrameLoader::addHTTPOriginIfNeeded(resourceRequest, docLoader->doc()->securityOrigin()->toHTTPOrigin()); 242 244 243 245 if (resourceIsCacheValidator) { -
trunk/WebCore/page/SecurityOrigin.cpp
r37282 r37317 221 221 } 222 222 223 String SecurityOrigin::toHTTPOrigin() const 224 { 225 String origin = toString(); 226 if (origin.isEmpty()) 227 return "null"; 228 229 return origin; 230 } 231 223 232 PassRefPtr<SecurityOrigin> SecurityOrigin::createFromString(const String& originString) 224 233 { -
trunk/WebCore/page/SecurityOrigin.h
r37282 r37317 107 107 String toString() const; 108 108 109 // Convert this SecurityOrigin into a string for use in the HTTP Origin 110 // header. This is similar to toString(), except that the empty 111 // SecurityOrigin is represented as the string "null". 112 String toHTTPOrigin() const; 113 109 114 // Serialize the security origin for storage in the database. This format is 110 115 // deprecated and should be used only for compatibility with old databases; -
trunk/WebCore/platform/network/ResourceRequestBase.h
r36108 r37317 79 79 void clearHTTPReferrer() { m_httpHeaderFields.remove("Referer"); } 80 80 81 String httpOrigin() const { return httpHeaderField("Origin"); } 82 void setHTTPOrigin(const String& httpOrigin) { setHTTPHeaderField("Origin", httpOrigin); } 83 void clearHTTPOrigin() { m_httpHeaderFields.remove("Origin"); } 84 81 85 String httpUserAgent() const { return httpHeaderField("User-Agent"); } 82 86 void setHTTPUserAgent(const String& httpUserAgent) { setHTTPHeaderField("User-Agent", httpUserAgent); } -
trunk/WebCore/xml/XMLHttpRequest.cpp
r37190 r37317 538 538 } 539 539 540 String XMLHttpRequest::accessControlOrigin() const541 {542 String accessControlOrigin = m_doc->securityOrigin()->toString();543 if (accessControlOrigin.isEmpty())544 return "null";545 return accessControlOrigin;546 }547 548 540 void XMLHttpRequest::makeSimpleCrossSiteAccessRequest(ExceptionCode& ec) 549 541 { … … 557 549 request.setHTTPMethod(m_method); 558 550 request.setAllowHTTPCookies(m_includeCredentials); 559 request.setHTTP HeaderField("Origin", accessControlOrigin());551 request.setHTTPOrigin(m_doc->securityOrigin()->toHTTPOrigin()); 560 552 561 553 if (m_requestHeaders.size() > 0) … … 588 580 void XMLHttpRequest::makeCrossSiteAccessRequestWithPreflight(ExceptionCode& ec) 589 581 { 590 String origin = accessControlOrigin();582 String origin = m_doc->securityOrigin()->toHTTPOrigin(); 591 583 KURL url = m_url; 592 584 url.setUser(String()); … … 676 668 request.setHTTPMethod(m_method); 677 669 request.setAllowHTTPCookies(m_includeCredentials); 678 request.setHTTP HeaderField("Origin", accessControlOrigin());670 request.setHTTPOrigin(m_doc->securityOrigin()->toHTTPOrigin()); 679 671 680 672 if (m_requestHeaders.size() > 0) … … 1201 1193 expiryDelta = 5; 1202 1194 1203 appendPreflightResultCacheEntry( accessControlOrigin(), m_url, expiryDelta, m_includeCredentials, methods.release(), headers.release());1195 appendPreflightResultCacheEntry(m_doc->securityOrigin()->toHTTPOrigin(), m_url, expiryDelta, m_includeCredentials, methods.release(), headers.release()); 1204 1196 } 1205 1197
Note: See TracChangeset
for help on using the changeset viewer.