Things to Check to Make Sure PHP Code is Secure
Here are some things to check to make sure PHP code is secure.
- Check to make sure you are validating or filtering inputs. Search $_GET, $_POST, $_REQUEST. Use filter_var(), strip_tags(), htmlentities() ). This and escaping outputs is to prevent cross-site scripting, which is one of the most common vulnerabilities in web apps. Use of $_REQUEST not recommended.
- Escaping outputs (use htmlspecialchars() or htmlentities()) – see here for the preferred method. Search “echo”, “print”, and even “<?=”.
- Check for SQL injection vurnerabilities. Use prepared statements using mysqli or pdo extensions. Watch for the “union select attack” that is not prevented by prepared statements.
- Look for RPO (defined here and here) or directory traversal attack. Never a good idea to have any user-input derived variables in “include”, “include_once”, “require”, “require_once”, “fopen”, or “file_get_contents” . A variable in path is a red flag. If you do need to have a variable path/filename, make sure you validate it or use preg_replace so that it doesn’t contain “../” and build your safe directory path using __DIR__. Same with autoloaders which loads file paths. Look for “__autoload” or “spl_autoload_register”. If only need filename, strip out the path using basename(realpath($filename))
- Security checks on forms and use single-use hash to generate anti-CSRF token.
- Security checks when uploading files also check file extension. Use of basename() and move_uploaded_file() is key.
- Check for calls to loadXML (if you find such calls, add code as suggested here)
- filter_var with flag FILTER_VALIDATE_URL has a loop hole which you need to fill (details here)
- Don’t have sensitive configuration files inside the web root. Don’t zip up source code and put in public web. Source code may contains passwords to databases.
- Check for magic_quotes Ideally, it should be disabled.
- disable register_globals (if register_globals is used, watch for uninitialized vars)
- display_errors to Off in production systems
- use session_regenerate_id() after each login process or elevated privileges to prevent “session fixation“. Also consider changing the session name away from the default PHPSESSID.
- Password used by code needs to be strong password.
- If saving user passwords, use phpass to salt, hash, and stretch the password before saving. And watch this.
- Password in code not accessible should not be in public git repository or in zip backup files that are publicly accessible. Best to place is config file outside of doc root.
- Error logging should be turned on. Error display should be off in production.
- Make sure no calls to phpinfo is in production code
- Preferably to use cookie for passing session info rather than in query string
- Add <meta charset=”UTF-8″> to prevent character-encoding based attacks.
- Remember to expire the cookie when logging out.
- If using file_get_contents for an https resource, you need to verify peer by setting context option and not have CURLOPT_SSL_VERIFYPEER set to false. The article advises that “all HTTPS requests are performed using the CURL extension for PHP”.
- The rand() is not random enough. Use RandomLib instead. Don’t seed random generators and avoid exposing uniqid to users. Example of use include password reset tokens in anti-CSRF tokens.
- Look for dangerous php functions: eval(), exec(), system(), file(), file_get_contents(), passthru(), popen(), proc_open(), readfile(), shell_exec(). preg_replace() can be dangerous when used with the “e” modifier (same risk as eval()).
- Look for dangerous php.ini settings. register_globals should be off. The allow_url_include, allow_url_fopen, enable_dl, file_uploads should be off if not used. open_basedir and disable_functions might be useful.
- Make sure .htaccess does not allow direct directory browsing.
- Make sure protected pages actually does check the login state.
- Make sure sufficient logout including expiring the cookie.
- Shared hosting is not very secure because hacked or malicious site on the same server can browse your source code or expose your session data file.
Useful online references…
- PHP Security Consortium
- Survive the Deep End
- Security on PHP.net
- Essential PHP Security book excerpt
- Sitepoint forums
- Seven Habits for Writing Secure PHP applications
udemy Writing Secure PHP Code
Lynda.com Creating Secure PHP Websites