1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CONTENT_BROWSER_WEBAUTH_WEBAUTH_REQUEST_SECURITY_CHECKER_H_
6 #define CONTENT_BROWSER_WEBAUTH_WEBAUTH_REQUEST_SECURITY_CHECKER_H_
7 
8 #include <string>
9 
10 #include "base/memory/ref_counted.h"
11 #include "base/optional.h"
12 #include "content/common/content_export.h"
13 #include "third_party/blink/public/mojom/webauthn/authenticator.mojom.h"
14 
15 namespace url {
16 class Origin;
17 }
18 
19 namespace content {
20 
21 class RenderFrameHost;
22 
23 // The following enums correspond to UMA histograms and should not be
24 // reassigned.
25 enum class RelyingPartySecurityCheckFailure {
26   kOpaqueOrNonSecureOrigin = 0,
27   kRelyingPartyIdInvalid = 1,
28   kAppIdExtensionInvalid = 2,
29   kAppIdExtensionDomainMismatch = 3,
30   kIconUrlInvalid = 4,
31   kCrossOriginMismatch = 5,
32   kMaxValue = kCrossOriginMismatch,
33 };
34 
35 // A centralized class for enforcing security policies that apply to
36 // Web Authentication requests to create credentials or get authentication
37 // assertions. For security reasons it is important that these checks are
38 // performed in the browser process, and this makes the verification code
39 // available to both the desktop and Android implementations of the
40 // |Authenticator| mojom interface.
41 class CONTENT_EXPORT WebAuthRequestSecurityChecker
42     : public base::RefCounted<WebAuthRequestSecurityChecker> {
43  public:
44   explicit WebAuthRequestSecurityChecker(RenderFrameHost* host);
45   WebAuthRequestSecurityChecker(const WebAuthRequestSecurityChecker&) = delete;
46 
47   WebAuthRequestSecurityChecker& operator=(
48       const WebAuthRequestSecurityChecker&) = delete;
49 
50   static void ReportSecurityCheckFailure(
51       RelyingPartySecurityCheckFailure error);
52   static bool OriginIsCryptoTokenExtension(const url::Origin& origin);
53 
54   // Returns blink::mojom::AuthenticatorStatus::SUCCESS if |origin| is
55   // same-origin with all ancestors in the frame tree, or else if
56   // requests from cross-origin embeddings are allowed by policy.
57   // Returns blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR otherwise.
58   // |is_cross_origin| is an output parameter that is set to true if there is
59   // a cross-origin embedding, regardless of policy, and false otherwise.
60   blink::mojom::AuthenticatorStatus ValidateAncestorOrigins(
61       const url::Origin& origin,
62       bool* is_cross_origin);
63 
64   // Returns AuthenticatorStatus::SUCCESS if the origin domain is valid under
65   // the referenced definitions, and also the requested RP ID is a registrable
66   // domain suffix of, or is equal to, the origin's effective domain.
67   // References:
68   //   https://url.spec.whatwg.org/#valid-domain-string
69   //   https://html.spec.whatwg.org/multipage/origin.html#concept-origin-effective-domain
70   //   https://html.spec.whatwg.org/multipage/origin.html#is-a-registrable-domain-suffix-of-or-is-equal-to
71   blink::mojom::AuthenticatorStatus ValidateDomainAndRelyingPartyID(
72       const url::Origin& caller_origin,
73       const std::string& relying_party_id);
74 
75   // Checks whether a given URL is an a-priori authenticated URL.
76   // https://w3c.github.io/webappsec-credential-management/#dom-credentialuserdata-iconurl
77   blink::mojom::AuthenticatorStatus ValidateAPrioriAuthenticatedUrl(
78       const GURL& url);
79 
80  protected:
81   friend class base::RefCounted<WebAuthRequestSecurityChecker>;
82   virtual ~WebAuthRequestSecurityChecker();
83 
84  private:
85   // Returns whether the frame indicated by |host| is same-origin with its
86   // entire ancestor chain. |origin| is the origin of the frame being checked.
87   bool IsSameOriginWithAncestors(const url::Origin& origin);
88 
89   RenderFrameHost* render_frame_host_;
90 };
91 
92 }  // namespace content
93 
94 #endif  // CONTENT_BROWSER_WEBAUTH_WEBAUTH_REQUEST_SECURITY_CHECKER_H_
95