Skip to content

Commit

Permalink
docs: document account enumeration defenses for oidc
Browse files Browse the repository at this point in the history
See #32
  • Loading branch information
aeneasr committed May 15, 2020
1 parent b1544f4 commit 266329c
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 5 deletions.
14 changes: 11 additions & 3 deletions docs/docs/guides/sign-in-with-github-google-facebook-linkedin.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ and adds that data to `std.extVar('claims')`. Check out what data is available
at
[GitHub's Scope Docs](https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/).
Not all GitHub fields are supported however. Check the list of supported fields
[in the source code](https://github.com/ory/kratos/blob/v0.2.1-alpha.1/selfservice/strategy/oidc/provider_github.go#L72-L80).
[in the source code](https://github.com/ory/kratos/blob/v0.2.1-alpha.1/selfservice/strategy/oidc/provider_github.go#L72-L98).

:::

Expand All @@ -47,12 +47,20 @@ you must also create a Jsonnet code snippet for the provider. Save the code in
The following schema takes `email_primary` and maps it to `traits.email`:

```json title="contrib/quickstart/kratos/email-password/oidc.github.jsonnet"
local claims = std.extVar('claims');
local claims = {
email_verified: false
} + std.extVar('claims');

{
identity: {
traits: {
[if "email_primary" in claims then "email" else null]: claims.email_primary,
// Allowing unverified email addresses enables account
// enumeration attacks, especially if the value is used for
// e.g. verification or as a password login identifier.
//
// Therefore we only return the email if it (a) exists and (b) is marked verified
// by GitHub.
[if "email_primary" in claims && claims.email_verified then "email" else null]: claims.email_primary,
},
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ already known. Depending on the result, one of the two flows will be executed:
src={useBaseUrl('img/docs/email-verify-known.png')}
/>

This prevents Account Enumeration Attacks at is is not possible for a threat
This prevents Account Enumeration Attacks at is not possible for a threat
agent to determine if an account exists or not based on the verification flow.

The emails are using templates that can be customised as explained in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,50 @@ future release of ORY Kratos.

Please be aware that OpenID Connect providers always require a Browser, with the
exception of "Sign in with Apple" on recent iOS versions.

## Security and Defenses

### Account Enumeration

:::warn

This feature is a work in progress and is tracked as
[kratos#133](https://github.com/ory/kratos/issues/133).

:::

Scenario: In some cases you might want to use the email address returned by e.g.
the GitHub profile to be added to your user's account. You might also want to use
it as an email + password identifier so that the user is able to log in
with a password as well. An attacker is able to exploit that by creating a social
profile on another site (e.g. Google) and use the victims email address to set it up
(this only works when the victim does not yet have an account with that email at Google).
The attacker can then use that "spoofed" social profile to try and sign up with your ORY Kratos
installation. Because the victim's email address is already known to ORY Kratos, the
attacker might be able to observe the behavior (e.g. seeing an error page) and come
to the conclusion that the victim already has an account at the website.

Mitigation: This attack surface is rather small and requires a lot of effort, including
forging an e.g. Google profile, and can fail at several stages. To completely mitigate
any chance of that happening, only accept email addresses that are marked as verified
in your Jsonnet code:

```json title="contrib/quickstart/kratos/email-password/oidc.github.jsonnet"
local claims = {
email_verified: false
} + std.extVar('claims');

{
identity: {
traits: {
// Allowing unverified email addresses enables account
// enumeration attacks, especially if the value is used for
// e.g. verification or as a password login identifier.
//
// Therefore we only return the email if it (a) exists and (b) is marked verified
// by GitHub.
[if "email_primary" in claims && claims.email_verified then "email" else null]: claims.email_primary,
},
},
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ To mitigate this attack, the following strategies need to be deployed:
link to the login screen.
If you wish to mitigate account enumeration attacks, it is important to note
that you can not sign in users directly after sign up! Depending on the type of
that you cannot sign in users directly after sign up! Depending on the type of
service you provide, you might not care about this specific attack in which case
direct login after sign up would be ok.
Expand Down

0 comments on commit 266329c

Please sign in to comment.