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
Родитель c881cf722e
Коммит cc2c6a3d27
3 изменённых файлов: 32 добавлений и 9 удалений

Просмотреть файл

@ -646,21 +646,26 @@ nsCSPParser::sourceExpression()
// mCurValue = "" // mCurValue = ""
resetCurValue(); 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()) { if (parsedScheme.IsEmpty()) {
// Resetting internal helpers, because we might already have parsed some of the host // Resetting internal helpers, because we might already have parsed some of the host
// when trying to parse a scheme. // when trying to parse a scheme.
resetCurChar(mCurToken); resetCurChar(mCurToken);
nsAutoCString scheme; nsAutoCString selfScheme;
mSelfURI->GetScheme(scheme); mSelfURI->GetScheme(selfScheme);
parsedScheme.AssignASCII(scheme.get()); parsedScheme.AssignASCII(selfScheme.get());
allowHttps = selfScheme.EqualsASCII("http");
} }
// At this point we are expecting a host to be parsed. // At this point we are expecting a host to be parsed.
// Trying to create a new nsCSPHost. // Trying to create a new nsCSPHost.
if (nsCSPHostSrc *cspHost = hostSource()) { if (nsCSPHostSrc *cspHost = hostSource()) {
// Do not forget to set the parsed scheme. // Do not forget to set the parsed scheme.
cspHost->setScheme(parsedScheme); cspHost->setScheme(parsedScheme, allowHttps);
return cspHost; return cspHost;
} }
// Error was reported in hostSource() // Error was reported in hostSource()

Просмотреть файл

@ -279,6 +279,7 @@ nsCSPSchemeSrc::toString(nsAString& outStr) const
nsCSPHostSrc::nsCSPHostSrc(const nsAString& aHost) nsCSPHostSrc::nsCSPHostSrc(const nsAString& aHost)
: mHost(aHost) : mHost(aHost)
, mAllowHttps(false)
{ {
ToLowerCase(mHost); ToLowerCase(mHost);
} }
@ -307,7 +308,16 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected
NS_ENSURE_SUCCESS(rv, false); NS_ENSURE_SUCCESS(rv, false);
if (!mScheme.IsEmpty() && if (!mScheme.IsEmpty() &&
!mScheme.EqualsASCII(scheme.get())) { !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 // 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()) { if (mPort.IsEmpty()) {
int32_t port = NS_GetDefaultPort(NS_ConvertUTF16toUTF8(mScheme).get()); int32_t port = NS_GetDefaultPort(NS_ConvertUTF16toUTF8(mScheme).get());
if (port != uriPort) { 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. // 4.7) Port matching: Compare the ports.
@ -431,10 +447,11 @@ nsCSPHostSrc::toString(nsAString& outStr) const
} }
void void
nsCSPHostSrc::setScheme(const nsAString& aScheme) nsCSPHostSrc::setScheme(const nsAString& aScheme, bool aAllowHttps)
{ {
mScheme = aScheme; mScheme = aScheme;
ToLowerCase(mScheme); ToLowerCase(mScheme);
mAllowHttps = aAllowHttps;
} }
void void

Просмотреть файл

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