As we continue to develop what I like to think is Enterprise PHP software, one of the most painful parts of the software installation is when we have to go through security audits. The most sticky and difficult ones that i have seen are the audits of financial institutions.
After a while, the requirements are pretty similar, but to pass our first audit wasn't easy. Here's a sampling of what is required:
- All important work processes must include a maker and a checker. In other words, if i make an important request (the maker), then someone else must check and authorize (the checker).
- All transactions must store an unique ID, parties who were active in the transaction, the data that was changed (before and after) and a timestamp.
- All database passwords used in PHP/ASP must be encrypted.
- Tripwire (to detect files that have been modified) must be installed if the web app is open to the Internet.
- Database connection (and password decryption) must be made through DLL or compiled script.
- The password key should not be stored in clear text in the compiled code, but obfusticated or split into multiple parts.
- Users must change passwords on first login.
- All database passwords must be encrypted using the bank's favorite algorithm (eg. SHA-1, 3DES, AES, etc).
- All user passwords must be encrypted using the bank's favorite algorithm (eg. SHA-1, 3DES, AES, etc).
- Users are locked out after X failed attempts. An exception is made for the main administrator.
- Users can be barred from logging in.
- All critical passwords of powerful accounts have to be split and held by 2 people.
- All passwords must be a mix of alpha and numeric, and of a configurable minimum length.
- Passwords must be changed every X days, typically 30-90 days.
- Passwords cannot be repeated X times; the highest value i have seen is 24.
- Passwords must not begin with the first X characters of user id.
- Session keys must be regenerated on every login [use regenerate_session_id()]. In one case, the audit team used a http proxy server which captures packets to confirm this and the next item.
- Cookies must not hold important information, eg. only the session id and similar info.
- Cross-site scripting was tested. The same audit team entered <script>alert('attack')</script> in a sampling of our input fields.
- Reports such as "accounts dormant for more than X days", "login attempts and failures", "user access matrix" have to be available.
- File permissions are also audited and limited.
- No service nor job is allowed to run with superuser rights.
- Administrator can force a user to logout remotely (this means giving a UI for manually deleting the session records stored in the database)
And that is only the web app hardening! Sometimes we have to go through both OS hardening and database hardening audits also.