From befc43a124da05eee24f1164bd70d480cb3aae2d Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Mon, 29 Feb 2016 14:50:20 -0500 Subject: [PATCH] Bug 1251873 - Store the trimmed referrer URL on HTTP channel if a trimming referrer policy is in effect; r=mcmanus Failure to do this will result in the consumers of nsIHttpChannel::GetReferrer() observing the wrong referrer. The test in this patch shows the scenarios which would fail under such conditions. --- netwerk/protocol/http/HttpBaseChannel.cpp | 6 ++ netwerk/test/unit/test_referrer_policy.js | 77 +++++++++++++++++++++++ netwerk/test/unit/xpcshell.ini | 1 + 3 files changed, 84 insertions(+) create mode 100644 netwerk/test/unit/test_referrer_policy.js diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index 47c5c1a5e28b..1e0c03a6c35b 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -1505,6 +1505,12 @@ HttpBaseChannel::SetReferrerWithPolicy(nsIURI *referrer, break; } + // If any user trimming policy is in effect, use the trimmed URI. + if (userReferrerTrimmingPolicy) { + rv = NS_NewURI(getter_AddRefs(clone), spec); + if (NS_FAILED(rv)) return rv; + } + // finally, remember the referrer URI and set the Referer header. rv = SetRequestHeader(NS_LITERAL_CSTRING("Referer"), spec, false); if (NS_FAILED(rv)) return rv; diff --git a/netwerk/test/unit/test_referrer_policy.js b/netwerk/test/unit/test_referrer_policy.js new file mode 100644 index 000000000000..a34ca27265f3 --- /dev/null +++ b/netwerk/test/unit/test_referrer_policy.js @@ -0,0 +1,77 @@ +Cu.import("resource://gre/modules/NetUtil.jsm"); + +function test_policy(test) { + do_print("Running test: " + test.toSource()); + + var uri = NetUtil.newURI(test.url, "", null) + var chan = NetUtil.newChannel({ + uri: uri, + loadUsingSystemPrincipal: true + }); + + var referrer = NetUtil.newURI(test.referrer, "", null); + chan.QueryInterface(Components.interfaces.nsIHttpChannel); + chan.setReferrerWithPolicy(referrer, test.policy); + if (test.expectedHeader === undefined) { + try { + chan.getRequestHeader("Referer"); + do_throw("Should not find a Referer header!"); + } catch(e) { + } + do_check_eq(chan.referrer, null); + } else { + var header = chan.getRequestHeader("Referer"); + do_check_eq(header, test.expectedHeader); + do_check_eq(chan.referrer.spec, test.expectedReferrerSpec); + } +} + +const nsIHttpChannel = Ci.nsIHttpChannel; +var gTests = [ + { + policy: nsIHttpChannel.REFERRER_POLICY_DEFAULT, + url: "https://test.example/foo", + referrer: "https://test.example/referrer", + expectedHeader: "https://test.example/referrer", + expectedReferrerSpec: "https://test.example/referrer" + }, + { + policy: nsIHttpChannel.REFERRER_POLICY_DEFAULT, + url: "http://test.example/foo", + referrer: "https://test.example/referrer", + expectedHeader: undefined, + expectedReferrerSpec: undefined + }, + { + policy: nsIHttpChannel.REFERRER_POLICY_NO_REFERRER, + url: "https://test.example/foo", + referrer: "https://test.example/referrer", + expectedHeader: undefined, + expectedReferrerSpec: undefined + }, + { + policy: nsIHttpChannel.REFERRER_POLICY_ORIGIN, + url: "https://test.example/foo", + referrer: "https://test.example/referrer", + expectedHeader: "https://test.example", + expectedReferrerSpec: "https://test.example/" + }, + { + policy: nsIHttpChannel.REFERRER_POLICY_UNSAFE_URL, + url: "https://test.example/foo", + referrer: "https://test.example/referrer", + expectedHeader: "https://test.example/referrer", + expectedReferrerSpec: "https://test.example/referrer" + }, + { + policy: nsIHttpChannel.REFERRER_POLICY_UNSAFE_URL, + url: "http://test.example/foo", + referrer: "https://test.example/referrer", + expectedHeader: "https://test.example/referrer", + expectedReferrerSpec: "https://test.example/referrer" + }, +]; + +function run_test() { + gTests.forEach(test => test_policy(test)); +} diff --git a/netwerk/test/unit/xpcshell.ini b/netwerk/test/unit/xpcshell.ini index 4df4f806ef01..9dbace1e267d 100644 --- a/netwerk/test/unit/xpcshell.ini +++ b/netwerk/test/unit/xpcshell.ini @@ -315,6 +315,7 @@ skip-if = os == "android" [test_about_networking.js] [test_ping_aboutnetworking.js] [test_referrer.js] +[test_referrer_policy.js] [test_predictor.js] # Android version detection w/in gecko does not work right on infra, so we just # disable this test on all android versions, even though it's enabled on 2.3+ in