This is a 3 part series.
Over the past couple of months, I’ve been implementing an authentication system for a Zend Framework project I’m working on in my spare time. This post is going to outline considerations when building an authentication system for web applications built with Apache HTTPD, PHP and Zend Framework.
Authentication is a lot more complex than a simple username and password in a database, a form and some business logic to confirm that the credentials match. When building an authentication system for your website, you’ll also need to consider browser persistence (remember me), session hijacking, database security and SSL/HTTPS and what impact these things have across multiple domains and servers.
Table of Contents for Part 1: Session
- Session Cookies
- Multiple Servers
- Session Hijacking
- RULE: Sensitive data should always be transmitted over HTTPS
- RULE: Never Trust Visitor Inputs
- RULE: Regenerate Session Cookie Regularly
- RULE: Don’t allow session data to be accidentally sent over non-secure HTTP
Session persistence is built into PHP with the $_SESSION variable and accessible in Zend Framework with the Zend_Session component. It’s an effective way of keeping persistence whilst a visitor is using your web application but expires after a short period of time, usually 20 minutes. PHPSESSID is the default name of the browser cookie dropped on the browser by PHP.
One option for longer persistence is to increase the session lifetime in PHP (http://www.php.net/manual/en/session.configuration.php). This is not suitable when you’re talking about persisting a visitor’s login credentials for 7+days as it will introduce a large resource burden on Apache HTTPD, plus, sessions are cleared when Apache HTTPD is restarted.
To change the persistence duration of visitor’s sessions:
- PHP ini – ini_set(‘session.remember_me_seconds’, 864000); // 10 days
- Zend_Session::setConfig(array(‘remember_me_seconds’ => 864000)); // 10 days
Session data is only accessible on the Apache HTTPD server that collected the data. If a website runs across multiple servers and a visitor authenticates against one server, their credentials will be stored in that one server’s session (via PHP’s $_SESSION). On the next request, if the visitor hits a second server, they will be prompted to authenticate again as the second server’s session does not have the credentials stored and does not have access to the first server’s session data.
To get around this, memcached can be used to store session data. Memcached is a distributed cache which solves the problem of servers sharing their session data. See implementation instructions here: http://www.vexedmonkey.com/2008/08/01/zend-framework-sessions-in-memcache/
Session hijacking (and here) is where a hacker sniffs a victim’s network traffic or gains access to the victim’s browser cookies and steals their session cookie. The PHP session browser cookie, PHPSESSID, contains a string (session key) like “fe070316c67d426ce92df402c281ad1e”. This session key is used by PHP to access the visitor’s session data (accessible via PHP’s $_SESSION).
If a hacker copied a victim’s session key and placed it into their own browser, they would gain access to the victim’s session and could use the website as if they were the victim.
RULE: Sensitive data should always be transmitted over HTTPS
To mitigate this risk, it’s essential that all network traffic on the domain/subdomain containing sensitive information is done so over SSL (HTTPS). Remember, over unencrypted HTTP, cookies are sent in plain text.
RULE: Never Trust Visitor Inputs
A hacker could gain access to a victim’s cookies using a cross-site-scripting (XSS) hack. To mitigate against this danger, it’s very important that all user supplied contents is run through a sanitisation/validation filter such as Zend_Filter, PHP’s filter_var() or HTMLPurifier.
Both Zend_Filter and filter_var() are excellent ways at sanitising and validating visitor inputs if the input is not HTML. If the visitor input is HTML, Zend_Filter and filter_var() will not do the job as they cannot validate or sanitise HTML.
HTMLPurifier is a very well written and maintained library that should be used to filter all visitor inputs, particularly if the visitor inputs contain HTML code.
RULE: Regenerate Session Cookie Regularly
To reduce the risk of session hijacking, the following code should be added when initiating Zend_Session:
// At the point at which session is initiated, regenerate session Id
The above code will regenerate a visitor’s session Id on each request, reducing the chance of a hacker sniffing your network traffic, copying the victim’s session Id and then using it.
RULE: Don’t allow session data to be accidentally sent over non-secure HTTP
If you were to require a visitor to login with their credentials over SSL (HTTPS), the session cookie is private and a hacker would not be able to view your session cookie or hijack your session.
What if the website then directed the visitor off to a non-secure page, or the visitor chose to view the website’s FAQ on a non-secure Url? When the request to the non-secure Url is made, the session cookie would be transported over a non-secure Url, making session hijacking a very possible threat.
To mitigate this risk, there are a couple of choices:
1. PHP session data is only available over SSL:
- PHP ini – ini_set(‘session.cookie_secure’, 1); // 0 – false, 1 – true
- Zend_Session::setConfig(array(‘cookie_secure’ => 1)); // 0 – false, 1 – true
The limitiation is that non-secure Urls will not have access to PHP’s $_SESSION variable. No longer able to persist non-sensitive data such as visitor layout or page flow without requiring the whole user experience to run across SSL (HTTPS).
2. Keep all secure communications with the server on a separate domain eg https://secure.example.com where the non-secure domain would be http://www.example.com
Both would have their own session cookie (PHPSESSID) meaning that a hacker could hijack the non-secure session by sniffing network traffic but would only find non-sensitive data and wouldn’t be able to view the contents of the secure one, which contains the visitor’s credentials.
Part 2: Cookies
Part 2 will cover the importance of cookies in authentication systems and how to effectively secure them to keep your visitor’s sensitive data safe.
Considerations When Building an Authentication System (Part 2: Cookies)
About the Author
Brett is the Lead Web Developer at BBC.com working on a number of products, such as the BBC International Homepage, News, Sport, Travel and the back-end work on the iPhone and iPad applications.