зеркало из https://github.com/mozilla/gecko-dev.git
Bug 783049 - CSP : use existing/old parser for X-Content-Security-Policy header, new/CSP 1.0 spec compliant parser for Content-Security-Policy header - Part 2 (r=bz)
This commit is contained in:
Родитель
21cfd6687a
Коммит
9b5cf4aea2
|
@ -2288,18 +2288,51 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
|||
}
|
||||
|
||||
nsAutoCString tCspHeaderValue, tCspROHeaderValue;
|
||||
nsAutoCString tCspOldHeaderValue, tCspOldROHeaderValue;
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
|
||||
if (httpChannel) {
|
||||
httpChannel->GetResponseHeader(
|
||||
NS_LITERAL_CSTRING("x-content-security-policy"),
|
||||
tCspHeaderValue);
|
||||
tCspOldHeaderValue);
|
||||
|
||||
httpChannel->GetResponseHeader(
|
||||
NS_LITERAL_CSTRING("x-content-security-policy-report-only"),
|
||||
tCspOldROHeaderValue);
|
||||
|
||||
httpChannel->GetResponseHeader(
|
||||
NS_LITERAL_CSTRING("content-security-policy"),
|
||||
tCspHeaderValue);
|
||||
|
||||
httpChannel->GetResponseHeader(
|
||||
NS_LITERAL_CSTRING("content-security-policy-report-only"),
|
||||
tCspROHeaderValue);
|
||||
}
|
||||
NS_ConvertASCIItoUTF16 cspHeaderValue(tCspHeaderValue);
|
||||
NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue);
|
||||
NS_ConvertASCIItoUTF16 cspOldHeaderValue(tCspOldHeaderValue);
|
||||
NS_ConvertASCIItoUTF16 cspOldROHeaderValue(tCspOldROHeaderValue);
|
||||
|
||||
// Until we want to turn on our CSP 1.0 spec compliant support
|
||||
// only use the 1.0 spec compliant headers if a pref to do so
|
||||
// is set (this lets us land CSP 1.0 support with tests without
|
||||
// having to turn it on before it's ready). When we turn on
|
||||
// CSP 1.0 in the release, we should remove this pref check.
|
||||
// This pref will never be set by default, it should only
|
||||
// be created/set by the CSP tests.
|
||||
if (!cspHeaderValue.IsEmpty() || !cspROHeaderValue.IsEmpty()) {
|
||||
bool specCompliantEnabled =
|
||||
Preferences::GetBool("security.csp.speccompliant");
|
||||
|
||||
// If spec compliant pref isn't set, pretend we never got
|
||||
// these headers.
|
||||
if (!specCompliantEnabled) {
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
("Got spec compliant CSP headers but pref was not set"));
|
||||
cspHeaderValue.Truncate();
|
||||
cspROHeaderValue.Truncate();
|
||||
}
|
||||
}
|
||||
|
||||
// ----- Figure out if we need to apply an app default CSP
|
||||
bool applyAppDefaultCSP = false;
|
||||
|
@ -2333,10 +2366,12 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
|||
PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("Failed to get app status from principal"));
|
||||
#endif
|
||||
|
||||
// If there's no CSP to apply go ahead and return early
|
||||
// If there's no CSP to apply, go ahead and return early
|
||||
if (!applyAppDefaultCSP &&
|
||||
cspHeaderValue.IsEmpty() &&
|
||||
cspROHeaderValue.IsEmpty()) {
|
||||
cspROHeaderValue.IsEmpty() &&
|
||||
cspOldHeaderValue.IsEmpty() &&
|
||||
cspOldROHeaderValue.IsEmpty()) {
|
||||
#ifdef PR_LOGGING
|
||||
nsCOMPtr<nsIURI> chanURI;
|
||||
aChannel->GetURI(getter_AddRefs(chanURI));
|
||||
|
@ -2383,34 +2418,63 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
|||
}
|
||||
|
||||
if (appCSP)
|
||||
csp->RefinePolicy(appCSP, chanURI);
|
||||
csp->RefinePolicy(appCSP, chanURI, true);
|
||||
}
|
||||
|
||||
// While we are supporting both CSP 1.0 and the x- headers, the 1.0 headers
|
||||
// take priority. If any spec-compliant headers are present, the x- headers
|
||||
// are ignored, and the spec compliant parser is used.
|
||||
bool cspSpecCompliant = (!cspHeaderValue.IsEmpty() || !cspROHeaderValue.IsEmpty());
|
||||
|
||||
// If the old header is present, warn that it will be deprecated.
|
||||
if (!cspOldHeaderValue.IsEmpty() || !cspOldROHeaderValue.IsEmpty()) {
|
||||
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
|
||||
"CSP", this,
|
||||
nsContentUtils::eDOM_PROPERTIES,
|
||||
"OldCSPHeaderDeprecated");
|
||||
|
||||
// Also, if the new headers AND the old headers were present, warn
|
||||
// that the old headers will be ignored.
|
||||
if (cspSpecCompliant) {
|
||||
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
|
||||
"CSP", this,
|
||||
nsContentUtils::eDOM_PROPERTIES,
|
||||
"BothCSPHeadersPresent");
|
||||
}
|
||||
}
|
||||
|
||||
// ----- if there's a full-strength CSP header, apply it.
|
||||
if (!cspHeaderValue.IsEmpty()) {
|
||||
bool applyCSPFromHeader =
|
||||
(( cspSpecCompliant && !cspHeaderValue.IsEmpty()) ||
|
||||
(!cspSpecCompliant && !cspOldHeaderValue.IsEmpty()));
|
||||
|
||||
if (applyCSPFromHeader) {
|
||||
// Need to tokenize the header value since multiple headers could be
|
||||
// concatenated into one comma-separated list of policies.
|
||||
// See RFC2616 section 4.2 (last paragraph)
|
||||
nsCharSeparatedTokenizer tokenizer(cspHeaderValue, ',');
|
||||
nsCharSeparatedTokenizer tokenizer(cspSpecCompliant ?
|
||||
cspHeaderValue :
|
||||
cspOldHeaderValue, ',');
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsSubstring& policy = tokenizer.nextToken();
|
||||
csp->RefinePolicy(policy, chanURI);
|
||||
csp->RefinePolicy(policy, chanURI, cspSpecCompliant);
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
("CSP refined with policy: \"%s\"",
|
||||
NS_ConvertUTF16toUTF8(policy).get()));
|
||||
("CSP refined with policy: \"%s\"",
|
||||
NS_ConvertUTF16toUTF8(policy).get()));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// ----- if there's a report-only CSP header, apply it
|
||||
if (!cspROHeaderValue.IsEmpty()) {
|
||||
if (( cspSpecCompliant && !cspROHeaderValue.IsEmpty()) ||
|
||||
(!cspSpecCompliant && !cspOldROHeaderValue.IsEmpty())) {
|
||||
// post a warning and skip report-only CSP when both read only and regular
|
||||
// CSP policies are present since CSP only allows one policy and it can't
|
||||
// be partially report-only.
|
||||
if (applyAppDefaultCSP || !cspHeaderValue.IsEmpty()) {
|
||||
if (applyAppDefaultCSP || applyCSPFromHeader) {
|
||||
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
|
||||
"CSP", this,
|
||||
nsContentUtils::eDOM_PROPERTIES,
|
||||
|
@ -2427,10 +2491,12 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
|||
// Need to tokenize the header value since multiple headers could be
|
||||
// concatenated into one comma-separated list of policies.
|
||||
// See RFC2616 section 4.2 (last paragraph)
|
||||
nsCharSeparatedTokenizer tokenizer(cspROHeaderValue, ',');
|
||||
nsCharSeparatedTokenizer tokenizer(cspSpecCompliant ?
|
||||
cspROHeaderValue :
|
||||
cspOldROHeaderValue, ',');
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsSubstring& policy = tokenizer.nextToken();
|
||||
csp->RefinePolicy(policy, chanURI);
|
||||
csp->RefinePolicy(policy, chanURI, cspSpecCompliant);
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
|
|
|
@ -1139,8 +1139,10 @@ GK_ATOM(withParam, "with-param")
|
|||
GK_ATOM(wizard, "wizard")
|
||||
GK_ATOM(wrap, "wrap")
|
||||
GK_ATOM(headerDNSPrefetchControl,"x-dns-prefetch-control")
|
||||
GK_ATOM(headerCSP, "x-content-security-policy")
|
||||
GK_ATOM(headerCSPReportOnly, "x-content-security-policy-report-only")
|
||||
GK_ATOM(headerOldCSP, "x-content-security-policy")
|
||||
GK_ATOM(headerOldCSPReportOnly, "x-content-security-policy-report-only")
|
||||
GK_ATOM(headerCSP, "content-security-policy")
|
||||
GK_ATOM(headerCSPReportOnly, "content-security-policy-report-only")
|
||||
GK_ATOM(headerXFO, "x-frame-options")
|
||||
GK_ATOM(x_western, "x-western")
|
||||
GK_ATOM(xml, "xml")
|
||||
|
|
|
@ -120,3 +120,7 @@ PluginHangUIWaitButton=Continue
|
|||
PluginHangUIStopButton=Stop plugin
|
||||
# LOCALIZATION NOTE: Do not translate "mozHidden", "mozVisibilityState", "hidden", or "visibilityState"
|
||||
PrefixedVisibilityApiWarning='mozHidden' and 'mozVisibilityState' are deprecated. Please use the unprefixed 'hidden' and 'visibilityState' instead.
|
||||
# LOCALIZATION NOTE: Do not translate "X-Content-Security-Policy", "X-Content-Security-Policy-Report-Only", "Content-Security-Policy" or "Content-Security-Policy-Report-Only"
|
||||
OldCSPHeaderDeprecated=The X-Content-Security-Policy and X-Content-Security-Report-Only headers will be deprecated in the future. Please use the Content-Security-Policy and Content-Security-Report-Only headers with CSP spec compliant syntax instead.
|
||||
# LOCALIZATION NOTE: Do not translate "X-Content-Security-Policy" or "Content-Security-Policy"
|
||||
BothCSPHeadersPresent=This site specified both an X-Content-Security-Policy/Report-Only header and a Content-Security-Policy/Report-Only header. The X-ContentSecurityPolicy/ReportOnly header(s) will be ignored.
|
|
@ -636,6 +636,10 @@ nsViewSourceChannel::GetResponseHeader(const nsACString & aHeader,
|
|||
nsCaseInsensitiveCStringComparator()) &&
|
||||
!aHeader.Equals(NS_LITERAL_CSTRING("X-Content-Security-Policy-Report-Only"),
|
||||
nsCaseInsensitiveCStringComparator()) &&
|
||||
!aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy"),
|
||||
nsCaseInsensitiveCStringComparator()) &&
|
||||
!aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy-Report-Only"),
|
||||
nsCaseInsensitiveCStringComparator()) &&
|
||||
!aHeader.Equals(NS_LITERAL_CSTRING("X-Frame-Options"),
|
||||
nsCaseInsensitiveCStringComparator())) {
|
||||
aValue.Truncate();
|
||||
|
|
Загрузка…
Ссылка в новой задаче