/*
 * Copyright (C) 2011 Google, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_CONTENT_SECURITY_POLICY_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_CONTENT_SECURITY_POLICY_H_

#include <memory>
#include <utility>

#include "services/network/public/mojom/content_security_policy.mojom-blink.h"
#include "services/network/public/mojom/web_sandbox_flags.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h"
#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-blink.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_content_security_policy_struct.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/security_context.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
#include "third_party/blink/renderer/platform/network/http_parsers.h"
#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/blink/renderer/platform/wtf/text/text_position.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace WTF {
class OrdinalNumber;
}

namespace blink {

class ContentSecurityPolicyResponseHeaders;
class ConsoleMessage;
class DOMWrapperWorld;
class Element;
class ExecutionContext;
class LocalFrame;
class KURL;
class ResourceRequest;
class SecurityOrigin;
class SecurityPolicyViolationEventInit;
class SourceLocation;
enum class ResourceType : uint8_t;

typedef HeapVector<Member<ConsoleMessage>> ConsoleMessageVector;
using RedirectStatus = ResourceRequest::RedirectStatus;
using network::mojom::blink::CSPDirectiveName;

//  A delegate interface to implement violation reporting, support for some
//  directives and other miscellaneous functionality.
class CORE_EXPORT ContentSecurityPolicyDelegate : public GarbageCollectedMixin {
 public:
  // Returns the SecurityOrigin this content security policy is bound to. Used
  // for matching the 'self' keyword. Must return a non-null value.
  // See https://w3c.github.io/webappsec-csp/#policy-self-origin.
  virtual const SecurityOrigin* GetSecurityOrigin() = 0;

  // Returns the URL this content security policy is bound to.
  // Used for https://w3c.github.io/webappsec-csp/#violation-url and so.
  // Note: Url() is used for several purposes that are specced slightly
  // differently.
  // See comments at the callers.
  virtual const KURL& Url() const = 0;

  // Directives support.
  virtual void SetSandboxFlags(network::mojom::blink::WebSandboxFlags) = 0;
  virtual void SetRequireTrustedTypes() = 0;
  virtual void AddInsecureRequestPolicy(
      mojom::blink::InsecureRequestPolicy) = 0;

  // Violation reporting.

  // See https://w3c.github.io/webappsec-csp/#create-violation-for-global.
  // These functions are used to create the violation object.
  virtual std::unique_ptr<SourceLocation> GetSourceLocation() = 0;
  virtual base::Optional<uint16_t> GetStatusCode() = 0;
  // If the Delegate is not bound to a document, a null string should be
  // returned as the referrer.
  virtual String GetDocumentReferrer() = 0;

  virtual void DispatchViolationEvent(const SecurityPolicyViolationEventInit&,
                                      Element*) = 0;
  virtual void PostViolationReport(const SecurityPolicyViolationEventInit&,
                                   const String& stringified_report,
                                   bool is_frame_ancestors_violaton,
                                   const Vector<String>& report_endpoints,
                                   bool use_reporting_api) = 0;

  virtual void Count(WebFeature) = 0;

  virtual void AddConsoleMessage(ConsoleMessage*) = 0;
  virtual void AddInspectorIssue(mojom::blink::InspectorIssueInfoPtr) = 0;
  virtual void DisableEval(const String& error_message) = 0;
  virtual void ReportBlockedScriptExecutionToInspector(
      const String& directive_text) = 0;
  virtual void DidAddContentSecurityPolicies(
      WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>) = 0;
};

class CORE_EXPORT ContentSecurityPolicy final
    : public GarbageCollected<ContentSecurityPolicy> {
 public:
  enum ExceptionStatus { kWillThrowException, kWillNotThrowException };

  // This covers the possible values of a violation's 'resource', as defined in
  // https://w3c.github.io/webappsec-csp/#violation-resource. By the time we
  // generate a report, we're guaranteed that the value isn't 'null', so we
  // don't need that state in this enum.
  //
  // Trusted Types violation's 'resource' values are defined in
  // https://wicg.github.io/trusted-types/dist/spec/#csp-violation-object-hdr.
  enum ContentSecurityPolicyViolationType {
    kInlineViolation,
    kEvalViolation,
    kURLViolation,
    kTrustedTypesSinkViolation,
    kTrustedTypesPolicyViolation
  };

  // The |type| argument given to inline checks, e.g.:
  // https://w3c.github.io/webappsec-csp/#should-block-inline
  // Its possible values are listed in:
  // https://w3c.github.io/webappsec-csp/#effective-directive-for-inline-check
  enum class InlineType {
    kNavigation,
    kScript,
    kScriptAttribute,
    kStyle,
    kStyleAttribute
  };

  // CheckHeaderType can be passed to Allow*FromSource methods to control which
  // types of CSP headers are checked.
  enum class CheckHeaderType {
    // Check both Content-Security-Policy and
    // Content-Security-Policy-Report-Only headers.
    kCheckAll,
    // Check Content-Security-Policy headers only and ignore
    // Content-Security-Policy-Report-Only headers.
    kCheckEnforce,
    // Check Content-Security-Policy-Report-Only headers only and ignore
    // Content-Security-Policy headers.
    kCheckReportOnly
  };

  // Helper type for the method AllowTrustedTypePolicy.
  enum AllowTrustedTypePolicyDetails {
    kAllowed,
    kDisallowedName,
    kDisallowedDuplicateName
  };

  static const size_t kMaxSampleLength = 40;

  // Parse raw Content Security Policy strings into mojo types.
  static WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>
  ParseHeaders(const ContentSecurityPolicyResponseHeaders& headers);

  ContentSecurityPolicy();
  ~ContentSecurityPolicy();
  void Trace(Visitor*) const;

  bool IsBound();
  void BindToDelegate(ContentSecurityPolicyDelegate&);
  void CopyStateFrom(const ContentSecurityPolicy*);

  void DidReceiveHeaders(const ContentSecurityPolicyResponseHeaders&);
  void DidReceiveHeader(const String&,
                        const SecurityOrigin& self_origin,
                        network::mojom::ContentSecurityPolicyType,
                        network::mojom::ContentSecurityPolicySource);
  void ReportAccumulatedHeaders() const;

  void AddPolicies(
      Vector<network::mojom::blink::ContentSecurityPolicyPtr> policies);

  // Returns whether or not the Javascript code generation should call back the
  // CSP checker before any script evaluation from a string attempts.
  //
  // CSP has two mechanisms for controlling eval: script-src and TrustedTypes.
  // This returns true when any of those should to be checked.
  bool ShouldCheckEval() const;

  // When the reporting status is |SendReport|, the |ExceptionStatus|
  // should indicate whether the caller will throw a JavaScript
  // exception in the event of a violation. When the caller will throw
  // an exception, ContentSecurityPolicy does not log a violation
  // message to the console because it would be redundant.
  bool AllowEval(ReportingDisposition,
                 ExceptionStatus,
                 const String& script_content);
  bool AllowWasmEval(ReportingDisposition,
                     ExceptionStatus,
                     const String& script_content);

  // AllowFromSource() wrappers.
  bool AllowBaseURI(const KURL&);
  bool AllowConnectToSource(
      const KURL&,
      const KURL& url_before_redirects,
      RedirectStatus,
      ReportingDisposition = ReportingDisposition::kReport,
      CheckHeaderType = CheckHeaderType::kCheckAll);
  bool AllowFormAction(const KURL&);
  bool AllowImageFromSource(
      const KURL&,
      const KURL& url_before_redirects,
      RedirectStatus,
      ReportingDisposition = ReportingDisposition::kReport,
      CheckHeaderType = CheckHeaderType::kCheckAll);
  bool AllowMediaFromSource(const KURL&);
  bool AllowObjectFromSource(const KURL&);
  bool AllowScriptFromSource(
      const KURL&,
      const String& nonce,
      const IntegrityMetadataSet&,
      ParserDisposition,
      const KURL& url_before_redirects,
      RedirectStatus,
      ReportingDisposition = ReportingDisposition::kReport,
      CheckHeaderType = CheckHeaderType::kCheckAll);
  bool AllowWorkerContextFromSource(const KURL&);

  bool AllowTrustedTypePolicy(const String& policy_name,
                              bool is_duplicate,
                              AllowTrustedTypePolicyDetails& violation_details);

  // Passing 'String()' into the |nonce| arguments in the following methods
  // represents an unnonced resource load.
  //
  // For kJavaScriptURL case, |element| will not be present for navigations to
  // javascript URLs, as those checks happen in the middle of the navigation
  // algorithm, and we generally don't have access to the responsible element.
  //
  // For kInlineEventHandler case, |element| will be present almost all of the
  // time, but because of strangeness around targeting handlers for '<body>',
  // '<svg>', and '<frameset>', it will be 'nullptr' for handlers on those
  // elements.
  bool AllowInline(InlineType,
                   Element*,
                   const String& content,
                   const String& nonce,
                   const String& context_url,
                   const WTF::OrdinalNumber& context_line,
                   ReportingDisposition = ReportingDisposition::kReport);

  static bool IsScriptInlineType(InlineType);

  // TODO(crbug.com/889751): Remove "mojom::blink::RequestContextType" once
  // all the code migrates.
  bool AllowRequestWithoutIntegrity(
      mojom::blink::RequestContextType,
      network::mojom::RequestDestination,
      const KURL&,
      const KURL& url_before_redirects,
      RedirectStatus,
      ReportingDisposition = ReportingDisposition::kReport,
      CheckHeaderType = CheckHeaderType::kCheckAll) const;

  // TODO(crbug.com/889751): Remove "mojom::blink::RequestContextType" once
  // all the code migrates.
  bool AllowRequest(mojom::blink::RequestContextType,
                    network::mojom::RequestDestination,
                    const KURL&,
                    const String& nonce,
                    const IntegrityMetadataSet&,
                    ParserDisposition,
                    const KURL& url_before_redirects,
                    RedirectStatus,
                    ReportingDisposition = ReportingDisposition::kReport,
                    CheckHeaderType = CheckHeaderType::kCheckAll);

  // Determine whether to enforce the assignment failure. Also handle reporting.
  // Returns whether enforcing Trusted Types CSP directives are present.
  bool AllowTrustedTypeAssignmentFailure(
      const String& message,
      const String& sample = String(),
      const String& sample_prefix = String());

  void UsesScriptHashAlgorithms(uint8_t content_security_policy_hash_algorithm);
  void UsesStyleHashAlgorithms(uint8_t content_security_policy_hash_algorithm);

  void SetOverrideAllowInlineStyle(bool);
  void SetOverrideURLForSelf(const KURL&);

  bool IsActive() const;
  bool IsActiveForConnections() const;

  // If a frame is passed in, the message will be logged to its active
  // document's console.  Otherwise, the message will be logged to this object's
  // |m_executionContext|.
  void LogToConsole(ConsoleMessage*, LocalFrame* = nullptr);

  void ReportDirectiveAsSourceExpression(const String& directive_name,
                                         const String& source_expression);
  void ReportDuplicateDirective(const String&);
  void ReportInvalidDirectiveValueCharacter(const String& directive_name,
                                            const String& value);
  void ReportInvalidPathCharacter(const String& directive_name,
                                  const String& value,
                                  const char);
  void ReportInvalidRequireTrustedTypesFor(const String&);
  void ReportInvalidSandboxFlags(const String&);
  void ReportInvalidSourceExpression(const String& directive_name,
                                     const String& source);
  void ReportMultipleReportToEndpoints();
  void ReportUnsupportedDirective(const String&);
  void ReportInvalidInReportOnly(const String&);
  void ReportInvalidDirectiveInMeta(const String& directive_name);
  void ReportReportOnlyInMeta(const String&);
  void ReportMetaOutsideHead(const String&);
  void ReportValueForEmptyDirective(const String& directive_name,
                                    const String& value);
  void ReportMixedContentReportURI(const String& endpoint);

  // If a frame is passed in, the report will be sent using it as a context. If
  // no frame is passed in, the report will be sent via this object's
  // |m_executionContext| (or dropped on the floor if no such context is
  // available).
  // If |sourceLocation| is not set, the source location will be the context's
  // current location.
  void ReportViolation(const String& directive_text,
                       CSPDirectiveName effective_type,
                       const String& console_message,
                       const KURL& blocked_url,
                       const Vector<String>& report_endpoints,
                       bool use_reporting_api,
                       const String& header,
                       network::mojom::ContentSecurityPolicyType,
                       ContentSecurityPolicyViolationType,
                       std::unique_ptr<SourceLocation>,
                       LocalFrame* = nullptr,
                       RedirectStatus = RedirectStatus::kFollowedRedirect,
                       Element* = nullptr,
                       const String& source = g_empty_string,
                       const String& source_prefix = g_empty_string);

  // Called when mixed content is detected on a page; will trigger a violation
  // report if the 'block-all-mixed-content' directive is specified for a
  // policy.
  void ReportMixedContent(const KURL& blocked_url, RedirectStatus);

  void ReportBlockedScriptExecutionToInspector(
      const String& directive_text) const;

  // Used as <object>'s URL when there is no `src` attribute.
  const KURL FallbackUrlForPlugin() const;

  void EnforceSandboxFlags(network::mojom::blink::WebSandboxFlags);
  void RequireTrustedTypes();
  bool IsRequireTrustedTypes() const { return require_trusted_types_; }
  String EvalDisabledErrorMessage() const;

  // Upgrade-Insecure-Requests and Block-All-Mixed-Content are represented in
  // |m_insecureRequestPolicy|
  void EnforceStrictMixedContentChecking();
  void UpgradeInsecureRequests();
  mojom::blink::InsecureRequestPolicy GetInsecureRequestPolicy() const {
    return insecure_request_policy_;
  }

  bool ExperimentalFeaturesEnabled() const;

  bool ShouldSendCSPHeader(ResourceType) const;

  // Whether the main world's CSP should be bypassed based on the current
  // javascript world we are in.
  // Note: This is deprecated. New usages should not be added. Operations in an
  // isolated world should use the isolated world CSP instead of bypassing the
  // main world CSP. See
  // ExecutionContext::GetContentSecurityPolicyForCurrentWorld.
  // TODO(karandeepb): Rename to ShouldBypassMainWorldDeprecated.
  static bool ShouldBypassMainWorld(const ExecutionContext*);

  // Whether the main world's CSP should be bypassed for operations in the given
  // |world|.
  // Note: This is deprecated. New usages should not be added. Operations in an
  // isolated world should use the isolated world CSP instead of bypassing the
  // main world CSP. See ExecutionContext::GetContentSecurityPolicyForWorld.
  // TODO(karandeepb): Rename to ShouldBypassMainWorldDeprecated.
  static bool ShouldBypassMainWorld(const DOMWrapperWorld* world);

  static bool IsNonceableElement(const Element*);

  static const char* GetDirectiveName(CSPDirectiveName type);
  static CSPDirectiveName GetDirectiveType(const String& name);

  bool HasHeaderDeliveredPolicy() const { return header_delivered_; }

  // Returns the 'wasm-eval' source is supported.
  bool SupportsWasmEval() const { return supports_wasm_eval_; }
  void SetSupportsWasmEval(bool value) { supports_wasm_eval_ = value; }

  // Retrieve the parsed policies.
  const WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>&
  GetParsedPolicies() const;

  // Retrieves the parsed sandbox flags. A lot of the time the execution
  // context will be used for all sandbox checks but there are situations
  // (before installing the document that this CSP will bind to) when
  // there is no execution context to enforce the sandbox flags.
  network::mojom::blink::WebSandboxFlags GetSandboxMask() const {
    return sandbox_mask_;
  }

  bool HasPolicyFromSource(network::mojom::ContentSecurityPolicySource) const;

  static bool IsScriptDirective(CSPDirectiveName directive_type) {
    return (directive_type == CSPDirectiveName::ScriptSrc ||
            directive_type == CSPDirectiveName::ScriptSrcAttr ||
            directive_type == CSPDirectiveName::ScriptSrcElem);
  }

  static bool IsStyleDirective(CSPDirectiveName directive_type) {
    return (directive_type == CSPDirectiveName::StyleSrc ||
            directive_type == CSPDirectiveName::StyleSrcAttr ||
            directive_type == CSPDirectiveName::StyleSrcElem);
  }

  void Count(WebFeature feature) const;

 private:
  FRIEND_TEST_ALL_PREFIXES(ContentSecurityPolicyTest, NonceInline);
  FRIEND_TEST_ALL_PREFIXES(ContentSecurityPolicyTest, NonceSinglePolicy);
  FRIEND_TEST_ALL_PREFIXES(ContentSecurityPolicyTest, NonceMultiplePolicy);
  FRIEND_TEST_ALL_PREFIXES(ContentSecurityPolicyTest, EmptyCSPIsNoOp);
  FRIEND_TEST_ALL_PREFIXES(BaseFetchContextTest, CanRequest);
  FRIEND_TEST_ALL_PREFIXES(BaseFetchContextTest, CheckCSPForRequest);
  FRIEND_TEST_ALL_PREFIXES(BaseFetchContextTest,
                           AllowResponseChecksReportedAndEnforcedCSP);
  FRIEND_TEST_ALL_PREFIXES(FrameFetchContextTest,
                           PopulateResourceRequestChecksReportOnlyCSP);

  Vector<network::mojom::blink::ContentSecurityPolicyPtr> Parse(
      const String&,
      const SecurityOrigin& self_origin,
      network::mojom::ContentSecurityPolicyType,
      network::mojom::ContentSecurityPolicySource);
  void ApplyPolicySideEffectsToDelegate();
  void ReportUseCounters(
      const Vector<network::mojom::blink::ContentSecurityPolicyPtr>& policies);
  void ComputeInternalStateForParsedPolicy(
      const network::mojom::blink::ContentSecurityPolicy& csp);

  void LogToConsole(
      const String& message,
      mojom::ConsoleMessageLevel = mojom::ConsoleMessageLevel::kError);

  bool ShouldSendViolationReport(const String&) const;
  void DidSendViolationReport(const String&);
  void PostViolationReport(const SecurityPolicyViolationEventInit*,
                           LocalFrame*,
                           const Vector<String>& report_endpoints,
                           bool use_reporting_api);

  bool AllowFromSource(CSPDirectiveName,
                       const KURL&,
                       const KURL& url_before_redirects,
                       RedirectStatus,
                       ReportingDisposition = ReportingDisposition::kReport,
                       CheckHeaderType = CheckHeaderType::kCheckAll,
                       const String& = String(),
                       const IntegrityMetadataSet& = IntegrityMetadataSet(),
                       ParserDisposition = kParserInserted);

  static void FillInCSPHashValues(
      const String& source,
      uint8_t hash_algorithms_used,
      Vector<network::mojom::blink::CSPHashSourcePtr>& csp_hash_values);

  // checks a vector of csp hashes against policy, probably a good idea
  // to use in tandem with FillInCSPHashValues.
  static bool CheckHashAgainstPolicy(
      Vector<network::mojom::blink::CSPHashSourcePtr>&,
      const network::mojom::blink::ContentSecurityPolicy&,
      InlineType);

  bool ShouldBypassContentSecurityPolicy(
      const KURL&,
      SchemeRegistry::PolicyAreas = SchemeRegistry::kPolicyAreaAll) const;

  // TODO: Consider replacing 'ContentSecurityPolicy::ViolationType' with the
  // mojo enum.
  mojom::blink::ContentSecurityPolicyViolationType BuildCSPViolationType(
      ContentSecurityPolicy::ContentSecurityPolicyViolationType violation_type);

  void ReportContentSecurityPolicyIssue(
      const blink::SecurityPolicyViolationEventInit& violation_data,
      network::mojom::ContentSecurityPolicyType header_type,
      ContentSecurityPolicyViolationType violation_type,
      LocalFrame*,
      Element*,
      SourceLocation*);

  Member<ContentSecurityPolicyDelegate> delegate_;
  bool override_inline_style_allowed_ = false;
  Vector<network::mojom::blink::ContentSecurityPolicyPtr> policies_;
  ConsoleMessageVector console_messages_;
  bool header_delivered_{false};

  HashSet<unsigned, AlreadyHashed> violation_reports_sent_;

  // We put the hash functions used on the policy object so that we only need
  // to calculate a hash once and then distribute it to all of the directives
  // for validation.
  uint8_t script_hash_algorithms_used_;
  uint8_t style_hash_algorithms_used_;

  // State flags used to configure the environment after parsing a policy.
  network::mojom::blink::WebSandboxFlags sandbox_mask_;
  bool require_trusted_types_;
  String disable_eval_error_message_;
  mojom::blink::InsecureRequestPolicy insecure_request_policy_;

  String self_protocol_;

  bool supports_wasm_eval_ = false;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_CONTENT_SECURITY_POLICY_H_
