// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/csp/content_security_policy.h"

#include "base/string_util.h"
#include "base/values.h"
#include "cobalt/csp/directive_list.h"
#include "cobalt/csp/source.h"

namespace cobalt {
namespace csp {

namespace {

ReferrerPolicy MergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b) {
  // If there are conflicting policies, err on the side of security, i.e.
  // send no referrer. This could happen if there is a CSP policy in the
  // response headers from the server and then a different one in a <meta>
  // in the document.
  if (a != b) {
    return kReferrerPolicyNoReferrer;
  } else {
    return a;
  }
}

// Macros for iterating over the CSP's policies_ list and
// calling a given function.
#define FOR_ALL_POLICIES_1(AllowFunc, arg0)               \
  for (PolicyList::const_iterator it = policies_.begin(); \
       it != policies_.end(); ++it) {                     \
    if (!(*it)->AllowFunc((arg0))) return false;          \
  }                                                       \
  return true

#define FOR_ALL_POLICIES_3(AllowFunc, arg0, arg1, arg2)                  \
  for (PolicyList::const_iterator it = policies_.begin();                \
       it != policies_.end(); ++it) {                                    \
    if ((*it)->AllowFunc((arg0), (arg1), (arg2)) == false) return false; \
  }                                                                      \
  return true

#define FOR_ALL_POLICIES_4(AllowFunc, arg0, arg1, arg2, arg3)        \
  for (PolicyList::const_iterator it = policies_.begin();            \
       it != policies_.end(); ++it) {                                \
    if ((*it)->AllowFunc((arg0), (arg1), (arg2), (arg3)) == false) { \
      return false;                                                  \
    }                                                                \
  }                                                                  \
  return true

// Similar to above but templatized on a member variable.
// Used by CheckDigest().
template <bool (DirectiveList::*allowed)(const HashValue&) const>
bool IsAllowedByAllWithHash(const ContentSecurityPolicy::PolicyList& policies,
                            const HashValue& hash_value) {
  for (ContentSecurityPolicy::PolicyList::const_iterator it = policies.begin();
       it != policies.end(); ++it) {
    if (!(*it->*allowed)(hash_value)) {
      return false;
    }
  }
  return true;
}

template <bool (DirectiveList::*allowed)(const HashValue&) const>
bool CheckDigest(const std::string& source, uint8 hash_algorithms_used,
                 const ContentSecurityPolicy::PolicyList& policies) {
  if (hash_algorithms_used == kHashAlgorithmNone) {
    return false;
  }

  HashAlgorithm valid_hash_algorithms[] = {
      kHashAlgorithmSha256, kHashAlgorithmSha384, kHashAlgorithmSha512,
  };

  for (size_t i = 0; i < arraysize(valid_hash_algorithms); ++i) {
    DigestValue digest;
    if (valid_hash_algorithms[i] & hash_algorithms_used) {
      bool digest_success = ComputeDigest(
          valid_hash_algorithms[i], source.c_str(), source.length(), &digest);
      if (digest_success &&
          IsAllowedByAllWithHash<allowed>(
              policies, HashValue(valid_hash_algorithms[i], digest))) {
        return true;
      }
    }
  }

  return false;
}

}  // namespace

ResponseHeaders::ResponseHeaders(
    const scoped_refptr<net::HttpResponseHeaders>& response) {
  response->GetNormalizedHeader("Content-Security-Policy",
                                &content_security_policy_);
  response->GetNormalizedHeader("Content-Security-Policy-Report-Only",
                                &content_security_policy_report_only_);
}

// CSP Level 1 Directives
const char ContentSecurityPolicy::kConnectSrc[] = "connect-src";
const char ContentSecurityPolicy::kDefaultSrc[] = "default-src";
const char ContentSecurityPolicy::kFontSrc[] = "font-src";
const char ContentSecurityPolicy::kFrameSrc[] = "frame-src";
const char ContentSecurityPolicy::kImgSrc[] = "img-src";
const char ContentSecurityPolicy::kMediaSrc[] = "media-src";
const char ContentSecurityPolicy::kObjectSrc[] = "object-src";
const char ContentSecurityPolicy::kReportURI[] = "report-uri";
const char ContentSecurityPolicy::kSandbox[] = "sandbox";
const char ContentSecurityPolicy::kScriptSrc[] = "script-src";
const char ContentSecurityPolicy::kStyleSrc[] = "style-src";

// CSP Level 2 Directives
const char ContentSecurityPolicy::kBaseURI[] = "base-uri";
const char ContentSecurityPolicy::kChildSrc[] = "child-src";
const char ContentSecurityPolicy::kFormAction[] = "form-action";
const char ContentSecurityPolicy::kFrameAncestors[] = "frame-ancestors";
const char ContentSecurityPolicy::kPluginTypes[] = "plugin-types";
const char ContentSecurityPolicy::kReflectedXSS[] = "reflected-xss";
const char ContentSecurityPolicy::kReferrer[] = "referrer";

// Custom Cobalt directive to enforce navigation restrictions.
const char ContentSecurityPolicy::kLocationSrc[] = "h5vcc-location-src";

// CSP Editor's Draft:
// https://w3c.github.io/webappsec/specs/content-security-policy
const char ContentSecurityPolicy::kManifestSrc[] = "manifest-src";

// Mixed Content Directive
// https://w3c.github.io/webappsec/specs/mixedcontent/#strict-mode
const char ContentSecurityPolicy::kBlockAllMixedContent[] =
    "block-all-mixed-content";

// https://w3c.github.io/webappsec/specs/upgrade/
const char ContentSecurityPolicy::kUpgradeInsecureRequests[] =
    "upgrade-insecure-requests";

// Suborigin Directive
// https://metromoxie.github.io/webappsec/specs/suborigins/index.html
const char ContentSecurityPolicy::kSuborigin[] = "suborigin";

// clang-format off
bool ContentSecurityPolicy::IsDirectiveName(const std::string& name) {
  std::string lower_name = StringToLowerASCII(name);
  return (lower_name == kConnectSrc ||
          lower_name == kDefaultSrc ||
          lower_name == kFontSrc ||
          lower_name == kFrameSrc ||
          lower_name == kImgSrc ||
          lower_name == kLocationSrc ||
          lower_name == kMediaSrc ||
          lower_name == kObjectSrc ||
          lower_name == kReportURI ||
          lower_name == kSandbox ||
          lower_name == kSuborigin ||
          lower_name == kScriptSrc ||
          lower_name == kStyleSrc ||
          lower_name == kBaseURI ||
          lower_name == kChildSrc ||
          lower_name == kFormAction ||
          lower_name == kFrameAncestors ||
          lower_name == kPluginTypes ||
          lower_name == kReflectedXSS ||
          lower_name == kReferrer ||
          lower_name == kManifestSrc ||
          lower_name == kBlockAllMixedContent ||
          lower_name == kUpgradeInsecureRequests);
}
// clang-format on

ContentSecurityPolicy::ContentSecurityPolicy(
    const GURL& url, const ViolationCallback& violation_callback)
    : violation_callback_(violation_callback),
      script_hash_algorithms_used_(0),
      style_hash_algorithms_used_(0),
      enforce_strict_mixed_content_checking_(false),
      referrer_policy_(kReferrerPolicyDefault) {
  NotifyUrlChanged(url);
}

ContentSecurityPolicy::~ContentSecurityPolicy() {}

void ContentSecurityPolicy::OnReceiveHeaders(const ResponseHeaders& headers) {
  if (!headers.content_security_policy().empty()) {
    AddPolicyFromHeaderValue(headers.content_security_policy(),
                             kHeaderTypeEnforce, kHeaderSourceHTTP);
  }
  if (!headers.content_security_policy_report_only().empty()) {
    AddPolicyFromHeaderValue(headers.content_security_policy_report_only(),
                             kHeaderTypeReport, kHeaderSourceHTTP);
  }
}

void ContentSecurityPolicy::OnReceiveHeader(const std::string& header,
                                            HeaderType type,
                                            HeaderSource source) {
  AddPolicyFromHeaderValue(header, type, source);
}

bool ContentSecurityPolicy::UrlMatchesSelf(const GURL& url) const {
  return self_source_->Matches(url, kDidNotRedirect);
}

bool ContentSecurityPolicy::SchemeMatchesSelf(const GURL& url) const {
  // https://www.w3.org/TR/CSP2/#match-source-expression, section 4.5.1
  // Allow "upgrade" to https if our document is http.
  if (LowerCaseEqualsASCII(self_scheme_, "http")) {
    return url.SchemeIs("http") || url.SchemeIs("https");
  } else {
    return self_scheme_ == url.scheme();
  }
}

void ContentSecurityPolicy::ReportViolation(
    const std::string& directive_text, const std::string& effective_directive,
    const std::string& console_message, const GURL& blocked_url,
    const std::vector<std::string>& report_endpoints,
    const std::string& header) {
  if (violation_callback_.is_null()) {
    return;
  }

  ViolationInfo violation_info;
  violation_info.directive_text = directive_text;
  violation_info.effective_directive = effective_directive;
  violation_info.console_message = console_message;
  violation_info.blocked_url = blocked_url;
  violation_info.endpoints = report_endpoints;
  violation_info.header = header;
  violation_callback_.Run(violation_info);
}

void ContentSecurityPolicy::ReportInvalidReferrer(
    const std::string& invalid_value) {
  std::string message =
      "The 'referrer' Content Security Policy directive has the invalid value "
      "\"" +
      invalid_value +
      "\". Valid values are \"no-referrer\", \"no-referrer-when-downgrade\", "
      "\"origin\", \"origin-when-cross-origin\", and \"unsafe-url\".";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidPluginTypes(
    const std::string& plugin_type) {
  std::string message;
  if (plugin_type.empty()) {
    message =
        "'plugin-types' Content Security Policy directive is empty; all "
        "plugins will be blocked.\n";
  } else if (plugin_type == "'none'") {
    message =
        "Invalid plugin type in 'plugin-types' Content Security Policy "
        "directive: '";
    message += plugin_type;
    message += "'. Did you mean to set the object-src directive to 'none'?\n";
  } else {
    message =
        "Invalid plugin type in 'plugin-types' Content Security Policy "
        "directive: '";
    message += plugin_type;
    message += "'.\n";
  }
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportMetaOutsideHead(const std::string& header) {
  std::string message = "The Content Security Policy '" + header +
                        "' was delivered via a <meta> element outside the "
                        "document's <head>, which is disallowed. The policy "
                        "has been ignored.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportValueForEmptyDirective(
    const std::string& name, const std::string& value) {
  std::string message =
      "The Content Security Policy directive '" + name +
      "' should be empty, but was delivered with a value of '" + value +
      "'. The directive has been applied, and the value ignored.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportDirectiveAsSourceExpression(
    const std::string& directive_name, const std::string& source_expression) {
  std::string message = "The Content Security Policy directive '" +
                        directive_name + "' contains '" + source_expression +
                        "' as a source expression. Did you mean '" +
                        directive_name + " ...; " + source_expression +
                        "...' (note the semicolon)?";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidSourceExpression(
    const std::string& directive_name, const std::string& source) {
  std::string message =
      "The source list for Content Security Policy directive '" +
      directive_name + "' contains an invalid source: '" + source +
      "'. It will be ignored.";
  if (LowerCaseEqualsASCII(source.c_str(), "'none'")) {
    message = message +
              " Note that 'none' has no effect unless it is the only "
              "expression in the source list.";
  }
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidPathCharacter(
    const std::string& directive_name, const std::string& value,
    char invalid_char) {
  DCHECK(invalid_char == '#' || invalid_char == '?');
  std::string message =
      "The source list for Content Security Policy directive '";
  message += directive_name;
  message += "' contains a source with an invalid path: '";
  message += value;
  message += "'. ";
  message +=
      invalid_char == '?'
          ? "The query component, including the '?', will be ignored."
          : "The fragment identifier, including the '#', will be ignored.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportDuplicateDirective(const std::string& name) {
  std::string message =
      "Ignoring duplicate Content-Security-Policy directive '" + name + "'.\n";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidDirectiveValueCharacter(
    const std::string& directive_name, const std::string& value) {
  std::string message =
      "The value for Content Security Policy directive '" + directive_name +
      "' contains an invalid character: '" + value +
      "'. Non-whitespace characters outside ASCII 0x21-0x7E must be "
      "percent-encoded, as described in RFC 3986, section 2.1: "
      "http://tools.ietf.org/html/rfc3986#section-2.1.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidReflectedXSS(
    const std::string& invalid_value) {
  std::string message =
      "The 'reflected-xss' Content Security Policy directive has the invalid "
      "value \"" +
      invalid_value +
      "\". Valid values are \"allow\", \"filter\", and \"block\".";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportMissingReportURI(const std::string& policy) {
  std::string message = "The Content Security Policy '";
  message += policy;
  message +=
      "' was delivered in report-only mode, but does not specify a "
      "'report-uri'; the policy will have no effect. Please either add a "
      "'report-uri' directive, or deliver the policy via the "
      "'Content-Security-Policy' header.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportReportOnlyInMeta(const std::string& header) {
  std::string message = "The report-only Content Security Policy '" + header +
                        "' was delivered via a <meta> element, which is "
                        "disallowed. The policy has been ignored.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidSuboriginFlags(
    const std::string& invalid_flags) {
  std::string message =
      "Error while parsing the 'suborigin' Content Security Policy "
      "directive: " +
      invalid_flags;
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportUnsupportedDirective(
    const std::string& name) {
  std::string lower_name = StringToLowerASCII(name);
  std::string message;
  if (lower_name == "allow") {
    message =
        "The 'allow' directive has been replaced with 'default-src'. Please "
        "use that directive instead, as 'allow' has no effect.";
  } else if (lower_name == "options") {
    message =
        "The 'options' directive has been replaced with 'unsafe-inline' and "
        "'unsafe-eval' source expressions for the 'script-src' and 'style-src' "
        "directives. Please use those directives instead, as 'options' has no "
        "effect.";
  } else if (lower_name == "policy-uri") {
    message =
        "The 'policy-uri' directive has been removed from the specification. "
        "Please specify a complete policy via the Content-Security-Policy "
        "header.";
  } else if (IsDirectiveName(name)) {
    message = "The Content-Security-Policy directive '" + name +
              "' is implemented behind a flag which is currently disabled.\n";
  } else {
    message =
        "Unrecognized Content-Security-Policy directive '" + name + "'.\n";
  }
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidInReportOnly(const std::string& name) {
  std::string message = "The Content Security Policy directive '" + name +
                        "' is ignored when delivered in a report-only policy.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportDirectiveNotSupportedInsideMeta(
    const std::string& name) {
  DLOG(WARNING) << "The " << name
                << " directive is not supported inside a <meta> element.";
}

bool ContentSecurityPolicy::AllowJavaScriptURLs(const std::string& context_url,
                                                int context_line,
                                                ReportingStatus status) const {
  FOR_ALL_POLICIES_3(AllowJavaScriptURLs, context_url, context_line, status);
}

bool ContentSecurityPolicy::AllowInlineEventHandlers(
    const std::string& context_url, int context_line,
    ReportingStatus status) const {
  FOR_ALL_POLICIES_3(AllowInlineEventHandlers, context_url, context_line,
                     status);
}
bool ContentSecurityPolicy::AllowInlineScript(const std::string& context_url,
                                              int context_line,
                                              const std::string& script_content,
                                              ReportingStatus status) const {
  FOR_ALL_POLICIES_4(AllowInlineScript, context_url, context_line, status,
                     script_content);
}
bool ContentSecurityPolicy::AllowInlineStyle(const std::string& context_url,
                                             int context_line,
                                             const std::string& style_content,
                                             ReportingStatus status) const {
  FOR_ALL_POLICIES_4(AllowInlineStyle, context_url, context_line, status,
                     style_content);
}

bool ContentSecurityPolicy::AllowEval(ReportingStatus status) const {
  FOR_ALL_POLICIES_1(AllowEval, status);
}

bool ContentSecurityPolicy::AllowScriptFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowScriptFromSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowObjectFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowObjectFromSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowImageFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowImageFromSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowNavigateToSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  // Note that this is a Cobalt-specific policy to prevent navigation
  // to any unexpected URLs.
  FOR_ALL_POLICIES_3(AllowNavigateToSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowStyleFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowStyleFromSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowFontFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowFontFromSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowMediaFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowMediaFromSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowConnectToSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowConnectToSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowFormAction(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowFormAction, url, redirect_status, reporting_status);
}

bool ContentSecurityPolicy::AllowBaseURI(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowBaseURI, url, redirect_status, reporting_status);
}

bool ContentSecurityPolicy::AllowManifestFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowManifestFromSource, url, redirect_status,
                     reporting_status);
}
bool ContentSecurityPolicy::AllowScriptWithNonce(
    const std::string& nonce) const {
  FOR_ALL_POLICIES_1(AllowScriptNonce, nonce);
}

bool ContentSecurityPolicy::AllowStyleWithNonce(
    const std::string& nonce) const {
  FOR_ALL_POLICIES_1(AllowStyleNonce, nonce);
}

bool ContentSecurityPolicy::AllowScriptWithHash(
    const std::string& source) const {
  return CheckDigest<&DirectiveList::AllowScriptHash>(
      source, script_hash_algorithms_used_, policies_);
}

bool ContentSecurityPolicy::AllowStyleWithHash(
    const std::string& source) const {
  return CheckDigest<&DirectiveList::AllowStyleHash>(
      source, style_hash_algorithms_used_, policies_);
}

void ContentSecurityPolicy::NotifyUrlChanged(const GURL& url) {
  url_ = url;
  CreateSelfSource();
}

bool ContentSecurityPolicy::DidSetReferrerPolicy() const {
  for (PolicyList::const_iterator it = policies_.begin(); it != policies_.end();
       ++it) {
    if ((*it)->did_set_referrer_policy()) {
      return true;
    }
  }
  return false;
}

void ContentSecurityPolicy::CreateSelfSource() {
  // Ensure that 'self' processes correctly.
  self_scheme_ = url_.scheme();
  SourceConfig config;
  config.scheme = self_scheme_;
  config.host = url_.host();
  config.path.clear();
  config.port = url_.IntPort();
  config.host_wildcard = SourceConfig::kNoWildcard;
  config.port_wildcard = SourceConfig::kNoWildcard;
  self_source_.reset(new Source(this, config));
}

void ContentSecurityPolicy::AddPolicyFromHeaderValue(const std::string& header,
                                                     HeaderType type,
                                                     HeaderSource source) {
  // If this is a report-only header inside a <meta> element, bail out.
  if (source == kHeaderSourceMeta && type == kHeaderTypeReport) {
    ReportReportOnlyInMeta(header);
    return;
  }

  base::StringPiece characters(header);

  const char* begin = characters.begin();
  const char* end = characters.end();

  // RFC2616, section 4.2 specifies that headers appearing multiple times can
  // be combined with a comma. Walk the header string, and parse each comma
  // separated chunk as a separate header.
  const char* position = begin;
  while (position < end) {
    SkipUntil(&position, end, ',');

    // header1,header2 OR header1
    //        ^                  ^
    base::StringPiece begin_piece(begin, static_cast<size_t>(position - begin));
    scoped_ptr<DirectiveList> policy(
        new DirectiveList(this, begin_piece, type, source));
    if (type != kHeaderTypeReport && policy->did_set_referrer_policy()) {
      // FIXME: We need a 'ReferrerPolicyUnset' enum to avoid confusing code
      // like this.
      referrer_policy_ = DidSetReferrerPolicy()
                             ? MergeReferrerPolicies(referrer_policy_,
                                                     policy->referrer_policy())
                             : policy->referrer_policy();
    }

    if (!policy->AllowEval(kSuppressReport) &&
        disable_eval_error_message_.empty()) {
      disable_eval_error_message_ = policy->eval_disabled_error_message();
    }

    policies_.push_back(policy.release());

    // Skip the comma, and begin the next header from the current position.
    DCHECK(position == end || *position == ',');
    SkipExactly(&position, end, ',');
    begin = position;
  }
}

}  // namespace csp
}  // namespace cobalt
