CSP should only check host (not including path) when performing frame ancestors checks.

This has been explicitly stated in the CSP-3 spec.
This commit is contained in:
wolfbeast 2017-08-15 21:10:10 +02:00 • committed by Roy Tam
commit fd1bb58ea8
4 changed files with 19 additions and 0 deletions

View file

@ -136,6 +136,7 @@ nsCSPParser::nsCSPParser(cspTokens& aTokens,
, mUnsafeInlineKeywordSrc(nullptr) , mUnsafeInlineKeywordSrc(nullptr)
, mChildSrc(nullptr) , mChildSrc(nullptr)
, mFrameSrc(nullptr) , mFrameSrc(nullptr)
, mParsingFrameAncestorsDir(false)
, mTokens(aTokens) , mTokens(aTokens)
, mSelfURI(aSelfURI) , mSelfURI(aSelfURI)
, mPolicy(nullptr) , mPolicy(nullptr)
@ -807,6 +808,7 @@ nsCSPParser::sourceExpression()
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);
cspHost->setWithinFrameAncestorsDir(mParsingFrameAncestorsDir);
return cspHost; return cspHost;
} }
// Error was reported in hostSource() // Error was reported in hostSource()
@ -1209,6 +1211,9 @@ nsCSPParser::directive()
mStrictDynamic = false; mStrictDynamic = false;
mUnsafeInlineKeywordSrc = nullptr; mUnsafeInlineKeywordSrc = nullptr;
mParsingFrameAncestorsDir =
CSP_IsDirective(mCurDir[0], nsIContentSecurityPolicy::FRAME_ANCESTORS_DIRECTIVE);
// Try to parse all the srcs by handing the array off to directiveValue // Try to parse all the srcs by handing the array off to directiveValue
nsTArray<nsCSPBaseSrc*> srcs; nsTArray<nsCSPBaseSrc*> srcs;
directiveValue(srcs); directiveValue(srcs);

View file

@ -252,6 +252,10 @@ class nsCSPParser {
nsCSPChildSrcDirective* mChildSrc; nsCSPChildSrcDirective* mChildSrc;
nsCSPDirective* mFrameSrc; nsCSPDirective* mFrameSrc;
// cache variable to let nsCSPHostSrc know that it's within
// the frame-ancestors directive.
bool mParsingFrameAncestorsDir;
cspTokens mTokens; cspTokens mTokens;
nsIURI* mSelfURI; nsIURI* mSelfURI;
nsCSPPolicy* mPolicy; nsCSPPolicy* mPolicy;

View file

@ -503,6 +503,7 @@ nsCSPSchemeSrc::toString(nsAString& outStr) const
nsCSPHostSrc::nsCSPHostSrc(const nsAString& aHost) nsCSPHostSrc::nsCSPHostSrc(const nsAString& aHost)
: mHost(aHost) : mHost(aHost)
, mWithinFrameAncstorsDir(false)
{ {
ToLowerCase(mHost); ToLowerCase(mHost);
} }
@ -686,6 +687,11 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected
rv = url->GetFilePath(uriPath); rv = url->GetFilePath(uriPath);
NS_ENSURE_SUCCESS(rv, false); NS_ENSURE_SUCCESS(rv, false);
if (mWithinFrameAncstorsDir) {
// no path matching for frame-ancestors to not leak any path information.
return true;
}
nsString decodedUriPath; nsString decodedUriPath;
CSP_PercentDecodeStr(NS_ConvertUTF8toUTF16(uriPath), decodedUriPath); CSP_PercentDecodeStr(NS_ConvertUTF8toUTF16(uriPath), decodedUriPath);

View file

@ -256,6 +256,9 @@ class nsCSPHostSrc : public nsCSPBaseSrc {
void setPort(const nsAString& aPort); void setPort(const nsAString& aPort);
void appendPath(const nsAString &aPath); void appendPath(const nsAString &aPath);
inline void setWithinFrameAncestorsDir(bool aValue) const
{ mWithinFrameAncstorsDir = aValue; }
inline void getScheme(nsAString& outStr) const inline void getScheme(nsAString& outStr) const
{ outStr.Assign(mScheme); }; { outStr.Assign(mScheme); };
@ -273,6 +276,7 @@ class nsCSPHostSrc : public nsCSPBaseSrc {
nsString mHost; nsString mHost;
nsString mPort; nsString mPort;
nsString mPath; nsString mPath;
mutable bool mWithinFrameAncstorsDir;
}; };
/* =============== nsCSPKeywordSrc ============ */ /* =============== nsCSPKeywordSrc ============ */