Tuesday, November 24, 2009

php basic security methods

Basic Security Methods
The following should be in place in your system, as a minimum.
  1. Login names and passwords should be 6 characters long, or more
  2. In the event of login failure, be very uncooperative
    Tell the user "Your login attempt was unsuccessful", not "Your password was missing the letter x" or "Your username is not in our system". Give very few leads as to why the login failed. They only serve to help intruders.
  3. Handle errors gracefully
    Place the ampersat symbol (@) in front of many of your PHP function calls. If they fail, the ampersand will stop from from showing that failure in the browser window. This is very useful when making database calls but your database is down, or the SQL statement returns an error. Such messages would only give feedback to intruders, or look unprofessional to regular users.
  4. Passwords in the user account table of your database must be encrypted (SHA-1)
    If someone were to somehow gain access to the database itself, and view all of the user accounts, they would be able to see logins, but not passwords. Unless they changed the password, which would alert the user once they realized they couldn't log in, or they tried to crack the encrypted password (possible, but hard) they would have no way of using their newly found information.
    To accomplish this, the "password" field in your SQL datbase should be 40 characters long, which will hold an SHA-1 encrypted string. Before you compare the user input password to the one stored in the database, use the PHP sha1() function to encrypt it.
    Example: $encrypted = sha1($password);
    Sample database data:
    Login name: bobsmith
    Password: d0be2dc421be4fcd0172e5afceea3970e2f3d940
  5. Never use "admin" or "root" as your adminstrator login name
    Try to use something else, one that gives the same idea, but is more unique. Some examples are: superman, wonderwoman, allpower, etc...
  6. Log the total number of logins for each user, as well as the data/time of their last login
    Logging the total is just a good indicator, and *may* be useful for security purposes depending on your system. Keeping track of their last login is very useful in the event that someone logged in using their account, without permission. You now know the time it happened, and if you log the date/time of any changes in your database and by whom, you can track what that intruder did while logged in.
    In order to accomplish the above, the user account table in your SQL database should have three extra fields:
    Logincount of type INTEGER
    Lastlogin of type TIMESTAMP (or datetime)
    Thislogin of type TIMESTAMP (or datetime)
    When the user logs in, in PHP, update that user's information in the database by incrementing their login count and by getting the timestamp using PHP's built in date() function. After successful login, first transfer the info stored in 'Thislogin' to the 'Lastlogin' field, and then insert the new date/time into 'Thislogin'.
  7. Strip backslashes, HTML, SQL and PHP tags from any form field data
    If someone maliciously tries to send HTML, SQL or PHP code through a text field entry not meant to expect it, they can disrupt or break your code. Use the following PHP functions to strip out such text:
    strip_tags(), str_replace() and stripslashes()
    Example: $login = @strip_tags($login);
    Example: $login = @stripslashes($login);
  8. Add "LIMIT 1" to the end of your SQL statements
    That will limit the number of results to just 1. If someone successfully hijacks your site, and is able to run a SQL statement that returns data, or deletes it, placing "LIMIT 1" at the end of any SQL string will help limit the amount of data they are able to see or damage.
    Example: SELECT * FROM useraccount WHERE Login='$login' AND Password='$encrypted' LIMIT 1
  9. Use the "maxlength" option in your HTML form elements
    Limit the user to the allocated input size. If an login field in your SQL schema is of size 8 characters, limit the text field input to 8 using maxlength.
    Example:
  10. Trim any and all form field data
    Trim down the length of any form field data. If you expect a string of length 8, don't rely on the HTML maxlength (above), or the kindness of the user to pass you a string that long. Cut it down to size. Always.
    substr()
    Example: $login = @substr($login, 0, 8);
  11. Check the referrer
    Make sure the login script checks the HTTP_REFERER to see where the request came from. It should come from your HTML form, on the same server. If not, reject the login attempt. Though, I must tell you the HTTP_REFERER is easy to "spoof", or fake, so this security measure is easy bypass. It will only stop simple spam bots, or the most amateur of attackers.
  12. Use $_POST not $_REQUEST
    If your HTML form uses POST to send the data to the login script, then make sure your login script gets the input data using $_POST, and not $_REQUEST. The latter would allow someone to pass data via GET, on the end of the URL string.
  13. SSL Encryption (https)
    To better ensure the privacy of the data being sent across the internet, purchase an SSL certificate to encrypt the login page, and any others.
  14. In general, limit user access according to their role
    Design your system to give users specific layers, or subsets of access. Not everyone needs to be all powerful, nor all knowing. Using the unix group idea as your starting point. Classify users and give them features based on that. If you have a system with multiple users who have different roles, give them functionality based on those roles. Accountants, and only allow accountants can see financial data, not warehouse inventory or much else. The person at the cash register can enter in a sale, but not delete it. That is a managers job, and needs override permission. Etc....

No comments: