mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-02 05:17:31 +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
|
// 0=always send, 1=send iff base domains match, 2=send iff hosts match
|
||||||
pref("network.http.referer.XOriginPolicy", 0);
|
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
|
// Controls whether referrer attributes in <a>, <img>, <area>, <iframe>, and <link> are honoured
|
||||||
pref("network.http.enablePerElementReferrer", true);
|
pref("network.http.enablePerElementReferrer", true);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1398,22 +1398,10 @@ HttpBaseChannel::SetReferrerWithPolicy(nsIURI *referrer,
|
||||||
referrer = referrerGrip.get();
|
referrer = referrerGrip.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Enforce Referrer whitelist
|
||||||
// block referrer if not on our white list...
|
if (!IsReferrerSchemeAllowed(referrer)) {
|
||||||
//
|
return NS_OK; // kick out....
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
if (!match) return NS_OK; // kick out....
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Handle secure referrals.
|
// Handle secure referrals.
|
||||||
|
|
@ -2844,6 +2832,24 @@ HttpBaseChannel::AddCookiesToRequest()
|
||||||
SetRequestHeader(nsDependentCString(nsHttp::Cookie), cookie, false);
|
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
|
bool
|
||||||
HttpBaseChannel::ShouldRewriteRedirectToGET(uint32_t httpStatus,
|
HttpBaseChannel::ShouldRewriteRedirectToGET(uint32_t httpStatus,
|
||||||
nsHttpRequestHead::ParsedMethodType method)
|
nsHttpRequestHead::ParsedMethodType method)
|
||||||
|
|
|
||||||
|
|
@ -319,6 +319,8 @@ public:
|
||||||
public: /* Necko internal use only... */
|
public: /* Necko internal use only... */
|
||||||
bool IsNavigation();
|
bool IsNavigation();
|
||||||
|
|
||||||
|
static bool IsReferrerSchemeAllowed(nsIURI *aReferrer);
|
||||||
|
|
||||||
// Return whether upon a redirect code of httpStatus for method, the
|
// Return whether upon a redirect code of httpStatus for method, the
|
||||||
// request method should be rewritten to GET.
|
// request method should be rewritten to GET.
|
||||||
static bool ShouldRewriteRedirectToGET(uint32_t httpStatus,
|
static bool ShouldRewriteRedirectToGET(uint32_t httpStatus,
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ HTTP_ATOM(Lock_Token, "Lock-Token")
|
||||||
HTTP_ATOM(Link, "Link")
|
HTTP_ATOM(Link, "Link")
|
||||||
HTTP_ATOM(Location, "Location")
|
HTTP_ATOM(Location, "Location")
|
||||||
HTTP_ATOM(Max_Forwards, "Max-Forwards")
|
HTTP_ATOM(Max_Forwards, "Max-Forwards")
|
||||||
|
HTTP_ATOM(Origin, "Origin")
|
||||||
HTTP_ATOM(Overwrite, "Overwrite")
|
HTTP_ATOM(Overwrite, "Overwrite")
|
||||||
HTTP_ATOM(Pragma, "Pragma")
|
HTTP_ATOM(Pragma, "Pragma")
|
||||||
HTTP_ATOM(Prefer, "Prefer")
|
HTTP_ATOM(Prefer, "Prefer")
|
||||||
|
|
|
||||||
|
|
@ -5710,6 +5710,7 @@ nsHttpChannel::BeginConnect()
|
||||||
mRequestHead.SetHTTPS(isHttps);
|
mRequestHead.SetHTTPS(isHttps);
|
||||||
mRequestHead.SetOrigin(scheme, host, port);
|
mRequestHead.SetOrigin(scheme, host, port);
|
||||||
|
|
||||||
|
SetOriginHeader();
|
||||||
SetDoNotTrack();
|
SetDoNotTrack();
|
||||||
|
|
||||||
NeckoOriginAttributes originAttributes;
|
NeckoOriginAttributes originAttributes;
|
||||||
|
|
@ -7997,6 +7998,58 @@ nsHttpChannel::ResumeInternal()
|
||||||
return NS_FAILED(rvTransaction) ? rvTransaction : rvCache;
|
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
|
void
|
||||||
nsHttpChannel::SetDoNotTrack()
|
nsHttpChannel::SetDoNotTrack()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -452,6 +452,7 @@ private:
|
||||||
|
|
||||||
void SetPushedStream(Http2PushedStreamWrapper *stream);
|
void SetPushedStream(Http2PushedStreamWrapper *stream);
|
||||||
|
|
||||||
|
void SetOriginHeader();
|
||||||
void SetDoNotTrack();
|
void SetDoNotTrack();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue