Resource loader should block HTTP redirects to local resources

https://bugs.webkit.org/show_bug.cgi?id=68706

Patch by Ken Buchanan <kenrb@chromium.org> on 2011-10-03
Reviewed by Adam Barth.

Source/WebCore:

Modified MainResourceLoader to add an extra security check on
HTTP redirects. Also, moved isFeedWithNestedProtocolInHTTPFamily
to SecurityOrigin.cpp.

* loader/FrameLoader.cpp:
(WebCore::isFeedWithNestedProtocolInHTTPFamily):
(WebCore::FrameLoader::loadFrameRequest):
* loader/MainResourceLoader.cpp:
(WebCore::MainResourceLoader::willSendRequest):
* page/SecurityOrigin.cpp:
(WebCore::isFeedWithNestedProtocolInHTTPFamily):
(WebCore::SecurityOrigin::canDisplay):

LayoutTests:

Adding a test to attempt an HTTP redirect to a file: URL.

* http/tests/security/redirect-BLOCKED-to-localURL.html: Added.
* http/tests/security/redirect-BLOCKED-to-localURL-expected.txt: Added.
* http/tests/security/resources/file-redirect-target.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96610 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 1fbeb615
2011-10-03 Ken Buchanan <kenrb@chromium.org>
Resource loader should block HTTP redirects to local resources
https://bugs.webkit.org/show_bug.cgi?id=68706
Reviewed by Adam Barth.
Adding a test to attempt an HTTP redirect to a file: URL.
* http/tests/security/redirect-BLOCKED-to-localURL.html: Added.
* http/tests/security/redirect-BLOCKED-to-localURL-expected.txt: Added.
* http/tests/security/resources/file-redirect-target.html: Added.
2011-10-04 Adam Barth <abarth@webkit.org>
Restore Linux baseline for this test. The Linux baseline got clobbered
CONSOLE MESSAGE: line 0: Not allowed to load local resource: file-redirect-target.html
This attempts to open a redirect link to a file URL, which should be blocked.
<html>
<body>
<iframe src="http://127.0.0.1:8000/security/resources/redir.php?url=file:///tmp/LayoutTests/http/tests/security/resources/file-redirect-target.html"></iframe></br>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
}
</script>
<p>This attempts to open a redirect link to a file URL, which should be blocked.</p>
</body>
</html>
<html>
FAIL: This page shouldn't load via HTTP redirect to file:
</html>
2011-10-03 Ken Buchanan <kenrb@chromium.org>
Resource loader should block HTTP redirects to local resources
https://bugs.webkit.org/show_bug.cgi?id=68706
Reviewed by Adam Barth.
Modified MainResourceLoader to add an extra security check on
HTTP redirects. Also, moved isFeedWithNestedProtocolInHTTPFamily
to SecurityOrigin.cpp.
* loader/FrameLoader.cpp:
(WebCore::isFeedWithNestedProtocolInHTTPFamily):
(WebCore::FrameLoader::loadFrameRequest):
* loader/MainResourceLoader.cpp:
(WebCore::MainResourceLoader::willSendRequest):
* page/SecurityOrigin.cpp:
(WebCore::isFeedWithNestedProtocolInHTTPFamily):
(WebCore::SecurityOrigin::canDisplay):
2011-10-04 Cary Clark <caryclark@google.com>
Apply color profile found to decoded bitmap (Skia on Mac)
......@@ -1125,21 +1125,6 @@ void FrameLoader::setupForReplace()
detachChildren();
}
// This is a hack to allow keep navigation to http/https feeds working. To remove this
// we need to introduce new API akin to registerURLSchemeAsLocal, that registers a
// protocols navigation policy.
static bool isFeedWithNestedProtocolInHTTPFamily(const KURL& url)
{
const String& urlString = url.string();
if (!urlString.startsWith("feed", false))
return false;
return urlString.startsWith("feed://", false)
|| urlString.startsWith("feed:http:", false) || urlString.startsWith("feed:https:", false)
|| urlString.startsWith("feeds:http:", false) || urlString.startsWith("feeds:https:", false)
|| urlString.startsWith("feedsearch:http:", false) || urlString.startsWith("feedsearch:https:", false);
}
void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, bool lockHistory, bool lockBackForwardList,
PassRefPtr<Event> event, PassRefPtr<FormState> formState, ReferrerPolicy referrerPolicy)
{
......@@ -1149,8 +1134,7 @@ void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, bool lockHis
KURL url = request.resourceRequest().url();
ASSERT(m_frame->document());
// FIXME: Should we move the isFeedWithNestedProtocolInHTTPFamily logic inside SecurityOrigin::canDisplay?
if (!isFeedWithNestedProtocolInHTTPFamily(url) && !request.requester()->canDisplay(url)) {
if (!request.requester()->canDisplay(url)) {
reportLocalLoadFailed(m_frame, url.string());
return;
}
......
......@@ -182,6 +182,15 @@ void MainResourceLoader::willSendRequest(ResourceRequest& newRequest, const Reso
ASSERT(documentLoader()->timing()->fetchStart);
if (!redirectResponse.isNull()) {
// If the redirecting url is not allowed to display content from the target origin,
// then block the redirect.
RefPtr<SecurityOrigin> redirectingOrigin = SecurityOrigin::create(redirectResponse.url());
if (!redirectingOrigin->canDisplay(newRequest.url())) {
FrameLoader::reportLocalLoadFailed(m_frame.get(), newRequest.url().string());
cancel();
return;
}
DocumentLoadTiming* documentLoadTiming = documentLoader()->timing();
// Check if the redirected url is allowed to access the redirecting url's timing information.
......
......@@ -332,10 +332,33 @@ bool SecurityOrigin::isAccessToURLWhiteListed(const KURL& url) const
return isAccessWhiteListed(targetOrigin.get());
}
// This is a hack to allow keep navigation to http/https feeds working. To remove this
// we need to introduce new API akin to registerURLSchemeAsLocal, that registers a
// protocols navigation policy.
// feed(|s|search): is considered a 'nesting' scheme by embedders that support it, so it can be
// local or remote depending on what is nested. Currently we just check if we are nesting
// http or https, otherwise we ignore the nesting for the purpose of a security check. We need
// a facility for registering nesting schemes, and some generalized logic for them.
// This function should be removed as an outcome of https://bugs.webkit.org/show_bug.cgi?id=69196
static bool isFeedWithNestedProtocolInHTTPFamily(const KURL& url)
{
const String& urlString = url.string();
if (!urlString.startsWith("feed", false))
return false;
return urlString.startsWith("feed://", false)
|| urlString.startsWith("feed:http:", false) || urlString.startsWith("feed:https:", false)
|| urlString.startsWith("feeds:http:", false) || urlString.startsWith("feeds:https:", false)
|| urlString.startsWith("feedsearch:http:", false) || urlString.startsWith("feedsearch:https:", false);
}
bool SecurityOrigin::canDisplay(const KURL& url) const
{
String protocol = url.protocol().lower();
if (isFeedWithNestedProtocolInHTTPFamily(url))
return true;
if (SchemeRegistry::canDisplayOnlyIfCanRequest(protocol))
return canRequest(url);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment