Bug 826805 - CSP: Allow http and https for scheme-less sources (r=dveditz)

This commit is contained in:
Christoph Kerschbaumer 2014-11-05 17:45:54 -08:00
parent 2981e835d5
commit 825f6f14af
3 changed files with 32 additions and 9 deletions

View File

@ -646,21 +646,26 @@ nsCSPParser::sourceExpression()
// mCurValue = ""
resetCurValue();
// If mCurToken does not provide a scheme, we apply the scheme from selfURI
// If mCurToken does not provide a scheme (scheme-less source), we apply the scheme
// from selfURI but we also need to remember if the protected resource is http, in
// which case we should allow https loads, see:
// http://www.w3.org/TR/CSP2/#match-source-expression
bool allowHttps = false;
if (parsedScheme.IsEmpty()) {
// Resetting internal helpers, because we might already have parsed some of the host
// when trying to parse a scheme.
resetCurChar(mCurToken);
nsAutoCString scheme;
mSelfURI->GetScheme(scheme);
parsedScheme.AssignASCII(scheme.get());
nsAutoCString selfScheme;
mSelfURI->GetScheme(selfScheme);
parsedScheme.AssignASCII(selfScheme.get());
allowHttps = selfScheme.EqualsASCII("http");
}
// At this point we are expecting a host to be parsed.
// Trying to create a new nsCSPHost.
if (nsCSPHostSrc *cspHost = hostSource()) {
// Do not forget to set the parsed scheme.
cspHost->setScheme(parsedScheme);
cspHost->setScheme(parsedScheme, allowHttps);
return cspHost;
}
// Error was reported in hostSource()

View File

@ -279,6 +279,7 @@ nsCSPSchemeSrc::toString(nsAString& outStr) const
nsCSPHostSrc::nsCSPHostSrc(const nsAString& aHost)
: mHost(aHost)
, mAllowHttps(false)
{
ToLowerCase(mHost);
}
@ -307,7 +308,16 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected
NS_ENSURE_SUCCESS(rv, false);
if (!mScheme.IsEmpty() &&
!mScheme.EqualsASCII(scheme.get())) {
return false;
// We should not return false for scheme-less sources where the protected resource
// is http and the load is https, see:
// http://www.w3.org/TR/CSP2/#match-source-expression
bool isHttpsScheme =
(NS_SUCCEEDED(aUri->SchemeIs("https", &isHttpsScheme)) && isHttpsScheme);
if (!(isHttpsScheme && mAllowHttps)) {
return false;
}
}
// The host in nsCSpHostSrc should never be empty. In case we are enforcing
@ -386,7 +396,13 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected
if (mPort.IsEmpty()) {
int32_t port = NS_GetDefaultPort(NS_ConvertUTF16toUTF8(mScheme).get());
if (port != uriPort) {
return false;
// We should not return false for scheme-less sources where the protected resource
// is http and the load is https, see: http://www.w3.org/TR/CSP2/#match-source-expression
// BUT, we only allow scheme-less sources to be upgraded from http to https if CSP
// does not explicitly define a port.
if (!(uriPort == NS_GetDefaultPort("https") && mAllowHttps)) {
return false;
}
}
}
// 4.7) Port matching: Compare the ports.
@ -431,10 +447,11 @@ nsCSPHostSrc::toString(nsAString& outStr) const
}
void
nsCSPHostSrc::setScheme(const nsAString& aScheme)
nsCSPHostSrc::setScheme(const nsAString& aScheme, bool aAllowHttps)
{
mScheme = aScheme;
ToLowerCase(mScheme);
mAllowHttps = aAllowHttps;
}
void

View File

@ -220,7 +220,7 @@ class nsCSPHostSrc : public nsCSPBaseSrc {
bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const;
void toString(nsAString& outStr) const;
void setScheme(const nsAString& aScheme);
void setScheme(const nsAString& aScheme, bool aAllowHttps = false);
void setPort(const nsAString& aPort);
void appendPath(const nsAString &aPath);
@ -229,6 +229,7 @@ class nsCSPHostSrc : public nsCSPBaseSrc {
nsString mHost;
nsString mPort;
nsString mPath;
bool mAllowHttps;
};
/* =============== nsCSPKeywordSrc ============ */