You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: module4-authentication-and-security/r1-securing-backend-app/README.md
+22-16Lines changed: 22 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -34,7 +34,7 @@ Now, suppose another user comes to your app: how will your app decide what to sh
34
34
35
35
That's why almost everywhere online, you need to register or log in to an account in order to use an application, so the data can be related to you and you only.
36
36
37
-
## Let's add some security
37
+
## Let's add some authentication
38
38
39
39
To secure our wishlist above, we can add a new column to the lists table to attach it to an identity (a user). We can name that column `user_email` for example, and use this query to get the user wishlist:
40
40
@@ -63,17 +63,18 @@ You can change the column `user_email` to `token` and every time a user comes in
63
63
64
64
Bingo! You've just created your first, very adequate authentication layer! You've secured your app and **slimmed the chances** of brute-forcing user data! Many apps today use this pattern to secure data. However, keep in mind that you usually need other features to track, like user email, name, age, etc. So such a simplistic approach wouldn't suffice. That's when this token is moved into another table and tracked with a `user_id` instead.
65
65
66
-
## Why do we need passwords
66
+
## Why do we need passwords?
67
67
68
-
The token system developed above is very robust, but it isn't always an acceptable security measure (at least not alone). That's because, if a user loses the token, it is next to impossible (especially if it was generated with CSPRNGs with reasonable size) to gain access back to their lists using today's technologies.
68
+
The token system developed above is very robust, but it isn't always an acceptable security measure (at least not alone). That's because, if a user loses the token, it is next to impossible (especially if it was generated with CSPRNGs with reasonable size) to gain access back to their lists using today's computing powers.
69
69
70
70
So, maybe instead of a long random token, use a password? We can ask the user when they land on our page for a passcode (aka password). And we check the database if we can find a list where `password = USER_SUBMITTED_PASSCODE` then display them. If not, that means they are a new user.
71
71
72
72
Indeed this works, passwords are okay and a perfectly viable and widespread approach. Keeping in mind that users tend to use easy to remember words, dates, phone numbers, and the like. This makes passwords vulnerable to brute-force attacks. It would be relatively harder than brute-forcing emails, but still easy to guess, and very easy for computers to break by checking every possible combination of words, dates, numbers, and even relatively harder passwords using a technology called **rainbow tables**.
73
73
74
74
Hence, there are two things to remember about passwords:
75
-
They require validation to prevent brute force attacks (thus preventing easy to guess passwords)
76
-
Use salt and hash to prevent rainbow attacks -- point to a code example here or include your own, and then this needs an in-depth explanation because this is probably the most important section that new people will forget about writing passwords
75
+
76
+
- They require validation to prevent brute force attacks (thus preventing easy to guess passwords)
77
+
- Use salt and hash to prevent rainbow attacks
77
78
78
79
## Security Checklist
79
80
@@ -95,14 +96,18 @@ Federated identity management is a configuration that can be made between two or
95
96
An example of this is to offer people to sign in with Google, or Github. Here, Google is an identity provider (IdP).
96
97
97
98
Many benefits come with this:
98
-
User convenience, they don't have to remember lots of passwords and fill preliminary registration forms.
99
-
Delegate account and password management overhead to the identity provider.
100
-
Sometimes, you can even skip email validation logic since that has been already done.
101
-
Avoid privacy compliance burden.
99
+
100
+
- User convenience, they don't have to remember lots of passwords and fill preliminary registration forms.
101
+
- Delegate account and password management overhead to the identity provider.
102
+
- Sometimes, you can even skip email validation logic since that has been already done.
103
+
- Avoid privacy compliance burden.
104
+
102
105
There are three protocols for federated identity:
103
-
SAML
104
-
OpenID
105
-
OAuth
106
+
107
+
- SAML
108
+
- OpenID
109
+
- OAuth
110
+
106
111
We will cover OID and OAuth later in this module.
107
112
108
113
### Database security
@@ -125,10 +130,11 @@ The process is usually done by obtaining a certificate from a Certificate Author
125
130
Testing the code correctly to ensure it achieves its intended purpose around normal and abnormal scenarios.
126
131
127
132
For instance, if you define an endpoint is only intended for admins, you need to test that it:
128
-
Rejects gracefully any request from non-admin users
129
-
Rejects requests from unauthenticated clients
130
-
When if a token has expired, it redirects the request correctly
131
-
These are some examples of test cases. You need to account for edge cases in your logic as well.
133
+
134
+
- Rejects gracefully any request from non-admin users
135
+
- Rejects requests from unauthenticated clients
136
+
- When if a token has expired, it redirects the request correctly
137
+
- These are some examples of test cases. You need to account for edge cases in your logic as well.
Copy file name to clipboardExpand all lines: module4-authentication-and-security/r1.1-defining-authentication-layer/README.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -196,7 +196,7 @@ If any email or phone number validation is required, it is usually in this step
196
196
197
197
One thing to emphasize in the code above is the introduction of hashing function. BCrypt was used to salt and **hash the password before saving in the database**. Some password validation was also used to make sure any password we store in the database is strong enough against brute-force and rainbow-table attacks.
198
198
199
-
### **Password management**
199
+
### Password management
200
200
201
201
Let's imagine this, we have 2 users Bob and Alice. They are using a form to register and out of coincidence they use the same password `c00k1eD0ugh`. Your app would hash this password before storing, and hash functions when given the same input, they always return the same hash. It is due to the deterministic nature of hashing functions. Your table would look like this:
202
202
@@ -219,7 +219,7 @@ Fortunately, though, for Alice and Bob, while using the same password, it is not
219
219
220
220
Thus, Jane is at high risk of being breached through a dictionary attack. Alice and Bob are not so different, it might take some more time, but with some tools that can replace letters with similar characters like numbers or special characters. And once cracked, the attacker will have 2 user accounts simultaneously.
221
221
222
-
### **Mitigating the damage with salts**
222
+
### Mitigating the damage with salts
223
223
224
224
To mitigate the damage introduced by this user vulnerability, we salt the passwords. A **salt** is a value generated by a [cryptographically secure function](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html) that is added to the input of hash functions to create unique hashes for every input, regardless of the input not being unique. Salt makes a hash function look non-deterministic, which is good as we don't want to reveal duplicate passwords through our hashing.
Copy file name to clipboardExpand all lines: module4-authentication-and-security/r1.1.1-authentication-persistence/README.md
+7-7Lines changed: 7 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ In this lesson, we will tackle how to persist user login, or registration betwee
6
6
- Implementing stateful persistence using express-sessions
7
7
- Implementing stateless identifiers using JSON Web Tokens (JWT)
8
8
9
-
## **Stateful Session Storage**
9
+
## Stateful Session Storage
10
10
11
11
In web servers, sessions are server-side temporary storage tools. They are used for a variety of use cases to store temporary data between requests. They use different storage adapters, like RAM, disk, databases, in-memory cache, etc. to save the temporary data.
12
12
@@ -62,7 +62,7 @@ And when requesting protected resources, we can check if the request session tha
62
62
63
63
> 💡 **Tip**: `express-session` comes with lots of adapters to store sessions as plug-in libraries. Check out [this list](https://github.com/expressjs/session#compatible-session-stores).
64
64
65
-
## **Stateless Session Storage**
65
+
## Stateless Session Storage
66
66
67
67
In stateless session storage, we don't store any temporary data on the server. Thus, the server is state-less. Instead, we issue a session payload in a token that encapsulates the data and sends it to the client for future use in subsequent requests. JWT is often, the way to carry out this process.
68
68
@@ -101,7 +101,7 @@ To make an authenticated request by the client, it needs to pass this token to t
101
101
102
102

103
103
104
-
### **JWT Validation**
104
+
### JWT Validation
105
105
106
106
A middleware library like [express-jwt](https://www.npmjs.com/package/express-jwt) can be used on the server to validate JWTs.
107
107
@@ -137,7 +137,7 @@ Then e can simply access the user object in the request as follows:
137
137
constuser=req.user;
138
138
```
139
139
140
-
### **Issuing JWT**
140
+
### Issuing JWT
141
141
142
142
To issue JWT, your authentication server can use a library [jsonwebtoken](https://www.npmjs.com/package/jsonwebtoken) to issue the token as follows:
> 💡 **TIP**: Always keep your tokens short-lived as they are, by design, harder to revoke. The token by default will stay functional until it expires.
180
180
181
-
### **JWT Signature**
181
+
### JWT Signature
182
182
183
183
You're probably wondering: if JWTs can be easily decoded and their payload can be seen, how do we make sure that someone doesn't pass any payload to authenticate a request? The signature is the answer.
184
184
185
185
When issuing JWTs, we take the claims and encrypt them using the `app-secret` key. Then attach that signature to the JWT as a `base64` encoded string. Remember that the `app-secret` is only known by your app.
186
186
187
187
When the JWT is passed back to the server in the header, we check the claims, and sign them again using our `app-secret`, then compare this signature with the signature provided by the token. If they match, that means the JWT is indeed issued by this app. Otherwise, it is fake.
188
188
189
-
## **Pros and Cons of JSON Web Tokens**
189
+
## Pros and Cons of JSON Web Tokens
190
190
191
191
JWTs are becoming more and more ubiquitous. Customer identity and access management (CIAM) providers everywhere are pushing JWTs as the silver bullet for everything. JWTs are pretty cool, but let’s talk about some of the downsides of JWTs and some of their strong benefits.
Copy file name to clipboardExpand all lines: module4-authentication-and-security/r1.2-adding-authorization-layer/README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,7 +22,7 @@ With authorization, we introduce another level of app security. In this lesson,
22
22
- Authentication by a client usually involves the server giving a certificate to the client in which a trusted third party such as Verisign or Thawte states that the server belongs to the entity (such as a bank) that the client expects it to. This is required to initiate secure communication (HTTPs) between client and server.
23
23
- Authentication does not determine what tasks the individual can do or what files the individual can see (aka scopes). Authentication merely identifies and verifies who the person or system is.
24
24
25
-
## **Role-based authorization**
25
+
## Role-based authorization
26
26
27
27
By role-based authorization, we assign a role or roles to the user either when we register them, or by some other mechanism that happens later to elevate a user access level.
Copy file name to clipboardExpand all lines: module4-authentication-and-security/r1.2.1-authorization-through-middleware/README.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -53,7 +53,7 @@ We've seen middleware in previous lessons when we used the `express-session` and
53
53
- Append the created or read `session` to `req`.
54
54
- Call `next()` to let the app continue its req-res cycle.
55
55
56
-
### **Middleware precedence**
56
+
### Middleware precedence
57
57
58
58
In Express.js middleware are applied in their order of use. Remember that every function that has `req` and `res` is a middleware function. And the middleware stack is established when you use `app.use` or `router.use`.
59
59
@@ -68,7 +68,7 @@ So it is important whenever you define your middleware that you make sure the re
68
68
69
69
For example, in your `onlyAuthenticated` middleware, you will need to check `req.session.user` (or `req.user` if you use `express-jwt`). Hence, it is important that the session middleware is applied before your middleware. Otherwise, you won't have `session` inside `req`.
70
70
71
-
### **Middleware mount-path**
71
+
### Middleware mount-path
72
72
73
73
Middleware can be scoped as well. It can be for every request, or for specific endpoints, or even specific HTTP methods:
All the middleware we've seen so far take only **three** arguments, `req`, `res`, and `next`. You can define an error-handling middleware by providing **four** arguments: `err`, `req`, `res`, and `next`. These middleware are important to handle errors that are thrown in your app and provide a safe fallback response to clients without exposing your app's security.
108
108
@@ -117,7 +117,7 @@ Usually, an error logging service like [sentry](https://sentry.io/) is also cont
117
117
118
118
> ⚠️ **Warning**: Error-handling middleware always takes **four** arguments. You must provide four arguments to identify it as an error-handling middleware function. Even if you don’t need to use the next object, you must specify it to maintain the signature. Otherwise, the next object will be interpreted as regular middleware and will fail to handle errors.
119
119
120
-
## **Auth guard middleware**
120
+
## Auth guard middleware
121
121
122
122
To implement `onlyAdmins`, `onlyModerators`, and `onlyAuthenticated` middleware, we create a new middleware containing source file:
0 commit comments