I wasn't being very precise there, but I meant security "best practices" -- common precautions and programming habits that most security experts agree are good for security. Some examples for apps written in PHP:
- bcrypt (at least 10 work factor) or PBKDF2 (at least 10K iterations of sha256) for password hashing.
- PDO and prepared statements for all DB queries. Don't let me find a single `mysql_query()` function call in your codebase, the mysql extension is deprecated anyway.
- Proper XSS filtering with HTMLPurifier or equivalent. BBCode and Markdown are not XSS filters, don't trust their regexps to keep you safe.
- Systematic protections against CSRF attacks. Don't do it manually. Don't trust plugin authors to get it right. Use a helper to insert a token to every form and every AJAX call. Validate the token automatically when submitted. No exceptions.
- Protections against arbitrary code execution via uploaded files (Never execute or `include` them!)
- Out-of-the-box compatibility with SSL (especially when generating absolute URLs), HTTP Strict Transport Security, set cookies with "secure" and "httponly" flags by default, etc.
- UTF-8 everything (primarily for convenience, but also helps protect against XSS and SQL injection using weird charsets)
Thanks for the answer, it makes very clear. Can I also ask how one learns about the latest best practices? I have come across many of these just by reading websites on the web.
Do most people learn these by reading books, reading about other people's mistakes or security blogs?
Unfortunately there is no single source that has all the best practices right. This is especially true of PHP, where too many tutorials are written for absolute beginners and not enough for advanced users. You just have to read a lot of stuff from many sources and stay tuned to the latest developments. (Avoid any PHP tutorial that is more than 3 years old. PHP development has really picked up in the last few years.)
phpbestpractices.org is definitely above average, but it seems light on security-related stuff. It's also getting a little long in the tooth in some parts. Possible modifications:
- Replace phpass with password_hash(), it has an even simpler interface.
- Don't close the ?> tag if possible. (Follow the PSR-0, PSR-1 and PSR-2 coding standards.)
- Use htmlspecialchars() instead of htmlentities()
- Know when not to use the resource-intensive DateTime class.
- Know that PHP 5.5 introduces a new opcode cache that isn't APC.
- This is down to personal preference, but I think SwiftMailer is more "modern" than PHPMailer and integrates better with third-party mailing APIs.