Commit 4761ef58 authored by jochen@chromium.org's avatar jochen@chromium.org

Implement Meta referrer

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

Reviewed by Adam Barth.

Source/WebCore:

http://wiki.whatwg.org/wiki/Meta_referrer

Tests: http/tests/security/referrer-policy-always.html
       http/tests/security/referrer-policy-default.html
       http/tests/security/referrer-policy-https-always.html
       http/tests/security/referrer-policy-https-default.html
       http/tests/security/referrer-policy-https-never.html
       http/tests/security/referrer-policy-https-origin.html
       http/tests/security/referrer-policy-never.html
       http/tests/security/referrer-policy-origin.html
       http/tests/security/referrer-policy-redirect.html
       http/tests/security/referrer-policy-rel-noreferrer.html

* WebCore.exp.in: updated
* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::processReferrerPolicy):
* dom/Document.h:
(WebCore::Document::referrerPolicy):
* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::handleClick):
* html/HTMLMetaElement.cpp:
(WebCore::HTMLMetaElement::process):
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::loadFrameRequest):
(WebCore::FrameLoader::loadResourceSynchronously):
* loader/PingLoader.cpp:
(WebCore::PingLoader::loadImage):
(WebCore::PingLoader::sendPing):
(WebCore::PingLoader::reportContentSecurityPolicyViolation):
* loader/SubframeLoader.cpp:
(WebCore::SubframeLoader::loadSubframe):
* loader/SubresourceLoader.cpp:
(WebCore::SubresourceLoader::create):
* page/SecurityPolicy.cpp:
(WebCore::SecurityPolicy::generateReferrerHeader):
* page/SecurityPolicy.h:

Source/WebKit/chromium:

* WebKit.gyp:
* public/WebFrame.h:
* public/WebReferrerPolicy.h: Added.
* public/WebSecurityPolicy.h:
* src/AssertMatchingEnums.cpp:
* src/WebFrameImpl.cpp:
(WebKit::WebFrameImpl::referrerPolicy):
(WebKit::WebFrameImpl::setReferrerForRequest):
* src/WebFrameImpl.h:
* src/WebSecurityPolicy.cpp:
(WebKit::WebSecurityPolicy::generateReferrerHeader):

Source/WebKit/mac:

* Plugins/Hosted/HostedNetscapePluginStream.mm:
(WebKit::HostedNetscapePluginStream::HostedNetscapePluginStream):
* Plugins/WebNetscapePluginStream.mm:
(WebNetscapePluginStream::WebNetscapePluginStream):

Source/WebKit2:

* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::loadURL):

LayoutTests:

* http/tests/security/referrer-policy-always-expected.txt: Added.
* http/tests/security/referrer-policy-always.html: Added.
* http/tests/security/referrer-policy-default-expected.txt: Added.
* http/tests/security/referrer-policy-default.html: Added.
* http/tests/security/referrer-policy-https-always-expected.txt: Added.
* http/tests/security/referrer-policy-https-always.html: Added.
* http/tests/security/referrer-policy-https-default-expected.txt: Added.
* http/tests/security/referrer-policy-https-default.html: Added.
* http/tests/security/referrer-policy-https-never-expected.txt: Added.
* http/tests/security/referrer-policy-https-never.html: Added.
* http/tests/security/referrer-policy-https-origin-expected.txt: Added.
* http/tests/security/referrer-policy-https-origin.html: Added.
* http/tests/security/referrer-policy-never-expected.txt: Added.
* http/tests/security/referrer-policy-never.html: Added.
* http/tests/security/referrer-policy-origin-expected.txt: Added.
* http/tests/security/referrer-policy-origin.html: Added.
* http/tests/security/referrer-policy-redirect-expected.txt: Added.
* http/tests/security/referrer-policy-redirect.html: Added.
* http/tests/security/referrer-policy-rel-noreferrer-expected.txt: Added.
* http/tests/security/referrer-policy-rel-noreferrer.html: Added.
* http/tests/security/resources/referrer-policy-log.php: Added.
* http/tests/security/resources/referrer-policy-redirect.html: Added.
* http/tests/security/resources/referrer-policy-start.html: Added.
* http/tests/security/resources/rel-noreferrer.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@100895 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e4a09265
2011-11-21 Jochen Eisinger <jochen@chromium.org>
Implement Meta referrer
https://bugs.webkit.org/show_bug.cgi?id=72674
Reviewed by Adam Barth.
* http/tests/security/referrer-policy-always-expected.txt: Added.
* http/tests/security/referrer-policy-always.html: Added.
* http/tests/security/referrer-policy-default-expected.txt: Added.
* http/tests/security/referrer-policy-default.html: Added.
* http/tests/security/referrer-policy-https-always-expected.txt: Added.
* http/tests/security/referrer-policy-https-always.html: Added.
* http/tests/security/referrer-policy-https-default-expected.txt: Added.
* http/tests/security/referrer-policy-https-default.html: Added.
* http/tests/security/referrer-policy-https-never-expected.txt: Added.
* http/tests/security/referrer-policy-https-never.html: Added.
* http/tests/security/referrer-policy-https-origin-expected.txt: Added.
* http/tests/security/referrer-policy-https-origin.html: Added.
* http/tests/security/referrer-policy-never-expected.txt: Added.
* http/tests/security/referrer-policy-never.html: Added.
* http/tests/security/referrer-policy-origin-expected.txt: Added.
* http/tests/security/referrer-policy-origin.html: Added.
* http/tests/security/referrer-policy-redirect-expected.txt: Added.
* http/tests/security/referrer-policy-redirect.html: Added.
* http/tests/security/referrer-policy-rel-noreferrer-expected.txt: Added.
* http/tests/security/referrer-policy-rel-noreferrer.html: Added.
* http/tests/security/resources/referrer-policy-log.php: Added.
* http/tests/security/resources/referrer-policy-redirect.html: Added.
* http/tests/security/resources/referrer-policy-start.html: Added.
* http/tests/security/resources/rel-noreferrer.html: Added.
2011-11-21 Dominic Mazzoni <dmazzoni@google.com>
Accessibility: Multiselect list boxes need to report the active option in addition to which items are selected.
This test checks the always referrer policy when navigating from an insecure URL to another insecure URL. The test passes if the printed referrer is http://127.0.0.1:8000/security/resources/referrer-policy-start.html?always
--------
Frame: '<!--framePath //<!--frame0-->-->'
--------
HTTP Referer header is http://127.0.0.1:8000/security/resources/referrer-policy-start.html?always
Referrer is http://127.0.0.1:8000/security/resources/referrer-policy-start.html?always
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.dumpChildFramesAsText();
layoutTestController.waitUntilDone();
}
</script>
</head>
<body>
<p>
This test checks the always referrer policy when navigating from an insecure
URL to another insecure URL. The test passes if the printed referrer is
http://127.0.0.1:8000/security/resources/referrer-policy-start.html?always
</p>
<iframe src="http://127.0.0.1:8000/security/resources/referrer-policy-start.html?always"></iframe>
</body>
</html>
This test checks the default referrer policy when navigating from an insecure URL to another insecure URL. The test passes if the printed referrer is http://127.0.0.1:8000/security/resources/referrer-policy-start.html?default
--------
Frame: '<!--framePath //<!--frame0-->-->'
--------
HTTP Referer header is http://127.0.0.1:8000/security/resources/referrer-policy-start.html?default
Referrer is http://127.0.0.1:8000/security/resources/referrer-policy-start.html?default
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.dumpChildFramesAsText();
layoutTestController.waitUntilDone();
}
</script>
</head>
<body>
<p>
This test checks the default referrer policy when navigating from an insecure
URL to another insecure URL. The test passes if the printed referrer is
http://127.0.0.1:8000/security/resources/referrer-policy-start.html?default
</p>
<iframe src="http://127.0.0.1:8000/security/resources/referrer-policy-start.html?default"></iframe>
</body>
</html>
This test checks the always referrer policy when navigating from a secure URL to an insecure URL. The test passes if the printed referrer is https://127.0.0.1:8443/security/resources/referrer-policy-start.html?always
--------
Frame: '<!--framePath //<!--frame0-->-->'
--------
HTTP Referer header is https://127.0.0.1:8443/security/resources/referrer-policy-start.html?always
Referrer is https://127.0.0.1:8443/security/resources/referrer-policy-start.html?always
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.dumpChildFramesAsText();
layoutTestController.waitUntilDone();
}
</script>
</head>
<body>
<p>
This test checks the always referrer policy when navigating from a secure URL
to an insecure URL. The test passes if the printed referrer is
https://127.0.0.1:8443/security/resources/referrer-policy-start.html?always
</p>
<iframe src="https://127.0.0.1:8443/security/resources/referrer-policy-start.html?always"></iframe>
</body>
</html>
This test checks the default referrer policy when navigating from a secure URL to an insecure URL. The test passes if the printed referrer is empty.
--------
Frame: '<!--framePath //<!--frame0-->-->'
--------
HTTP Referer header is empty
Referrer is empty
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.dumpChildFramesAsText();
layoutTestController.waitUntilDone();
}
</script>
</head>
<body>
<p>
This test checks the default referrer policy when navigating from a secure URL
to an insecure URL. The test passes if the printed referrer is empty.
</p>
<iframe src="https://127.0.0.1:8443/security/resources/referrer-policy-start.html?default"></iframe>
</body>
</html>
This test checks the never referrer policy when navigating from a secure URL to an insecure URL. The test passes if the printed referrer is empty.
--------
Frame: '<!--framePath //<!--frame0-->-->'
--------
HTTP Referer header is empty
Referrer is empty
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.dumpChildFramesAsText();
layoutTestController.waitUntilDone();
}
</script>
</head>
<body>
<p>
This test checks the never referrer policy when navigating from a secure URL to
an insecure URL. The test passes if the printed referrer is empty.
</p>
<iframe src="https://127.0.0.1:8443/security/resources/referrer-policy-start.html?never"></iframe>
</body>
</html>
This test checks the origin referrer policy when navigating from a secure URL to an insecure URL. The test passes if the printed referrer is https://127.0.0.1:8443
--------
Frame: '<!--framePath //<!--frame0-->-->'
--------
HTTP Referer header is https://127.0.0.1:8443/
Referrer is https://127.0.0.1:8443/
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.dumpChildFramesAsText();
layoutTestController.waitUntilDone();
}
</script>
</head>
<body>
<p>
This test checks the origin referrer policy when navigating from a secure URL
to an insecure URL. The test passes if the printed referrer is
https://127.0.0.1:8443
</p>
<iframe src="https://127.0.0.1:8443/security/resources/referrer-policy-start.html?origin"></iframe>
</body>
</html>
This test checks the never referrer policy when navigating from an insecure URL to another insecure URL. The test passes if the printed referrer is empty.
--------
Frame: '<!--framePath //<!--frame0-->-->'
--------
HTTP Referer header is empty
Referrer is empty
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.dumpChildFramesAsText();
layoutTestController.waitUntilDone();
}
</script>
</head>
<body>
<p>
This test checks the never referrer policy when navigating from an insecure
URL to another insecure URL. The test passes if the printed referrer is empty.
</p>
<iframe src="http://127.0.0.1:8000/security/resources/referrer-policy-start.html?never"></iframe>
</body>
</html>
This test checks the origin referrer policy when navigating from an insecure URL to another insecure URL. The test passes if the printed referrer is http://127.0.0.1:8000
--------
Frame: '<!--framePath //<!--frame0-->-->'
--------
HTTP Referer header is http://127.0.0.1:8000/
Referrer is http://127.0.0.1:8000/
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.dumpChildFramesAsText();
layoutTestController.waitUntilDone();
}
</script>
</head>
<body>
<p>
This test checks the origin referrer policy when navigating from an insecure
URL to another insecure URL. The test passes if the printed referrer is
http://127.0.0.1:8000
</p>
<iframe src="http://127.0.0.1:8000/security/resources/referrer-policy-start.html?origin"></iframe>
</body>
</html>
This test checks the referrer policy is obeyed along the redirect chain. The test passes if the referrer is http://127.0.0.1:8000
--------
Frame: '<!--framePath //<!--frame0-->-->'
--------
HTTP Referer header is http://127.0.0.1:8000/
Referrer is http://127.0.0.1:8000/
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.dumpChildFramesAsText();
layoutTestController.waitUntilDone();
}
</script>
</head>
<body>
<p>
This test checks the referrer policy is obeyed along the redirect chain. The
test passes if the referrer is http://127.0.0.1:8000
</p>
<iframe src="http://127.0.0.1:8000/security/resources/referrer-policy-redirect.html"></iframe>
</body>
</html>
This test navigates a frame by clicking on a link with rel=noreferrer. It passes, if the referrer is empty, even though the referrer policy is set to always.
--------
Frame: '<!--framePath //<!--frame0-->-->'
--------
HTTP Referer header is empty
Referrer is empty
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.dumpChildFramesAsText();
layoutTestController.waitUntilDone();
}
</script>
</head>
<body>
<p>
This test navigates a frame by clicking on a link with rel=noreferrer.
It passes, if the referrer is empty, even though the referrer policy is
set to always.
</p>
<iframe src="http://127.0.0.1:8000/security/resources/rel-noreferrer.html"></iframe>
</body>
</html>
<html>
<head>
<script>
function log(msg) {
document.getElementById("log").innerHTML += msg + "<br>";
}
function runTest() {
var referrerHeader = "<?php echo $_SERVER['HTTP_REFERER'] ?>";
if (referrerHeader == "")
log("HTTP Referer header is empty");
else
log("HTTP Referer header is " + referrerHeader);
if (document.referrer == "")
log("Referrer is empty");
else
log("Referrer is " + document.referrer);
if (window.layoutTestController)
layoutTestController.notifyDone();
}
</script>
</head>
<body onload="runTest()">
<div id="log"></div>
</body>
</html>
<html>
<head>
<meta name="referrer" content="origin" />
<script>
function runTest() {
document.location = "https://127.0.0.1:8443/resources/redirect.php?url=" +
"http://127.0.0.1:8000/security/resources/referrer-policy-log.php";
}
</script>
</head>
<body onload="runTest()">
</body>
</html>
<html>
<head>
<script>
function runTest() {
var meta = document.createElement("meta");
meta.name = "referrer";
meta.content = document.location.search.substring(1);
document.head.appendChild(meta);
document.location =
"http://127.0.0.1:8000/security/resources/referrer-policy-log.php";
}
</script>
</head>
<body onload="runTest()">
</body>
</html>
<html>
<head>
<meta name="referrer" content="always" />
<script>
function runTest() {
var link = document.getElementById("link");
var iframe = window.parent.document.getElementsByTagName("iframe")[0];
eventSender.mouseMoveTo(link.offsetLeft + iframe.offsetLeft + 2,
link.offsetTop + iframe.offsetTop + 2);
eventSender.mouseDown();
eventSender.mouseUp();
}
</script>
</head>
<body onload="runTest()">
<a id="link" href="http://127.0.0.1:8000/security/resources/referrer-policy-log.php" rel="noreferrer">link</a>
</body>
</html>
2011-11-21 Jochen Eisinger <jochen@chromium.org>
Implement Meta referrer
https://bugs.webkit.org/show_bug.cgi?id=72674
Reviewed by Adam Barth.
http://wiki.whatwg.org/wiki/Meta_referrer
Tests: http/tests/security/referrer-policy-always.html
http/tests/security/referrer-policy-default.html
http/tests/security/referrer-policy-https-always.html
http/tests/security/referrer-policy-https-default.html
http/tests/security/referrer-policy-https-never.html
http/tests/security/referrer-policy-https-origin.html
http/tests/security/referrer-policy-never.html
http/tests/security/referrer-policy-origin.html
http/tests/security/referrer-policy-redirect.html
http/tests/security/referrer-policy-rel-noreferrer.html
* WebCore.exp.in: updated
* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::processReferrerPolicy):
* dom/Document.h:
(WebCore::Document::referrerPolicy):
* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::handleClick):
* html/HTMLMetaElement.cpp:
(WebCore::HTMLMetaElement::process):
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::loadFrameRequest):
(WebCore::FrameLoader::loadResourceSynchronously):
* loader/PingLoader.cpp:
(WebCore::PingLoader::loadImage):
(WebCore::PingLoader::sendPing):
(WebCore::PingLoader::reportContentSecurityPolicyViolation):
* loader/SubframeLoader.cpp:
(WebCore::SubframeLoader::loadSubframe):
* loader/SubresourceLoader.cpp:
(WebCore::SubresourceLoader::create):
* page/SecurityPolicy.cpp:
(WebCore::SecurityPolicy::generateReferrerHeader):
* page/SecurityPolicy.h:
2011-11-21 Vsevolod Vlasov <vsevik@chromium.org>
Web Inspector: ApplicationCache view should show navigator.onLine indicator.
......@@ -391,6 +391,7 @@ __ZN7WebCore14SecurityOrigin6createERKN3WTF6StringES4_i
__ZN7WebCore14SecurityOrigin6createERKNS_4KURLE
__ZN7WebCore14SecurityPolicy18setLocalLoadPolicyENS0_15LocalLoadPolicyE
__ZN7WebCore14SecurityPolicy18shouldHideReferrerERKNS_4KURLERKN3WTF6StringE
__ZN7WebCore14SecurityPolicy22generateReferrerHeaderENS0_14ReferrerPolicyERKNS_4KURLERKN3WTF6StringE
__ZN7WebCore14SecurityPolicy27resetOriginAccessWhitelistsEv
__ZN7WebCore14SecurityPolicy29addOriginAccessWhitelistEntryERKNS_14SecurityOriginERKN3WTF6StringES7_b
__ZN7WebCore14SecurityPolicy32removeOriginAccessWhitelistEntryERKNS_14SecurityOriginERKN3WTF6StringES7_b
......
......@@ -423,6 +423,7 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
#endif
, m_loadEventDelayCount(0)
, m_loadEventDelayTimer(this, &Document::loadEventDelayTimerFired)
, m_referrerPolicy(SecurityPolicy::ReferrerPolicyDefault)
, m_directionSetOnDocumentElement(false)
, m_writingModeSetOnDocumentElement(false)
, m_writeRecursionIsTooDeep(false)
......@@ -2742,6 +2743,20 @@ void Document::processViewport(const String& features)
frame->page()->updateViewportArguments();
}
void Document::processReferrerPolicy(const String& policy)
{
ASSERT(!policy.isNull());
m_referrerPolicy = SecurityPolicy::ReferrerPolicyDefault;
if (equalIgnoringCase(policy, "never"))
m_referrerPolicy = SecurityPolicy::ReferrerPolicyNever;
else if (equalIgnoringCase(policy, "always"))
m_referrerPolicy = SecurityPolicy::ReferrerPolicyAlways;
else if (equalIgnoringCase(policy, "origin"))
m_referrerPolicy = SecurityPolicy::ReferrerPolicyOrigin;
}
MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& request, const LayoutPoint& documentPoint, const PlatformMouseEvent& event)
{
ASSERT(!renderer() || renderer()->isRenderView());
......
......@@ -42,6 +42,7 @@
#include "PlatformScreen.h"
#include "QualifiedName.h"
#include "ScriptExecutionContext.h"
#include "SecurityPolicy.h"
#include "StringWithDirection.h"
#include "Timer.h"
#include "TreeScope.h"
......@@ -323,6 +324,8 @@ public:
ViewportArguments viewportArguments() const { return m_viewportArguments; }
SecurityPolicy::ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; }
DocumentType* doctype() const { return m_docType.get(); }
DOMImplementation* implementation();
......@@ -805,6 +808,7 @@ public:
*/
void processHttpEquiv(const String& equiv, const String& content);
void processViewport(const String& features);
void processReferrerPolicy(const String& policy);
// Returns the owning element in the parent document.
// Returns 0 if this is the top level document.
......@@ -1414,6 +1418,8 @@ private:
ViewportArguments m_viewportArguments;
SecurityPolicy::ReferrerPolicy m_referrerPolicy;
bool m_directionSetOnDocumentElement;
bool m_writingModeSetOnDocumentElement;
......
......@@ -504,8 +504,8 @@ void HTMLAnchorElement::handleClick(Event* event)
ResourceRequest request(kurl);
if (!hasRel(RelationNoReferrer)) {
String referrer = frame->loader()->outgoingReferrer();
if (!referrer.isEmpty() && !SecurityPolicy::shouldHideReferrer(kurl, referrer))
String referrer = SecurityPolicy::generateReferrerHeader(document()->referrerPolicy(), kurl, frame->loader()->outgoingReferrer());
if (!referrer.isEmpty())
request.setHTTPReferrer(referrer);
frame->loader()->addExtraFieldsToMainResourceRequest(request);
}
......
......@@ -72,6 +72,9 @@ void HTMLMetaElement::process()
if (equalIgnoringCase(name(), "viewport"))
document()->processViewport(contentValue);
if (equalIgnoringCase(name(), "referrer"))
document()->processReferrerPolicy(contentValue);
// Get the document to process the tag, but only if we're actually part of DOM tree (changing a meta tag while
// it's not in the tree shouldn't have any effect on the document)
const AtomicString& httpEquivValue = fastGetAttribute(http_equivAttr);
......
......@@ -1138,14 +1138,12 @@ void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, bool lockHis
return;
}
String referrer;
String argsReferrer = request.resourceRequest().httpReferrer();
if (!argsReferrer.isEmpty())
referrer = argsReferrer;
else
referrer = m_outgoingReferrer;
if (argsReferrer.isEmpty())
argsReferrer = m_outgoingReferrer;
if (SecurityPolicy::shouldHideReferrer(url, referrer) || shouldSendReferrer == NeverSendReferrer)
String referrer = SecurityPolicy::generateReferrerHeader(m_frame->document()->referrerPolicy(), url, argsReferrer);
if (shouldSendReferrer == NeverSendReferrer)
referrer = String();
FrameLoadType loadType;
......@@ -2594,9 +2592,8 @@ void FrameLoader::loadPostRequest(const ResourceRequest& inRequest, const String
unsigned long FrameLoader::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data)
{
String referrer = m_outgoingReferrer;
if (SecurityPolicy::shouldHideReferrer(request.url(), referrer))
referrer = String();
ASSERT(m_frame->document());
String referrer = SecurityPolicy::generateReferrerHeader(m_frame->document()->referrerPolicy(), request.url(), m_outgoingReferrer);
ResourceRequest initialRequest = request;
initialRequest.setTimeoutInterval(10);
......
......@@ -60,8 +60,9 @@ void PingLoader::loadImage(Frame* frame, const KURL& url)
request.setTargetType(ResourceRequest::TargetIsImage);
#endif
request.setHTTPHeaderField("Cache-Control", "max-age=0");
if (!SecurityPolicy::shouldHideReferrer(<