Introduction: Cookies are one of the most sensitive items during a user’s session. An authentication cookie is as powerful as a password. Security of these authentication cookies is an important subject. This article demonstrates how we can implement some of the cookie attributes in PHP applications in order to protect cookies from certain attacks. Cookie protection using HTTP Headers: HttpOnly: It is a known fact that, Cross Site Scripting is one of the dangerous vulnerabilities that allows an attacker to steal cookies from the user browser. HttpOnly is introduced to disable the ability to read cookies using external JavaScript. Even if an application is vulnerable to XSS, it is not possible to read cookies when HttpOnly flag is enabled. Let us launch our sample application we used in the previous articles to see how it can be accomplished. First, lets look at the headers from the HTTP response. [plain] HTTP/1.1 200 OK Date: Sun, 12 Apr 2015 15:07:14 GMT Server: Apache/2.2.29 (Unix) mod_fastcgi/2.4.6 mod_wsgi/3.4 Python/2.7.8 PHP/5.6.2 mod_ssl/2.2.29 OpenSSL/0.9.8y DAV/2 mod_perl/2.0.8 Perl/v5.20.0 X-Powered-By: PHP/5.6.2 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Set-Cookie: PHPSESSID=a2ed2bf468dd811c09bf62521b07a023; path=/ Content-Length: 820 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html; charset=UTF-8 [/plain] As we can see, there are no additional flags with the Set-Cookie header and thus an attacker can read this session id if the application is vulnerable to XSS. In order to avoid this, we can implement HttpOnly flag, which enables us to send cookies only over http protocol but not JavaScript. Enabling HttpOnly flag in your application: The sample code snippet below shows a way to set HttpOnly flag in PHP applications. [php]
As we can see in the above figure, the script we executed is unable to read the cookies though the application is vulnerable to XSS. Secure: The next cookie attribute is “secure”. We often see websites that run on both HTTP and HTTPS. When an application sends its cookies over HTTP, it is possible that they can be hijacked using various ways since they are transmitted in clear text format. “secure” attribute on set-cookie header forces your application to send cookies only over HTTPS. Below is the code snippet that shows how we can use “secure” flag in PHP applications. [php]
As we can see in the above figure, “Session” is checked. This ensures that our session will not be active upon closing the browser. The same can also be seen from chrome’s developer tools as shown below.
Following are some other cookie attributes Domain: This attribute gives control on the domains that can access the cookies. Path: it specifies the path of the domain that can have access to the cookie set by the server. Expiration: It specifies when this cookie has to be expired. So that the cookie won’t be valid anymore. We can set all these attributes in PHP applications just with three lines of code as shown below. [plain] ini_set(“session.cookie_secure”, “True”); //secure ini_set(“session.cookie_httponly”, “True”); //httponly session_set_cookie_params(3, ‘/’, ‘.localhost’); //This cookie is valid for 3 seconds (max age) // “/” ensures that this cookie is valid on all //paths of this domain // since the domain is prefixed with dot, this //cookie is accessible from all the subdomains. session_start(); [/plain] When we load the page with the above attributes, the response headers will be as shown below. [plain] HTTP/1.1 200 OK Date: Thu, 30 Apr 2015 03:04:11 GMT Server: Apache/2.2.29 (Unix) mod_fastcgi/2.4.6 mod_wsgi/3.4 Python/2.7.8 PHP/5.6.2 mod_ssl/2.2.29 OpenSSL/0.9.8y DAV/2 mod_perl/2.0.8 Perl/v5.20.0 X-Powered-By: PHP/5.6.2 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Set-Cookie: PHPSESSID=f4d99777d9810bfedb6869acd556bc66; expires=Thu, 30-Apr-2015 03:04:14 GMT; Max-Age=3; path=/; domain=.localhost; secure; HttpOnly X-XSS-Protection: 1 Content-Security-Policy: script-src ‘self’ Content-Length: 820 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html; charset=UTF-8 [/plain] In this article, we have seen how cookies can be secured using various attributes available with set-cookie response header. Though, these concepts can drastically improve the security of a web application, we cant solely depend on those headers to protect an application, rather we should consider using them to add additional layer of security.