mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 23:38:38 +09:00
Issue #1975 - Implement Origin header CSRF mitigation.
Backported from Mozilla bug 446344.
This commit is contained in:
parent
3e6cbc6af3
commit
faa778ec9d
6 changed files with 82 additions and 15 deletions
|
|
@ -1491,6 +1491,10 @@ pref("network.http.referer.XOriginTrimmingPolicy", 0);
|
|||
// 0=always send, 1=send iff base domains match, 2=send iff hosts match
|
||||
pref("network.http.referer.XOriginPolicy", 0);
|
||||
|
||||
// Include an origin header on non-GET and non-HEAD requests regardless of CORS
|
||||
// 0=never send, 1=send when same-origin only, 2=always send
|
||||
pref("network.http.sendOriginHeader", 0);
|
||||
|
||||
// Controls whether referrer attributes in <a>, <img>, <area>, <iframe>, and <link> are honoured
|
||||
pref("network.http.enablePerElementReferrer", true);
|
||||
|
||||
|
|
|
|||
|
|
@ -1398,22 +1398,10 @@ HttpBaseChannel::SetReferrerWithPolicy(nsIURI *referrer,
|
|||
referrer = referrerGrip.get();
|
||||
}
|
||||
|
||||
//
|
||||
// block referrer if not on our white list...
|
||||
//
|
||||
static const char *const referrerWhiteList[] = {
|
||||
"http",
|
||||
"https",
|
||||
"ftp",
|
||||
nullptr
|
||||
};
|
||||
match = false;
|
||||
const char *const *scheme = referrerWhiteList;
|
||||
for (; *scheme && !match; ++scheme) {
|
||||
rv = referrer->SchemeIs(*scheme, &match);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
// Enforce Referrer whitelist
|
||||
if (!IsReferrerSchemeAllowed(referrer)) {
|
||||
return NS_OK; // kick out....
|
||||
}
|
||||
if (!match) return NS_OK; // kick out....
|
||||
|
||||
//
|
||||
// Handle secure referrals.
|
||||
|
|
@ -2844,6 +2832,24 @@ HttpBaseChannel::AddCookiesToRequest()
|
|||
SetRequestHeader(nsDependentCString(nsHttp::Cookie), cookie, false);
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
HttpBaseChannel::IsReferrerSchemeAllowed(nsIURI *aReferrer)
|
||||
{
|
||||
NS_ENSURE_TRUE(aReferrer, false);
|
||||
|
||||
nsAutoCString scheme;
|
||||
nsresult rv = aReferrer->GetScheme(scheme);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
if (scheme.EqualsIgnoreCase("https") ||
|
||||
scheme.EqualsIgnoreCase("http") ||
|
||||
scheme.EqualsIgnoreCase("ftp")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
HttpBaseChannel::ShouldRewriteRedirectToGET(uint32_t httpStatus,
|
||||
nsHttpRequestHead::ParsedMethodType method)
|
||||
|
|
|
|||
|
|
@ -319,6 +319,8 @@ public:
|
|||
public: /* Necko internal use only... */
|
||||
bool IsNavigation();
|
||||
|
||||
static bool IsReferrerSchemeAllowed(nsIURI *aReferrer);
|
||||
|
||||
// Return whether upon a redirect code of httpStatus for method, the
|
||||
// request method should be rewritten to GET.
|
||||
static bool ShouldRewriteRedirectToGET(uint32_t httpStatus,
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ HTTP_ATOM(Lock_Token, "Lock-Token")
|
|||
HTTP_ATOM(Link, "Link")
|
||||
HTTP_ATOM(Location, "Location")
|
||||
HTTP_ATOM(Max_Forwards, "Max-Forwards")
|
||||
HTTP_ATOM(Origin, "Origin")
|
||||
HTTP_ATOM(Overwrite, "Overwrite")
|
||||
HTTP_ATOM(Pragma, "Pragma")
|
||||
HTTP_ATOM(Prefer, "Prefer")
|
||||
|
|
|
|||
|
|
@ -5710,6 +5710,7 @@ nsHttpChannel::BeginConnect()
|
|||
mRequestHead.SetHTTPS(isHttps);
|
||||
mRequestHead.SetOrigin(scheme, host, port);
|
||||
|
||||
SetOriginHeader();
|
||||
SetDoNotTrack();
|
||||
|
||||
NeckoOriginAttributes originAttributes;
|
||||
|
|
@ -7997,6 +7998,58 @@ nsHttpChannel::ResumeInternal()
|
|||
return NS_FAILED(rvTransaction) ? rvTransaction : rvCache;
|
||||
}
|
||||
|
||||
// Step 10 of HTTP-network-or-cache fetch
|
||||
void
|
||||
nsHttpChannel::SetOriginHeader()
|
||||
{
|
||||
if (mRequestHead.IsGet() || mRequestHead.IsHead()) {
|
||||
return;
|
||||
}
|
||||
nsAutoCString existingHeader;
|
||||
Unused << mRequestHead.GetHeader(nsHttp::Origin, existingHeader);
|
||||
if (!existingHeader.IsEmpty()) {
|
||||
LOG(("nsHttpChannel::SetOriginHeader Origin header already present"));
|
||||
return;
|
||||
}
|
||||
|
||||
DebugOnly<nsresult> rv;
|
||||
|
||||
// Instead of consulting Preferences::GetInt() all the time we
|
||||
// can cache the result to speed things up.
|
||||
static int32_t sSendOriginHeader = 0;
|
||||
static bool sIsInited = false;
|
||||
if (!sIsInited) {
|
||||
sIsInited = true;
|
||||
Preferences::AddIntVarCache(&sSendOriginHeader,
|
||||
"network.http.sendOriginHeader");
|
||||
}
|
||||
if (sSendOriginHeader == 0) {
|
||||
// Origin header suppressed by user setting
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> referrer;
|
||||
mLoadInfo->TriggeringPrincipal()->GetURI(getter_AddRefs(referrer));
|
||||
|
||||
nsAutoCString origin("null");
|
||||
if (referrer && IsReferrerSchemeAllowed(referrer)) {
|
||||
nsContentUtils::GetASCIIOrigin(referrer, origin);
|
||||
}
|
||||
|
||||
// Restrict Origin to same-origin loads if requested by user
|
||||
if (sSendOriginHeader == 1) {
|
||||
nsAutoCString currentOrigin;
|
||||
nsContentUtils::GetASCIIOrigin(mURI, currentOrigin);
|
||||
if (!origin.EqualsIgnoreCase(currentOrigin.get())) {
|
||||
// Origin header suppressed by user setting
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rv = mRequestHead.SetHeader(nsHttp::Origin, origin, false /* merge */);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpChannel::SetDoNotTrack()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -452,6 +452,7 @@ private:
|
|||
|
||||
void SetPushedStream(Http2PushedStreamWrapper *stream);
|
||||
|
||||
void SetOriginHeader();
|
||||
void SetDoNotTrack();
|
||||
|
||||
private:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue