2019-02-12 22:35:32 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef mozilla_dom_ReferrerInfo_h
|
|
|
|
#define mozilla_dom_ReferrerInfo_h
|
|
|
|
|
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsIReferrerInfo.h"
|
|
|
|
#include "nsISerializable.h"
|
|
|
|
#include "mozilla/net/ReferrerPolicy.h"
|
2019-05-02 15:34:52 +03:00
|
|
|
#include "nsReadableUtils.h"
|
|
|
|
#include "mozilla/Maybe.h"
|
2019-07-16 18:03:56 +03:00
|
|
|
#include "mozilla/HashFunctions.h"
|
2019-02-12 22:35:32 +03:00
|
|
|
|
|
|
|
#define REFERRERINFOF_CONTRACTID "@mozilla.org/referrer-info;1"
|
|
|
|
// 041a129f-10ce-4bda-a60d-e027a26d5ed0
|
|
|
|
#define REFERRERINFO_CID \
|
|
|
|
{ \
|
|
|
|
0x041a129f, 0x10ce, 0x4bda, { \
|
|
|
|
0xa6, 0x0d, 0xe0, 0x27, 0xa2, 0x6d, 0x5e, 0xd0 \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
class nsIURI;
|
|
|
|
class nsIChannel;
|
2019-05-02 15:34:52 +03:00
|
|
|
class nsILoadInfo;
|
2019-06-06 10:23:37 +03:00
|
|
|
class nsINode;
|
2019-06-13 23:37:34 +03:00
|
|
|
class nsIPrincipal;
|
2019-05-02 15:34:52 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
2019-07-16 18:03:56 +03:00
|
|
|
class StyleSheet;
|
2019-07-16 18:03:56 +03:00
|
|
|
class URLAndReferrerInfo;
|
2019-07-16 18:03:56 +03:00
|
|
|
|
2019-05-02 15:34:52 +03:00
|
|
|
namespace net {
|
|
|
|
class HttpBaseChannel;
|
|
|
|
class nsHttpChannel;
|
|
|
|
} // namespace net
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
using mozilla::Maybe;
|
2019-02-12 22:35:32 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
|
|
|
|
/**
|
2019-05-02 15:34:52 +03:00
|
|
|
* The ReferrerInfo class holds the raw referrer and potentially a referrer
|
|
|
|
* policy which allows to query the computed referrer which should be applied to
|
|
|
|
* a channel as the actual referrer value.
|
2019-02-12 22:35:32 +03:00
|
|
|
*
|
2019-05-02 15:34:52 +03:00
|
|
|
* The ReferrerInfo class solely contains readonly fields and represents a 1:1
|
|
|
|
* sync to the referrer header of the corresponding channel. In turn that means
|
|
|
|
* the class is immutable - so any modifications require to clone the current
|
|
|
|
* ReferrerInfo.
|
|
|
|
*
|
|
|
|
* For example if a request undergoes a redirect, the new channel
|
|
|
|
* will need a new ReferrerInfo clone with members being updated accordingly.
|
|
|
|
*/
|
|
|
|
|
2019-02-12 22:35:32 +03:00
|
|
|
class ReferrerInfo : public nsIReferrerInfo {
|
|
|
|
public:
|
2019-05-02 15:34:52 +03:00
|
|
|
ReferrerInfo();
|
|
|
|
|
|
|
|
explicit ReferrerInfo(
|
|
|
|
nsIURI* aOriginalReferrer, uint32_t aPolicy = mozilla::net::RP_Unset,
|
|
|
|
bool aSendReferrer = true,
|
|
|
|
const Maybe<nsCString>& aComputedReferrer = Maybe<nsCString>());
|
|
|
|
|
|
|
|
// create an exact copy of the ReferrerInfo
|
|
|
|
already_AddRefed<nsIReferrerInfo> Clone() const;
|
|
|
|
|
|
|
|
// create an copy of the ReferrerInfo with new referrer policy
|
|
|
|
already_AddRefed<nsIReferrerInfo> CloneWithNewPolicy(uint32_t aPolicy) const;
|
|
|
|
|
2019-07-04 22:58:35 +03:00
|
|
|
// create an copy of the ReferrerInfo with new send referrer
|
|
|
|
already_AddRefed<nsIReferrerInfo> CloneWithNewSendReferrer(
|
|
|
|
bool aSendReferrer) const;
|
|
|
|
|
2019-06-06 10:23:37 +03:00
|
|
|
// create an copy of the ReferrerInfo with new original referrer
|
|
|
|
already_AddRefed<nsIReferrerInfo> CloneWithNewOriginalReferrer(
|
|
|
|
nsIURI* aOriginalReferrer) const;
|
|
|
|
|
2019-07-16 18:03:56 +03:00
|
|
|
/*
|
|
|
|
* Helper function to create a new ReferrerInfo object from a given document
|
|
|
|
* and override referrer policy if needed (for example, when parsing link
|
|
|
|
* header or speculative loading).
|
|
|
|
*
|
|
|
|
* @param aDocument the document to init referrerInfo object.
|
|
|
|
* @param aPolicyOverride referrer policy to override if necessary.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static already_AddRefed<nsIReferrerInfo> CreateFromDocumentAndPolicyOverride(
|
|
|
|
Document* aDoc, uint32_t aPolicyOverride);
|
|
|
|
|
2019-06-13 23:37:34 +03:00
|
|
|
/*
|
|
|
|
* Implements step 3.1 and 3.3 of the Determine request's Referrer algorithm
|
|
|
|
* from the Referrer Policy specification.
|
|
|
|
*
|
|
|
|
* https://w3c.github.io/webappsec/specs/referrer-policy/#determine-requests-referrer
|
|
|
|
*/
|
|
|
|
static already_AddRefed<nsIReferrerInfo> CreateForFetch(
|
|
|
|
nsIPrincipal* aPrincipal, Document* aDoc);
|
|
|
|
|
2019-07-16 18:03:56 +03:00
|
|
|
/**
|
|
|
|
* Helper function to create new ReferrerInfo object from a given external
|
|
|
|
* stylesheet. The returned nsIReferrerInfo object will be used for any
|
|
|
|
* requests or resources referenced by the sheet.
|
|
|
|
*
|
|
|
|
* @param aSheet the stylesheet to init referrerInfo.
|
|
|
|
* @param aPolicy referrer policy from header if there's any.
|
|
|
|
*/
|
|
|
|
static already_AddRefed<nsIReferrerInfo> CreateForExternalCSSResources(
|
|
|
|
StyleSheet* aExternalSheet, uint32_t aPolicy = mozilla::net::RP_Unset);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper function to create new ReferrerInfo object from a given document.
|
|
|
|
* The returned nsIReferrerInfo object will be used for any requests or
|
|
|
|
* resources referenced by internal stylesheet (for example style="" or
|
|
|
|
* wrapped by <style> tag).
|
|
|
|
*
|
|
|
|
* @param aDocument the document to init referrerInfo object.
|
|
|
|
*/
|
|
|
|
static already_AddRefed<nsIReferrerInfo> CreateForInternalCSSResources(
|
|
|
|
Document* aDocument);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper function to create new ReferrerInfo object from a given document.
|
|
|
|
* The returned nsIReferrerInfo object will be used for any requests or
|
|
|
|
* resources referenced by SVG.
|
|
|
|
*
|
|
|
|
* @param aDocument the document to init referrerInfo object.
|
|
|
|
*/
|
|
|
|
static already_AddRefed<nsIReferrerInfo> CreateForSVGResources(
|
|
|
|
Document* aDocument);
|
|
|
|
|
2019-05-02 15:34:52 +03:00
|
|
|
/**
|
|
|
|
* Check whether the given referrer's scheme is allowed to be computed and
|
|
|
|
* sent. The whitelist schemes are: http, https, ftp.
|
|
|
|
*/
|
|
|
|
static bool IsReferrerSchemeAllowed(nsIURI* aReferrer);
|
|
|
|
|
2019-06-06 10:23:37 +03:00
|
|
|
/*
|
|
|
|
* The Referrer Policy should be inherited for nested browsing contexts that
|
|
|
|
* are not created from responses. Such as: srcdoc, data, blob.
|
|
|
|
*/
|
|
|
|
static bool ShouldResponseInheritReferrerInfo(nsIChannel* aChannel);
|
|
|
|
|
2019-05-02 15:34:52 +03:00
|
|
|
/*
|
|
|
|
* Check whether we need to hide referrer when leaving a .onion domain.
|
|
|
|
* Controlled by user pref: network.http.referer.hideOnionSource
|
|
|
|
*/
|
|
|
|
static bool HideOnionReferrerSource();
|
|
|
|
|
2019-06-15 00:10:41 +03:00
|
|
|
/*
|
|
|
|
* Check whether referrer is allowed to send in secure to insecure scenario.
|
|
|
|
*/
|
|
|
|
static nsresult HandleSecureToInsecureReferral(nsIURI* aOriginalURI,
|
|
|
|
nsIURI* aURI, uint32_t aPolicy,
|
|
|
|
bool& aAllowed);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if the given channel is cross-origin request
|
|
|
|
*
|
|
|
|
* Computing whether the request is cross-origin may be expensive, so please
|
|
|
|
* do that in cases where we're going to use this information later on.
|
|
|
|
*/
|
|
|
|
static bool IsCrossOriginRequest(nsIHttpChannel* aChannel);
|
|
|
|
|
2019-06-15 01:24:33 +03:00
|
|
|
/**
|
|
|
|
* Returns true if the given channel is suppressed by Referrer-Policy header
|
|
|
|
* and should set "null" to Origin header.
|
|
|
|
*/
|
|
|
|
static bool ShouldSetNullOriginHeader(net::HttpBaseChannel* aChannel,
|
|
|
|
nsIURI* aOriginURI);
|
|
|
|
|
2019-05-02 15:34:52 +03:00
|
|
|
/**
|
|
|
|
* Return default referrer policy which is controlled by user
|
|
|
|
* prefs:
|
|
|
|
* network.http.referer.defaultPolicy for regular mode
|
|
|
|
* network.http.referer.defaultPolicy.trackers for third-party trackers
|
|
|
|
* in regular mode
|
|
|
|
* network.http.referer.defaultPolicy.pbmode for private mode
|
|
|
|
* network.http.referer.defaultPolicy.trackers.pbmode for third-party trackers
|
|
|
|
* in private mode
|
|
|
|
*/
|
|
|
|
static uint32_t GetDefaultReferrerPolicy(nsIHttpChannel* aChannel = nullptr,
|
|
|
|
nsIURI* aURI = nullptr,
|
|
|
|
bool privateBrowsing = false);
|
2019-02-12 22:35:32 +03:00
|
|
|
|
2019-07-16 18:03:56 +03:00
|
|
|
/**
|
|
|
|
* Hash function for this object
|
|
|
|
*/
|
|
|
|
PLDHashNumber Hash() const;
|
|
|
|
|
2019-06-13 23:37:34 +03:00
|
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
2019-02-12 22:35:32 +03:00
|
|
|
NS_DECL_NSIREFERRERINFO
|
|
|
|
NS_DECL_NSISERIALIZABLE
|
|
|
|
|
|
|
|
private:
|
|
|
|
virtual ~ReferrerInfo() {}
|
|
|
|
|
2019-05-02 15:34:52 +03:00
|
|
|
ReferrerInfo(const ReferrerInfo& rhs);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Default referrer policy to use
|
|
|
|
*/
|
|
|
|
enum DefaultReferrerPolicy : uint32_t {
|
|
|
|
eDefaultPolicyNoReferrer = 0,
|
|
|
|
eDefaultPolicySameOrgin = 1,
|
|
|
|
eDefaultPolicyStrictWhenXorigin = 2,
|
|
|
|
eDefaultPolicyNoReferrerWhenDownGrade = 3,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Trimming policy when compute referrer, indicate how much information in the
|
|
|
|
* referrer will be sent. Order matters here.
|
|
|
|
*/
|
|
|
|
enum TrimmingPolicy : uint32_t {
|
|
|
|
ePolicyFullURI = 0,
|
|
|
|
ePolicySchemeHostPortPath = 1,
|
|
|
|
ePolicySchemeHostPort = 2,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Referrer sending policy, indicates type of action could trigger to send
|
|
|
|
* referrer header, not send at all, send only with user's action (click on a
|
|
|
|
* link) or send even with inline content request (image request).
|
|
|
|
* Order matters here.
|
|
|
|
*/
|
|
|
|
enum ReferrerSendingPolicy : uint32_t {
|
|
|
|
ePolicyNotSend = 0,
|
|
|
|
ePolicySendWhenUserTrigger = 1,
|
|
|
|
ePolicySendInlineContent = 2,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Sending referrer when cross origin policy, indicates when referrer should
|
|
|
|
* be send when compare 2 origins. Order matters here.
|
|
|
|
*/
|
|
|
|
enum XOriginSendingPolicy : uint32_t {
|
|
|
|
ePolicyAlwaysSend = 0,
|
|
|
|
ePolicySendWhenSameDomain = 1,
|
|
|
|
ePolicySendWhenSameHost = 2,
|
|
|
|
};
|
|
|
|
|
2019-06-06 10:23:37 +03:00
|
|
|
/**
|
|
|
|
* Check whether the given node has referrerpolicy attribute and parse
|
|
|
|
* referrer policy from the attribute.
|
|
|
|
* Currently, referrerpolicy attribute is supported in a, area, img, iframe,
|
|
|
|
* script, or link element.
|
|
|
|
*/
|
|
|
|
void GetReferrerPolicyFromAtribute(nsINode* aNode, uint32_t& aPolicy) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if node has a rel="noreferrer" attribute.
|
|
|
|
*/
|
|
|
|
bool HasRelNoReferrer(nsINode* aNode) const;
|
|
|
|
|
2019-05-02 15:34:52 +03:00
|
|
|
/*
|
|
|
|
* Handle user controlled pref network.http.referer.XOriginPolicy
|
|
|
|
*/
|
|
|
|
nsresult HandleUserXOriginSendingPolicy(nsIURI* aURI, nsIURI* aReferrer,
|
|
|
|
bool& aAllowed) const;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Handle user controlled pref network.http.sendRefererHeader
|
|
|
|
*/
|
|
|
|
nsresult HandleUserReferrerSendingPolicy(nsIHttpChannel* aChannel,
|
|
|
|
bool& aAllowed) const;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Compute trimming policy from user controlled prefs.
|
|
|
|
* This function is called when we already made sure a nonempty referrer is
|
|
|
|
* allowed to send.
|
|
|
|
*/
|
|
|
|
TrimmingPolicy ComputeTrimmingPolicy(nsIHttpChannel* aChannel) const;
|
|
|
|
|
|
|
|
// HttpBaseChannel could access IsInitialized() and ComputeReferrer();
|
|
|
|
friend class mozilla::net::HttpBaseChannel;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Compute referrer for a given channel. The computation result then will be
|
|
|
|
* stored in this class and then used to set the actual referrer header of
|
|
|
|
* the channel. The computation could be controlled by sereral user prefs
|
|
|
|
* which is defined in all.js (see all.js for more details):
|
|
|
|
* network.http.sendRefererHeader
|
|
|
|
* network.http.referer.spoofSource
|
|
|
|
* network.http.referer.hideOnionSource
|
|
|
|
* network.http.referer.XOriginPolicy
|
|
|
|
* network.http.referer.trimmingPolicy
|
|
|
|
* network.http.referer.XOriginTrimmingPolicy
|
|
|
|
*/
|
|
|
|
nsresult ComputeReferrer(nsIHttpChannel* aChannel);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check whether the ReferrerInfo has been initialized or not.
|
|
|
|
*/
|
|
|
|
bool IsInitialized() { return mInitialized; }
|
|
|
|
|
2019-06-06 10:23:37 +03:00
|
|
|
// nsHttpChannel, Document could access IsPolicyOverrided();
|
2019-05-02 15:34:52 +03:00
|
|
|
friend class mozilla::net::nsHttpChannel;
|
2019-06-06 10:23:37 +03:00
|
|
|
friend class mozilla::dom::Document;
|
2019-05-02 15:34:52 +03:00
|
|
|
/*
|
|
|
|
* Check whether if unset referrer policy is overrided by default or not
|
|
|
|
*/
|
|
|
|
bool IsPolicyOverrided() { return mOverridePolicyByDefault; }
|
|
|
|
|
2019-07-09 20:47:22 +03:00
|
|
|
/*
|
|
|
|
* Get origin string from a given valid referrer URI (http, https, ftp)
|
|
|
|
*
|
|
|
|
* @aReferrer - the full referrer URI
|
|
|
|
* @aResult - the resulting aReferrer in string format.
|
|
|
|
*/
|
|
|
|
nsresult GetOriginFromReferrerURI(nsIURI* aReferrer,
|
|
|
|
nsACString& aResult) const;
|
|
|
|
|
2019-05-02 15:34:52 +03:00
|
|
|
/*
|
|
|
|
* Trim a given referrer with a given a trimming policy,
|
|
|
|
*/
|
2019-07-09 20:47:22 +03:00
|
|
|
nsresult TrimReferrerWithPolicy(nsIURI* aReferrer,
|
2019-05-02 15:34:52 +03:00
|
|
|
TrimmingPolicy aTrimmingPolicy,
|
|
|
|
nsACString& aResult) const;
|
|
|
|
|
2019-07-09 20:47:22 +03:00
|
|
|
/*
|
|
|
|
* Limit referrer length using the following ruleset:
|
|
|
|
* - If the length of referrer URL is over max length, strip down to origin.
|
|
|
|
* - If the origin is still over max length, remove the referrer entirely.
|
|
|
|
*
|
|
|
|
* This function comlements TrimReferrerPolicy and needs to be called right
|
|
|
|
* after TrimReferrerPolicy.
|
|
|
|
*
|
|
|
|
* @aChannel - used to query information needed for logging to the console.
|
|
|
|
* @aReferrer - the full referrer URI; needs to be identical to aReferrer
|
|
|
|
* passed to TrimReferrerPolicy.
|
|
|
|
* @aTrimmingPolicy - represents the trimming policy which was applied to the
|
|
|
|
* referrer; needs to be identical to aTrimmingPolicy
|
|
|
|
* passed to TrimReferrerPolicy.
|
|
|
|
* @aInAndOutTrimmedReferrer - an in and outgoing argument representing the
|
|
|
|
* referrer value. Please pass the result of
|
|
|
|
* TrimReferrerWithPolicy as
|
|
|
|
* aInAndOutTrimmedReferrer which will then be
|
|
|
|
* reduced to the origin or completely truncated
|
|
|
|
* in case the referrer value exceeds the length
|
|
|
|
* limitation.
|
|
|
|
*/
|
|
|
|
nsresult LimitReferrerLength(nsIHttpChannel* aChannel, nsIURI* aReferrer,
|
|
|
|
TrimmingPolicy aTrimmingPolicy,
|
|
|
|
nsACString& aInAndOutTrimmedReferrer) const;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Write message to the error console
|
|
|
|
*/
|
|
|
|
void LogMessageToConsole(nsIHttpChannel* aChannel, const char* aMsg,
|
|
|
|
const nsTArray<nsString>& aParams) const;
|
|
|
|
|
2019-07-16 18:03:56 +03:00
|
|
|
friend class mozilla::URLAndReferrerInfo;
|
|
|
|
|
2019-02-12 22:35:32 +03:00
|
|
|
nsCOMPtr<nsIURI> mOriginalReferrer;
|
2019-05-02 15:34:52 +03:00
|
|
|
|
2019-02-12 22:35:32 +03:00
|
|
|
uint32_t mPolicy;
|
|
|
|
|
|
|
|
// Indicates if the referrer should be sent or not even when it's available
|
|
|
|
// (default is true).
|
|
|
|
bool mSendReferrer;
|
2019-05-02 15:34:52 +03:00
|
|
|
|
|
|
|
// Since the ReferrerInfo is immutable, we use this member as a helper to
|
|
|
|
// ensure no one can call e.g. init() twice to modify state of the
|
|
|
|
// ReferrerInfo.
|
|
|
|
bool mInitialized;
|
|
|
|
|
|
|
|
// Indicates if unset referrer policy is overrided by default
|
|
|
|
bool mOverridePolicyByDefault;
|
|
|
|
|
|
|
|
// Store a computed referrer for a given channel
|
|
|
|
Maybe<nsCString> mComputedReferrer;
|
2019-02-12 22:35:32 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // mozilla_dom_ReferrerInfo_h
|