-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rewrite security section #692
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -2559,49 +2559,65 @@ The [=remote end steps=] are: | |||||||||||||||||||||
This section provides a few of the security considerations for the FedCM API. Note that there is a | ||||||||||||||||||||||
separate section for [[#privacy]] considerations. | ||||||||||||||||||||||
|
||||||||||||||||||||||
In FedCM, there are various assets that need to be protected. All of the endpoints need basic | ||||||||||||||||||||||
protections, and the credentialed ones need protections from various kinds of attacks and threats. | ||||||||||||||||||||||
The following subsections cover the various security threats and the mitigations from the FedCM | ||||||||||||||||||||||
spec. | ||||||||||||||||||||||
|
||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
## Content Security Policy ## {#content-security-policy} | ||||||||||||||||||||||
## Cross-Site Scripting ## {#cross-site-scripting} | ||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
|
||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
The first fetches triggered by the FedCM API are the manifest list, which is public, and the | ||||||||||||||||||||||
[=config file=]. Imagine a malicious script included by (and running as) the [=RP=] attempting to | ||||||||||||||||||||||
execute the FedCM API calls to a malicious [=IDP=], one which is not trusted by the [=RP=]. If the | ||||||||||||||||||||||
call is successful, this would introduce browser UI on the [=RP=] with sign in options into a | ||||||||||||||||||||||
malicious [=IDP=]. This malicious[=IDP=] could then attempt to trick the user. The protection | ||||||||||||||||||||||
against this attack is the [[!CSP]] check, which would fail because the origin of the manifest of | ||||||||||||||||||||||
the malicious [=IDP=] would not be an origin included in the allowlist specified by the [[!CSP]] of | ||||||||||||||||||||||
the [=RP=], hence preventing the undesired FedCM UI from being shown. Since any subsequent fetches | ||||||||||||||||||||||
are same origin with respect to the [=config file=] or at least dependent on the contents of the | ||||||||||||||||||||||
[=config file=], they do not require additional checks. | ||||||||||||||||||||||
Imagine a malicious script included by (and running as) the [=RP=] attempting to execute the FedCM | ||||||||||||||||||||||
API calls to a legitimate [=IDP=]. If the call is successful, this would introduce some browser UI | ||||||||||||||||||||||
where all parties might look legitimate to the user. If the user logs in using the FedCM API in this | ||||||||||||||||||||||
scenario, their credentials are then received by the malicious script, which can then send it to its | ||||||||||||||||||||||
own server. The protection against this attack is to sanitize all user input to prevent script | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
injection, and to use [[!CSP]] to restrict the execution of inline scripts. | ||||||||||||||||||||||
|
||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
A script could also instead use the FedCM API to request credentials from some [=IDP=] that is not | ||||||||||||||||||||||
approved by the [=RP=]. If the user went through this flow, these credentials could also be stolen, | ||||||||||||||||||||||
or the [=RP=]'s reputation could be harmed. An additional protection for this scenario is that the | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
origin of the [=config file=] of the malicious [=IDP=] would not be an origin included in the | ||||||||||||||||||||||
allowlist specified by the [[CSP#directive-connect-src|connect-src]] [[!CSP]] check of the [=RP=], | ||||||||||||||||||||||
hence preventing the undesired FedCM UI from being shown. Since any subsequent fetches are same | ||||||||||||||||||||||
origin with respect to the [=config file=] or at least dependent on the contents of the [=config | ||||||||||||||||||||||
file=], they do not require additional checks. | ||||||||||||||||||||||
|
||||||||||||||||||||||
The non-same-origin fetches include, for example, the brand icon. The user agent does not perform a | ||||||||||||||||||||||
[[!CSP]] check on these because they are directly specified from the manifest. In addition, the | ||||||||||||||||||||||
rendering of this image is performed by the user agent, and as such this image cannot affect the | ||||||||||||||||||||||
[=RP=] site nor can they be inspected by the [=RP=] in any way. | ||||||||||||||||||||||
Note that the non-same-origin fetches include, for example, the brand icon. The user agent does not | ||||||||||||||||||||||
perform a [[!CSP]] check on these because they are directly specified from the manifest. In | ||||||||||||||||||||||
addition, the rendering of this image is performed by the user agent, and as such this image cannot | ||||||||||||||||||||||
affect the [=RP=] site nor can they be inspected by the [=RP=] in any way. | ||||||||||||||||||||||
npm1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
|
||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
## Sec-Fetch-Dest Header ## {#sec-fetch-dest-header} | ||||||||||||||||||||||
## Unauthorized Fetching ## {#unauthorized-fetching} | ||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
|
||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
The FedCM API introduces several non-static endpoints on the [=IDP=], so these need to be protected | ||||||||||||||||||||||
from XSS attacks. In order to do so, the FedCM API introduces a new value for the | ||||||||||||||||||||||
<a http-header>Sec-Fetch-Dest</a> header, a [=forbidden request-header=]. The requests initiated by the FedCM API | ||||||||||||||||||||||
have a `webidentity` value for this header. The value cannot be set by random websites, so the | ||||||||||||||||||||||
[=IDP=] can be confident that the request was originated by the FedCM browser rather than sent by a | ||||||||||||||||||||||
websites trying to run an XSS attack. An [=IDP=] needs to check for this header's value in the | ||||||||||||||||||||||
credentialed requests it receives, which ensures that the request was initiated by the user agent, | ||||||||||||||||||||||
based on the FedCM API. A malicious actor cannot spam FedCM API calls, so this is sufficient | ||||||||||||||||||||||
protection for the new [=IDP=] endpoints. | ||||||||||||||||||||||
The FedCM API introduces several non-static endpoints on the [=IDP=]. These are meant to be invoked | ||||||||||||||||||||||
only by the user agent as part of a FedCM flow. If an attacker wanted to invoke these endpoints | ||||||||||||||||||||||
npm1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
directly, the [=IDP=] should have the capability to revoke the fetch. This applies even if the call | ||||||||||||||||||||||
originated from a valid [=RP=] so just having the origin of the fetch is not a sufficient mitigation | ||||||||||||||||||||||
here. In order to distinguish the fetches that are initiated from the FedCM flow from fetches coming | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
from elsewhere, the FedCM API introduces a new value for the <a http-header>Sec-Fetch-Dest</a> | ||||||||||||||||||||||
header, a [=forbidden request-header=]. The requests initiated by the FedCM API have a `webidentity` | ||||||||||||||||||||||
value for this header. The value cannot be set by random websites, so the [=IDP=] can be confident | ||||||||||||||||||||||
that the request was originated by the FedCM browser rather than sent by a websites trying to run an | ||||||||||||||||||||||
XSS attack. An [=IDP=] needs to check for this header's value in the credentialed requests it | ||||||||||||||||||||||
receives, which ensures that the request was initiated by the user agent, based on the FedCM API. | ||||||||||||||||||||||
This protects the new [=IDP=] endpoints from unauthorized fetches. Also note that a [=user agent=] | ||||||||||||||||||||||
which does not send third-party cookies also adds a protection, since a regular fetch from an [=RP=] | ||||||||||||||||||||||
context will not contain the [=IDP=]'s first-party cookies. | ||||||||||||||||||||||
|
||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
## CORS Header ## {#sec-cors-header} | ||||||||||||||||||||||
## Sensitive Data Access ## {#sec-cors-header} | ||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
|
||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
The FedCM API allows the response from the [=identity assertion endpoint=] to be shared to the | ||||||||||||||||||||||
[=RP=]. Because of this, we impose the requirement that the [=IDP=] explicitly consents to this | ||||||||||||||||||||||
sharing taking place by using the "cors" [=request/mode=] when fetching this endpoint. This also | ||||||||||||||||||||||
helps with servers that may accidentally ignore the <a http-header>Sec-Fetch-Dest</a>: they cannot | ||||||||||||||||||||||
ignore CORS, as without it the fetch will fail. | ||||||||||||||||||||||
[=RP=]. This endpoint typically contains user data that is extremly sensitive, and as such needs | ||||||||||||||||||||||
enhanced protection. To enable this, we impose the requirement that the [=IDP=] explicitly consents | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
to this sharing taking place by using the "cors" [=request/mode=] when fetching this endpoint. This | ||||||||||||||||||||||
also helps with servers that may accidentally ignore the <a http-header>Sec-Fetch-Dest</a>: they | ||||||||||||||||||||||
cannot ignore CORS, as without it the fetch will fail. | ||||||||||||||||||||||
npm1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
|
||||||||||||||||||||||
npm1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
## Browser Surface Impersonation ## {#browser-surface-impersonation} | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. on this, for some reason I cannot propose the threat/mitigation schema |
||||||||||||||||||||||
|
@@ -2617,13 +2633,77 @@ metadata about the user accounts of the [=IDP=], which the malicious website doe | |||||||||||||||||||||
If this is a malicious site, it would not know the user accounts unless the user is already | ||||||||||||||||||||||
compromised. However, the site could have some guess of the user identity, so the browser is | ||||||||||||||||||||||
encouraged to provide UI that is hard to replicate and that clearly presents the domains of the | ||||||||||||||||||||||
parties involved in the website's FedCM call. Overall, an attacker trying to impersonate the browser | ||||||||||||||||||||||
using exclusively UI that is accessible to the content area (e.g. iframes) to attempt to retrieve | ||||||||||||||||||||||
sensitive information from the user would be noticeably different from the FedCM UI. Finally, | ||||||||||||||||||||||
because the FedCM UI can only be queried from the top-level frame (or potentially from an iframe | ||||||||||||||||||||||
with explicit permission from the top-level frame), the priviledged UI surface is only shown when | ||||||||||||||||||||||
the top-level frame wants it so. A sneaky iframe cannot force the FedCM UI to occlude important | ||||||||||||||||||||||
content from the main page. | ||||||||||||||||||||||
parties involved in the website's FedCM call. | ||||||||||||||||||||||
|
||||||||||||||||||||||
One impersonation attack that would work for an attacker that the user somewhat trusts consists of | ||||||||||||||||||||||
the attacker first using the FedCM API. A trusting user would then login to FedCM using the browser | ||||||||||||||||||||||
UI. The attacker would then gain access to the information about the user and immediately would | ||||||||||||||||||||||
create a mockup of browser UI which would look almost identical in style that would request | ||||||||||||||||||||||
sensitive user information such as the password of the user account that the user just logged in to | ||||||||||||||||||||||
via FedCM. This attack requires the user to somewhat trust the attacker since FedCM needs to be | ||||||||||||||||||||||
successfully used first. It is mitigated by the fact that the FedCM UI does not ever require the | ||||||||||||||||||||||
user to enter passwords in the UI, so the new UI will look suspicious, especially to a user who has | ||||||||||||||||||||||
previously seen the FedCM flow on other sites. | ||||||||||||||||||||||
|
||||||||||||||||||||||
Overall, an attacker trying to impersonate the browser using exclusively UI that is accessible to | ||||||||||||||||||||||
the content area (e.g., iframes) to attempt to retrieve sensitive information from the user would be | ||||||||||||||||||||||
noticeably different from the FedCM UI. Finally, because the FedCM UI can only be queried from the | ||||||||||||||||||||||
top-level frame (or potentially from an iframe with explicit permission from the top-level frame), | ||||||||||||||||||||||
the privileged UI surface is only shown when the top-level frame wants it so. A sneaky iframe cannot | ||||||||||||||||||||||
force the FedCM UI to occlude important content from the main page. | ||||||||||||||||||||||
|
||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
## IDP Impersonation ## {#idp-impersonation} | ||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
|
||||||||||||||||||||||
An attacker who has some knowledge about the user via previous tracking could try to impersonate a | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
real [=IDP=] by pretending to be an [=IDP=] and invoking the FedCM API. However, this does not grant | ||||||||||||||||||||||
much more power to the attacker: if the user logs in via FedCM to the attacker, the attacker can now | ||||||||||||||||||||||
track the user more easily within the [=RP=], but the attacker was already tracking the user in | ||||||||||||||||||||||
order to surface a meaningful dialog. That said, [=IDP=] impersonation would still be poor UX for | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
the user and it would also reflect poorly on the real [=IDP=]. To protect from this, the user agent | ||||||||||||||||||||||
is encouraged to not just include the [=IDP=] branding in the UI dialogs, but also include the | ||||||||||||||||||||||
origins of the relevant parties as well. This way, the attacker can never create a FedCM dialog | ||||||||||||||||||||||
identical to that of the real [=IDP=] since its origin will be different. | ||||||||||||||||||||||
|
||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
## Clickbait ## {#clickbait} | ||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
|
||||||||||||||||||||||
An attacker controlled [=IDP=] could attempt to trick the user into going through the FedCM UI by | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
introducing fake text into the name/email fields of the accounts endpoint response that become | ||||||||||||||||||||||
visible in the UI. For example, they could enter text such as "Click here to win $100!". As this | ||||||||||||||||||||||
requires the attacker to control the [=IDP=], the gain would be minimal, i.e. access to user | ||||||||||||||||||||||
tracking within the [=RP=]. No sensitive information would be shared with the attacker in this case. | ||||||||||||||||||||||
To mitigate this, the user agent can add [=IDP=]-independent text to ensure that the user has some | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
context about what the dialog is for (like 'sign in'). Because this text would not be something the | ||||||||||||||||||||||
attacker can just override, it will ensure that this kind of abuse looks suspicious to the user. In | ||||||||||||||||||||||
addition, the [=RP=] would likely remove such abusive caller from their site unless they are also | ||||||||||||||||||||||
involved in this attack. Thus, while clickbait text is not something that the spec protects against, | ||||||||||||||||||||||
the power it provides to attackers is limited, similar to how an attacker could compromise the | ||||||||||||||||||||||
[=RP=] and introduce a clickbait dialog to entice the user to click on some part of the page to | ||||||||||||||||||||||
enable APIs requiring user gesture. Outright trackers need to be silent, since they need to work | ||||||||||||||||||||||
within pages that do not condone their practices, so this attack is not viable for them. | ||||||||||||||||||||||
|
||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
## Clickjacking ## {#clickjacking} | ||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
|
||||||||||||||||||||||
An attacker could surface UI to try to force the user into accidentally consenting to the FedCM | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
dialog. In this case, the attacker would likely be the [=RP=], which would want to gain valuable | ||||||||||||||||||||||
user information from a real [=IDP=]. For example, an attacker could have a button 'click here 4 | ||||||||||||||||||||||
times' which would surface the FedCM dialog the first time it is clicked. If the timing and the | ||||||||||||||||||||||
location of this button works out, an unsuspecting user would click on their account in the FedCM | ||||||||||||||||||||||
dialog when it appears. There are a couple of possible mitigations to this. One is the user agent | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
can always show a confirmation dialog after an account has been selected. This reduces the chance of | ||||||||||||||||||||||
the user accidentally confirming the entire FedCM flow. Another is that the user agent can establish | ||||||||||||||||||||||
a limited window of time during which user input is ignored, right after the FedCM dialog is shown | ||||||||||||||||||||||
to the user. This allows the user to have time to react to the dialog showing up while also not | ||||||||||||||||||||||
impacting the regular scenario of FedCM being used successfully. It is recommended for the user | ||||||||||||||||||||||
agent to implement at least one of these two mitigations in order to prevent an attacker from | ||||||||||||||||||||||
tricking the user into providing their credentials via the FedCM API. For this particular attack, | ||||||||||||||||||||||
the attacker's [=RP=] might also not be trusted by the [=IDP=], so the flow would fail due to | ||||||||||||||||||||||
{{id_assertion_endpoint_request/client_id}} or CORS checks. | ||||||||||||||||||||||
|
||||||||||||||||||||||
npm1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
<!-- ============================================================ --> | ||||||||||||||||||||||
# Privacy Considerations # {#privacy} | ||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding some assumptions. I have been thinking about this for a long time, and it makes sense that some assumptions may seem obvious to us (precisely because they are things we take for granted), but they are useful in defining the scope of the specification, even “outside” of what is the environment we consider within the trust boundaries.