mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 690168. Implement the 'Allow-From' directive for X-Frame-Options. r=bzbarsky
This commit is contained in:
parent
8ec001feea
commit
cd2459e50f
@ -19,6 +19,8 @@ window.addEventListener('load', parent.testFramesLoaded, false);
|
||||
<iframe id="sameorigin7" src="http://mochi.test:8888/tests/content/base/test/file_x-frame-options_page.sjs?testid=sameorigin7&xfo=sameorigin3"></iframe><br>
|
||||
<iframe id="sameorigin8" src="http://example.com/tests/content/base/test/file_x-frame-options_page.sjs?testid=sameorigin8&xfo=sameorigin3"></iframe><br>
|
||||
<iframe id="mixedpolicy" src="http://mochi.test:8888/tests/content/base/test/file_x-frame-options_page.sjs?testid=mixedpolicy&xfo=mixedpolicy"></iframe><br>
|
||||
<iframe id="allow-from-allow" src="http://example.com/tests/content/base/test/file_x-frame-options_page.sjs?testid=allow-from-allow&xfo=afa"></iframe><br>
|
||||
<iframe id="allow-from-deny" src="http://example.com/tests/content/base/test/file_x-frame-options_page.sjs?testid=allow-from-deny&xfo=afd"></iframe><br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -26,6 +26,12 @@ function handleRequest(request, response)
|
||||
else if (query['xfo'] == "mixedpolicy") {
|
||||
response.setHeader("X-Frame-Options", "DENY,SAMEORIGIN", false);
|
||||
}
|
||||
else if (query['xfo'] == "afa") {
|
||||
response.setHeader("X-Frame-Options", "ALLOW-FROM http://mochi.test:8888/", false);
|
||||
}
|
||||
else if (query['xfo'] == "afd") {
|
||||
response.setHeader("X-Frame-Options", "ALLOW-FROM http://example.com/", false);
|
||||
}
|
||||
|
||||
// from the test harness we'll be checking for the presence of this element
|
||||
// to test if the page loaded
|
||||
|
@ -108,6 +108,16 @@ var testFramesLoaded = function() {
|
||||
var test10 = frame.contentDocument.getElementById("test");
|
||||
is(test10, null, "test mixedpolicy");
|
||||
|
||||
// iframe from different origin, allow-from: this origin - should load
|
||||
frame = harness.contentDocument.getElementById("allow-from-allow");
|
||||
var test11 = frame.contentDocument.getElementById("test").textContent;
|
||||
is(test11, "allow-from-allow", "test allow-from-allow");
|
||||
|
||||
// iframe from different origin, with allow-from: other - should not load
|
||||
frame = harness.contentDocument.getElementById("allow-from-deny");
|
||||
var test12 = frame.contentDocument.getElementById("test");
|
||||
is(test12, null, "test allow-from-deny");
|
||||
|
||||
// call tests to check principal comparison, e.g. a document can open a window
|
||||
// to a data: or javascript: document which frames an
|
||||
// X-Frame-Options: SAMEORIGIN document and the frame should load
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "nsDocShellCID.h"
|
||||
#include "nsIWebNavigationInfo.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
@ -258,9 +259,15 @@ nsDSURIContentListener::SetParentContentListener(nsIURIContentListener*
|
||||
|
||||
bool nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIRequest *request,
|
||||
const nsAString& policy) {
|
||||
// return early if header does not have one of the two values with meaning
|
||||
static const char allowFrom[] = "allow-from ";
|
||||
const PRUint32 allowFromLen = ArrayLength(allowFrom) - 1;
|
||||
bool isAllowFrom =
|
||||
StringHead(policy, allowFromLen).LowerCaseEqualsLiteral(allowFrom);
|
||||
|
||||
// return early if header does not have one of the values with meaning
|
||||
if (!policy.LowerCaseEqualsLiteral("deny") &&
|
||||
!policy.LowerCaseEqualsLiteral("sameorigin"))
|
||||
!policy.LowerCaseEqualsLiteral("sameorigin") &&
|
||||
!isAllowFrom)
|
||||
return true;
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(request);
|
||||
@ -342,18 +349,32 @@ bool nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIRequest *request,
|
||||
return false;
|
||||
}
|
||||
|
||||
topDoc = do_GetInterface(curDocShellItem);
|
||||
nsCOMPtr<nsIURI> topUri;
|
||||
topDoc->NodePrincipal()->GetURI(getter_AddRefs(topUri));
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
|
||||
// If the X-Frame-Options value is SAMEORIGIN, then the top frame in the
|
||||
// parent chain must be from the same origin as this document.
|
||||
if (policy.LowerCaseEqualsLiteral("sameorigin")) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
httpChannel->GetURI(getter_AddRefs(uri));
|
||||
topDoc = do_GetInterface(curDocShellItem);
|
||||
nsCOMPtr<nsIURI> topUri;
|
||||
topDoc->NodePrincipal()->GetURI(getter_AddRefs(topUri));
|
||||
rv = ssm->CheckSameOriginURI(uri, topUri, true);
|
||||
if (NS_FAILED(rv))
|
||||
return false; /* wasn't same-origin */
|
||||
}
|
||||
|
||||
// If the X-Frame-Options value is "allow-from [uri]", then the top
|
||||
// frame in the parent chain must be from that origin
|
||||
if (isAllowFrom) {
|
||||
rv = NS_NewURI(getter_AddRefs(uri),
|
||||
Substring(policy, allowFromLen));
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
rv = ssm->CheckSameOriginURI(uri, topUri, true);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -63,6 +63,10 @@ MOCHITEST_FILES = \
|
||||
browserElement_XFrameOptionsSameOrigin.js \
|
||||
test_browserElement_inproc_XFrameOptionsSameOrigin.html \
|
||||
file_browserElement_XFrameOptionsSameOrigin.html \
|
||||
browserElement_XFrameOptionsAllowFrom.js \
|
||||
test_browserElement_inproc_XFrameOptionsAllowFrom.html \
|
||||
file_browserElement_XFrameOptionsAllowFrom.html \
|
||||
file_browserElement_XFrameOptionsAllowFrom.sjs \
|
||||
browserElement_Alert.js \
|
||||
test_browserElement_inproc_Alert.html \
|
||||
browserElement_AlertInFrame.js \
|
||||
@ -154,6 +158,7 @@ MOCHITEST_FILES += \
|
||||
test_browserElement_oop_XFrameOptions.html \
|
||||
test_browserElement_oop_XFrameOptionsDeny.html \
|
||||
test_browserElement_oop_XFrameOptionsSameOrigin.html \
|
||||
test_browserElement_oop_XFrameOptionsAllowFrom.html \
|
||||
test_browserElement_oop_Alert.html \
|
||||
test_browserElement_oop_AlertInFrame.html \
|
||||
test_browserElement_oop_TargetTop.html \
|
||||
|
@ -0,0 +1,53 @@
|
||||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 690168 - Support Allow-From notation for X-Frame-Options header.
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var initialScreenshot = null;
|
||||
|
||||
function runTest() {
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addPermission();
|
||||
var count = 0;
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.mozbrowser = true;
|
||||
iframe.height = '1000px';
|
||||
|
||||
// The innermost page we load will fire an alert when it successfully loads.
|
||||
iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
|
||||
switch (e.detail.message) {
|
||||
case 'step 1':
|
||||
// Make the page wait for us to unblock it (which we do after we finish
|
||||
// taking the screenshot).
|
||||
e.preventDefault();
|
||||
|
||||
iframe.getScreenshot().onsuccess = function(sshot) {
|
||||
if (initialScreenshot == null)
|
||||
initialScreenshot = sshot.target.result;
|
||||
e.detail.unblock();
|
||||
};
|
||||
break;
|
||||
case 'step 2':
|
||||
ok(false, 'cross origin page loaded');
|
||||
break;
|
||||
case 'finish':
|
||||
// The page has now attempted to load the X-Frame-Options page; take
|
||||
// another screenshot.
|
||||
iframe.getScreenshot().onsuccess = function(sshot) {
|
||||
is(sshot.target.result, initialScreenshot, "Screenshots should be identical");
|
||||
SimpleTest.finish();
|
||||
};
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
iframe.src = 'http://example.com/tests/dom/browser-element/mochitest/file_browserElement_XFrameOptionsAllowFrom.html';
|
||||
}
|
||||
|
||||
runTest();
|
@ -0,0 +1,43 @@
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<!-- Try to load in a frame a cross-origin page which sends:
|
||||
"X-Frame-Options: Allow-From http://mochi.test:8888/",
|
||||
and a cross-origin page which sends
|
||||
"X-Frame-Options: Allow-From http://example.com/". -->
|
||||
|
||||
<script>
|
||||
|
||||
// Make sure these iframes aren't too tall; they both need to fit inside the
|
||||
// iframe this page is contained in, without scrolling, in order for the test's
|
||||
// screenshots to work properly.
|
||||
|
||||
var frame_src = 'http://example.com/tests/dom/browser-element/mochitest/file_browserElement_XFrameOptionsAllowFrom.sjs';
|
||||
|
||||
var iframe1 = document.createElement('iframe');
|
||||
iframe1.height = '300px';
|
||||
var iframe2 = document.createElement('iframe');
|
||||
iframe2.height = '300px';
|
||||
document.body.appendChild(iframe1);
|
||||
document.body.appendChild(iframe2);
|
||||
|
||||
iframe1.addEventListener('load', function iframe1Load() {
|
||||
iframe1.removeEventListener('load', iframe1Load);
|
||||
// This causes our embedder to take a screenshot (and blocks until the
|
||||
// screenshot is completed).
|
||||
var iframe2Loaded = false;
|
||||
iframe2.addEventListener('load', function iframe2Load() {
|
||||
iframe2.removeEventListener('load', iframe2Load);
|
||||
iframe2Loaded = true;
|
||||
alert('finish');
|
||||
});
|
||||
|
||||
setTimeout(function() { iframe2.src = frame_src; }, 1000);
|
||||
});
|
||||
|
||||
|
||||
iframe1.src = frame_src + '?iframe1';
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,16 @@
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var content = 'step 1';
|
||||
if (request.queryString == "iframe1") {
|
||||
response.setHeader("X-Frame-Options", "Allow-From http://mochi.test:8888/")
|
||||
content = 'finish';
|
||||
} else {
|
||||
response.setHeader("X-Frame-Options", "Allow-From http://example.com")
|
||||
}
|
||||
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
|
||||
// Tests rely on this page not being entirely blank, because they take
|
||||
// screenshots to determine whether this page was loaded.
|
||||
response.write("<html><body>XFrameOptions test<script>alert('" + content + "')</script></body></html>");
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 690168</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_XFrameOptionsAllowFrom.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 690168</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_XFrameOptionsAllowFrom.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user