In this blog post (my first ever!) I will discuss some of the most common security vulnerabilities on the web. The code examples will be in PHP, but most vulnerabilities discussed are not a PHP problem in specific and can (and are) found in projects crated using other languages.
I have also created a GitHub repository containing the vulnerabilities and the fixes which you can clone locally to try it out. Keep in mind that this project should never be available to the public for obvious reasons.
PHP has the concept of variable variables meaning you can use variable variables names:
$name = 'foo';
$$name = 'bar';
var_dump($foo); // outputs string(3) "bar"
Besides the fact that in most cases you probably just want to use an associative array instead, the above can result in security issues when used inappropiately. On more then one occasion I have seen people for example using POST data in this way:
foreach($_POST as $key => $value){
${$key} = $value;
}
The problem with this appraoch is that you are overwriting local variables with data coming from the client / user. This will result in a debugging nightmare at best and security vulnerabilities at worst. Consider the following code:
<?php
$dbhost = 'localhost';
$dbuser = 'dbuser';
$dbpass = 'thepassword';
foreach ($_POST as $key => $value) {
${$key} = $value;
}
This would mean I could overwrite the three local variables with my own values using a POST request. Meaning for example (there are numerous ways to exploit this vulnerability) I could overwrite the database connection credential variables so that everything gets inserted in my own (the attacker's) database instead of yours.
Now before you say "but those names (dbhost, dbuser and dbpass) are not in my form, so the user will never post it" any attacker can easily send a specicially crafted POST request to your server by simply editing the form in the browser's developer tools or even by sending a manually created request using cURL or some other HTTP client.
Another (but related) vulnerability is by using PHP's extract()
function. The extract function basically does the exact same thing as the previous example. It uses all data from an array and "converts" it to "normal" variables:
<?php
$dbhost = 'localhost';
$dbuser = 'dbuser';
$dbpass = 'thepassword';
extract($_POST);
To mitigate this issue you have to pass the second parameter ($flags
) to the function, because the deault behavior of the function is to overwrite existing variables.
phpinfo();
error reporting (also note the password leakage of PDO)