Skip to content

Commit

Permalink
Merge pull request #13 from infomiho/typos-fixes
Browse files Browse the repository at this point in the history
Fixes various typos
  • Loading branch information
pilcrowonpaper authored Mar 10, 2024
2 parents d6c47e1 + e300b73 commit 461028a
Show file tree
Hide file tree
Showing 12 changed files with 75 additions and 77 deletions.
20 changes: 10 additions & 10 deletions pages/csrf.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ title: "Cross-site request forgery (CSRF)"
- [Cross-site vs cross-origin](#cross-site-vs-cross-origin)
- [Prevention](#prevention)
- [Anti-CSRF tokens](#anti-csrf-tokens)
- [Signed double submit cookies](#signed-double-submit-cookies)
- [Signed double-submit cookies](#signed-double-submit-cookies)
- [Origin header](#origin-header)
- [SameSite cookie attribute](#samesite-cookie-attribute)

Expand Down Expand Up @@ -53,11 +53,11 @@ CSRF can be prevented by only accepting POST and POST-like requests made by brow

Protection must be implemented for all routes that deal with forms. If your application does not currently use forms, it may still be a good idea to at least [check the `Origin` header](#origin-header) to prevent future issues. It's also a generally good idea to only modify resources using POST and POST-like methods (PUT, DELETE, etc).

For the common token based approach, the token should not be single-use (e.g. a new token for every form submission) as it will break with a single back button. It is also crucial that your pages have a strict cross-origin resource sharing (CORS) policy. If `Access-Control-Allow-Credentials` is not strict, a malicious site can send a GET request to get a HTML form with a valid CSRF token.
For the common token-based approach, the token should not be single-use (e.g. a new token for every form submission) as it will break with a single back button. It is also crucial that your pages have a strict cross-origin resource sharing (CORS) policy. If `Access-Control-Allow-Credentials` is not strict, a malicious site can send a GET request to get an HTML form with a valid CSRF token.

### Anti-CSRF tokens

This is a very simple method where each session have a unique CSRF [token](/server-side-tokens) associated with it.
This is a very simple method where each session has a unique CSRF [token](/server-side-tokens) associated with it.

```html
<form method="post">
Expand All @@ -67,9 +67,9 @@ This is a very simple method where each session have a unique CSRF [token](/serv
</form>
```

### Signed double submit cookies
### Signed double-submit cookies

If storing the token server-side is not an option, signed double submit cookies is another approach. This is different from the basic double submit cookie in that the token included in the form is signed with a secret.
If storing the token server-side is not an option, using signed double-submit cookies is another approach. This is different from the basic double submit cookie in that the token included in the form is signed with a secret.

A new [token](/server-side-tokens) is generated and hashed with HMAC SHA-256 using a secret key.

Expand All @@ -95,9 +95,9 @@ func generateCSRFToken(sessionId string) (string, []byte) {

The token is stored as a cookie and the HMAC is stored in the form. The cookie should have a `Secure`, `HttpOnly`, and `SameSite` flag. To validate a request, the cookie can be used to verify the signature sent in the form data.

#### Traditional double submit cookies
#### Traditional double-submit cookies

Regular double submit cookies that aren't signed will still leave you vulnerable if an attacker has access to a subdomain of your application's domain. This would allow them to set their own double submit cookies.
Regular double-submit cookies that aren't signed will still leave you vulnerable if an attacker has access to a subdomain of your application's domain. This would allow them to set their own double-submit cookies.

### Origin header

Expand All @@ -120,12 +120,12 @@ func handleRequest(w http.ResponseWriter, request *http.Request) {
}
```

The `Origin` header is supported by all modern browsers since around 2020, though Chrome and Safari have supported it before that. If the `Origin` header is not included, do not allow the request.
The `Origin` header has been supported by all modern browsers since around 2020, though Chrome and Safari have supported it before that. If the `Origin` header is not included, do not allow the request.

The `Referer` header is a similar header introduced before the `Origin` header. This can be used as a fallback if the `Origin` header isn't defined.

## SameSite cookie attribute

Session cookies should have a `SameSite` flag. This flag determines when the browser includes the cookie in requests. `SameSame=Lax` cookies will not be sent on cross-site, non-GET requests, while `SameSite=Strict` cookies will not be sent on any cross site requests. We recommend using `Lax` as the default as `Strict` cookies will not be sent when a user access your website via an external link.
Session cookies should have a `SameSite` flag. This flag determines when the browser includes the cookie in requests. `SameSame=Lax` cookies will not be sent on cross-site, non-GET requests, while `SameSite=Strict` cookies will not be sent on any cross-site requests. We recommend using `Lax` as the default as `Strict` cookies will not be sent when a user accesses your website via an external link.

If you set the value to `Lax`, it is crucial that your application does not use GET requests for modifying resources. Additionally, as this flag is relatively new and only protects against cross-site request forgery (instead of cross-origin request forgery), this should not be the only layer of defense.
If you set the value to `Lax`, it is crucial that your application does not use GET requests for modifying resources. Additionally, as this flag is relatively new and only protects against cross-site request forgery (instead of cross-origin request forgery), this should not be the only layer of defense.
14 changes: 7 additions & 7 deletions pages/email-verification.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: "Email verification"

# Email verification

If your application requires user email addresses to be unique, email verification is a must. It discourages users from entering a random email address and, if password reset is implemented, allows users to take back accounts created with their email address. You may event want to block users from accessing your application's content until they verify their email address.
If your application requires user email addresses to be unique, email verification is a must. It discourages users from entering a random email address and, if password reset is implemented, allows users to take back accounts created with their email address. You may eventually want to block users from accessing your application's content until they verify their email address.

## Table of contents

Expand Down Expand Up @@ -33,13 +33,13 @@ Some email providers, including Google, allow users to specify a tag that will b

One way to verify email is to send a secret code stored in the server to the user's mailbox.

This approach should be preferred over using links. People are increasingly less likely to click on links, and some filters may block emails with them. Using links also limit what device the users can use to create an account (eg. the user doesn't have to their mailbox on their phone).
This approach should be preferred over using links. People are increasingly less likely to click on links, and some filters may block emails with them. Using links also limits what device the users can use to create an account (eg. the user doesn't have to their mailbox on their phone).

The verification code should be at least 8 digits if the code is numeric, and at least 6 digits if it's alphanumeric. You should avoid using both lowercase and uppercase letters. You may also want to remove numbers and letters that can be misread (0, O, 1, I, etc). It must be generated using a cryptographically-secure random generator.
The verification code should be at least 8 digits if the code is numeric, and at least 6 digits if it's alphanumeric. You should avoid using both lowercase and uppercase letters. You may also want to remove numbers and letters that can be misread (0, O, 1, I, etc). It must be generated using a cryptographically secure random generator.

A single verification code should be tied to a single user and email. This is especially important if you allow users to change their email address after they're sent an email. Each code should be valid for at least 15 minutes (anywhere between 1-24 hours is recommended). The code must be single-use and immediately invalidated after validation. A new verification code should be generated every time the user asks for another email/code.
A single verification code should be tied to a single user and email. This is especially important if you allow users to change their email address after they're sent an email. Each code should be valid for at least 15 minutes (anywhere between 1-24 hours is recommended). The code must be single-use and immediately invalidated after validation. A new verification code should be generated every time the user asks for another email/code.

Similar to a regular login form, throttling or rate-limiting based on the user ID must be implemented. A good limit is around 10 attempts per hour. Assuming proper limiting is implemented, the code can be valid for up to 24 hours. You should generate and resend a new code if the user inputted code has expired.
Similar to a regular login form, throttling or rate-limiting based on the user ID must be implemented. A good limit is around 10 attempts per hour. Assuming proper limiting is implemented, the code can be valid for up to 24 hours. You should generate and resend a new code if the user-inputted code has expired.

All sessions of a user should be invalidated when their email is verified.

Expand All @@ -53,7 +53,7 @@ https://example.com/verify-email/<TOKEN>

A single token should be tied to a single user and email. This is especially important if you allow users to change their email address after they're sent an email. Tokens should be single-use and be immediately deleted from storage after verification. The token should be valid for at least 15 minutes (anywhere between 1-24 hours is recommended). When a user asks for another verification email, you can resend the previous token instead of generating a new token if that token is still within expiration.

Make sure to set the pages's [Referrer Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) tag to `noreferrer` to protect the token from referer leakage.
Make sure to set the pages' [Referrer Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) tag to `noreferrer` to protect the token from referer leakage.

All sessions should be invalidated when the email is verified.

Expand All @@ -65,4 +65,4 @@ A notification should be sent to the previous email address when the user change

## Rate limiting

Any endpoint that can send emails should have strict rate limiting implemented.
Any endpoint that can send emails should have strict rate limiting implemented.
4 changes: 2 additions & 2 deletions pages/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ title: "The Copenhagen Book"

# The Copenhagen Book

The Copenhagen Book provides a general guideline on implementing auth in web applications. It is free, open source, and community maintained. It may be opinionated or incomplete at times but we hope this fills a certain void in online resources. We recommend using this alongside the [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/index.html).
The Copenhagen Book provides a general guideline on implementing auth in web applications. It is free, open-source, and community-maintained. It may be opinionated or incomplete at times but we hope this fills a certain void in online resources. We recommend using this alongside the [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/index.html).

If you have any suggestions or concerns, consider opening a new issue.

*Created by [Pilcrow](https://github.com/pilcrowOnPaper)*
*Created by [Pilcrow](https://github.com/pilcrowOnPaper)*
8 changes: 4 additions & 4 deletions pages/mfa.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ title: "Multi-factor authentication (MFA)"
## Table of contents

- [Overview](#overview)
- [Time-based one time passwords (TOTP)](#time-based-one-time-passwords-totp)
- [Time-based one-time passwords (TOTP)](#time-based-one-time-passwords-totp)
- [Generate QR code](#generate-qr-code)
- [Validate OTPs](#validate-otps)
- [SMS](#sms)
Expand All @@ -24,9 +24,9 @@ MFA is when a user is required to input more than just a password to authenticat
- Somewhere you are
- Something you do

## Time-based one time passwords (TOTP)
## Time-based one-time passwords (TOTP)

TOTP is defined in [RFC 6238](https://datatracker.ietf.org/doc/html/rfc6238), which is based on hash-based one time passwords (HOTP), defined in [RFC 4226](https://www.ietf.org/rfc/rfc4226.txt).
TOTP is defined in [RFC 6238](https://datatracker.ietf.org/doc/html/rfc6238), which is based on hash-based one-time passwords (HOTP), defined in [RFC 4226](https://www.ietf.org/rfc/rfc4226.txt).

Standard TOTP uses an authenticator app, usually installed on the user's mobile device, to generate a code for the user.

Expand Down Expand Up @@ -97,4 +97,4 @@ Passkeys allow you to use in-device authentication methods, such as biometrics a

If your application uses MFA, we recommend issuing users with 1 or more recovery codes. These are single-use passwords that can be used instead of passkeys/OTPs to sign in and reset their second-factor when a user loses access to their devices. The codes must be generated using a cryptographically-secure random generator. They can be generated with only 40 bits of entropy (10 characters when encoded with hex) assuming proper throttling is implemented. When storing these codes, you should hash them with your preferred password hashing algorithm (e.g. Argon2id).

These codes should be provided when the user first sets up MFA and the user should be able to download them anytime if they have access to one of their second factors.
These codes should be provided when the user first sets up MFA and the user should be able to download them anytime if they have access to one of their second factors.
Loading

0 comments on commit 461028a

Please sign in to comment.