PHP Security Crash Course - 3 - CSRF
PHP Security Crash Course - 3 - CSRF
PHP Security Crash Course - 3 - CSRF
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 1
What is Cross Site Request Forgery?
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 2
„Blind“ Browser Trust (I)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 3
„Blind“ Browser Trust (II)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 4
Simple CSRF Attacks (I)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 5
Simple CSRF Attacks (II)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 6
CSRF Example: Step by Step (I)
User-Generated-Content
www.my-movie-community.de
<IMG src=“http://www.mybank.de/transfer.php?
amount=0,99&account=123456789“>
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 7
CSRF Example: Step by Step (II)
User-Generated-Content
<IMG src=“http://www.mybank.de/transfer.php?
amount=0,99&account=123456789“>
www.my-movie-community.de
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 8
CSRF Example: Step by Step (III)
GET /transfer.php?amount=0,99&account=123456789
www.mybank.de
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 9
CSRF Example: Step by Step (IV)
ERRORMESSAGE
www.mybank.de
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 10
CSRF Example: Step by Step (V)
SUCCESSMESSAGE
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 11
CSRF Example: Step by Step (VI)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 12
Real Damagepotential of CSRF
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 13
Attackvectors
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 14
CSRF Protections
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 15
Not working CSRF Protections (I)
• „Referer“ protection
• checking the „Referer“ HTTP header
• ignoring the HTTP requests if „Referer“ is incorrect
• not working because
• (desktop-)firewalls block/modify the „Referer“
• browser sometimes do not send „Referer“
• attack from within Adobe Flash can spoof „Referer“
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 16
Not working CSRF Protections (II)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 17
Not working CSRF Protections (III)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 18
Working CSRF Protections (I)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 19
Working CSRF Protections (II)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 20
Working CSRF Protections (III)
Protection by CAPTCHA
• makes automatic abuse hard or impossible
• CAPTCHA image is protected by same-origin-policy
• attacker won‘t be able to see the image without a browser
vulnerability
• requests with valid CAPTCHA answer can only be intended
(if CAPTCHA URL is not guessable)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 21
Working CSRF Protections (IV)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 22
Generation of „secret“ Form Tokens
function generateFormToken($formName)
{
$token = md5(uniqid(microtime(), true));
$_SESSION[$formName.‘_token‘] = $token;
return $token;
}
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 23
Checking the „secret“ Form Tokens
function verifyFormToken($formName)
{
$index = $formName.‘_token‘;
return true;
}
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 24
Using the „secret“ Form Tokens
if (!isset($_POST[‘submit‘])) {
$newToken = generateFormToken(‘loginForm‘);
die();
}
if (!verifyFormToken(‘loginForm‘)) {
die(‘CSRF Attack detected.‘);
}
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 25
Questions ?
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 26