ExpertRefresh

Basics

1) Which superglobals array is safe?






2) Which filtering approach is better from security point of view?





3) Which one is important for usabillity?








// Only $_SESSION is safe. // Whitelists filtering better than blacklists // Filter input with ctype_* // Escape html output with htmlentities() // Escape sql with mysql_escape_string($sql) // Register_globals must be off

Superglobals

All of PHP's superglobals arrays should be considered tainted. Even $_SERVER array is not fully safe, because it contains some data provided by the client. Only $_SESSION is safe.

Whitelist Filtering

Whitelists afford stronger protection against attacks than blacklists

Filter Input

Server-side filtering is important for security, while client-side validation is important for usability. Ctype functions are always preferred over regular expressions, and even to some equivalent "str_*" and "is_*" functions. This is because of the fact that ctype uses a native C library and thus processes significantly faster. <form method="POST"> Username: <input type="text" name="username"> Color: <select name="color"><option></option><option>Red</option><option>Blue</option></select> <input type="submit" name="btn_submit"> </form> <?php // You should force the user to provide correct information (ctype_*) if (isset($_POST['btn_submit'])) { $clean = array(); if (ctype_alpha($_POST['username'])) { // --- Look Here --- // $clean['username'] = $_POST['username']; } if (in_array($_POST['color'], array("Red", "Blue"))) { $clean['color'] = $_POST['color']; } var_dump($clean); }

Escape Output

Escaping output protects the client and user from potentially damaging commands. For Html escape use htmlentities(). For sql escape use mysql_escape_string($sql). <form method="POST"> Message: <input type="text" name="message"> <input type="submit" name="btn_submit"> <br><br> Example: <br> John's message is "Hellow World!" </form> <?php if (isset($_POST['btn_submit'])) { echo "nr" . htmlentities($_POST['message']); // John's message is &quot;Hellow World! // Will convert double-quotes echo "nr" . htmlentities($_POST['message'], ENT_QUOTES); // John&#039;s message is &quot;Hellow World! // Will convert both double and single quotes } Register Globals When set to On, the register_globals configuration directive automatically injects variables into scripts. <?php // Register_globals = on (security risks) <form method="POST"> Username: <input type="text" name="username" value="111aaa"/> <input type="submit" name="btn_submit"/> <input type='hidden' name='cleanUsername' value='1'> </form> <?php error_reporting(E_ALL & ~E_NOTICE); // register_globals = on (php.ini) / default is off if (isset($_POST['btn_submit'])) { if (ctype_alpha($_POST['username'])) { $cleanUsername = true; } if ($cleanUsername) { // will be loaded from globals echo $cleanUsername ? "Accepted" : "Denied"; // output accepted every time !!! } } A best practice for maintainable and manageable code is to use the appropriate superglobal $_GET, $_POST, $_COOKIE Before PHP 4.2.0, the register_globals configuration directive was set to On by default. Since then, this directive has been set to Off by default; as of PHP 6, it will no longer exist.