Session management and security in SPA

Priyamvada Pant
7 min readMay 21, 2018

--

As the web is growing at a very fast pace and deepening its roots in every sphere of our lives, the applications serving us are getting more and more complex. And as a consequence developers are uncovering new challenges to ensure high level of trust and security for our web applications.

Problems with the traditional approaches

  • Cookies : Approaches used by traditional web applications do not prove to be useful for a true stateless architecture where there is no server-side web session. Traditional applications store cookies in browsers for authentication but this exposes the application to many security threats.
  • Vulnerability : Using cookies as the sole method of authentication is simple and works great until you realise the big loophole of CSRF and XSS attacks. As the cookies which contain the authentication token are always sent to the server, no matter how the request is initiated.
  • Platform-specificity : Cookies are primarily designed for web browsers and not for other types of clients such as native mobile applications or desktop programs.
  • Other limitations are size of the cookie and access to user to for disabling, modifying or erasing them.

Is using token based authentication better?

  • Flexible :Since token based authentication doesn’t require the use of cookies it makes solutions friendly to mobile applications and also helps with CORS (cross-origin resource sharing) issues.
  • Controllable: HTTP cookies are always automatically passed by the browser, no matter what causes the request, whereas you have complete control over when to pass a token.
  • Fast: Token signatures can be quickly validated by a target system (API or web server) and don’t necessarily require a call-out to a separate system for validation.

Concerns with SPAs

Although security issues are not unique to SPAs. It’s just that in a non-SPA you have to secure the individual pages on the server, whereas in a SPAs you have to secure the data endpoints on the server which are ultimately and totally responsible for ensuring the security of the data and the application

Major security threats

1. Cross Site Scripting (XSS)

Occurs when a vulnerable application allows arbitrary javascript code to be injected and executed on your page. This often occurs through the form fields on the page.

You can see this behavior in action, in the clip below . This is taken from the app security live example page.

Since this site is not protected against XSS attacks, it executes the code put in script tags into the search field of the page form.

There are three categories of XSS flaws:

  • Stored: Where the malicious string originates from the website’s database. ( Input JS in a field, sent to DB, sent back to the page )
  • Reflected : Where the malicious string originates from the victim’s request. ( Input JS in URL, the URL sent to the user, JS executed)
  • DOM Based : Where the vulnerability is in the client-side code rather than the server-side code. ( Input triggers JS logic that manipulates the DOM and insert custom JS)

Ways to prevent XSS from your app

i) Escaping user input : Its the censoring of the data your web page receives and does not permit the characters — especially < and > characters — from being rendered, which otherwise could cause harm to the application and users. For example : esc_js() is intended for inline Javascript.

<a href="#" onclick="<?php echo esc_js( $custom_js ); ?>">Click me</a>

ii) Validating Input :Validating input is the process of ensuring an application is rendering the correct data and preventing malicious data from doing harm to the site, database, and users. Whereas disallowing certain, predetermined characters in user input, disallows only known bad characters, validating only allows known good characters and is a better method for preventing XSS attacks as well as others.

<input id="my-zipcode" type="text" maxlength="5" name="my-zipcode" />

Validating the input:

$safe_zipcode = intval( $_POST['my-zipcode'] );if ( ! $safe_zipcode )$safe_zipcode = '';update_post_meta( $post->ID, 'my_zipcode', $safe_zipcode );

iii) Sanitizing: Sanitizing user input is especially helpful on sites that allow HTML markup, to ensure data received can do no harm to users as well as your database by scrubbing the data clean of potentially harmful markup, changing unacceptable user input to an acceptable format.

<input type="text" id="title" name="title" />

Sanitizing the input :

$title = sanitize_text_field( $_POST['title'] );
update_post_meta( $post->ID, 'title', $title );

2. Cross Site Request Forgery (CSRF)

Occurs when a malicious program causes a user’s web browser to perform an unwanted action on a trusted site for which the user is currently authenticated. CSRF occurs when a malicious site has a link or form that connects to another site that you are already logged into.

A browser will send an authentication cookie or token with a HTTP request even if the request didn’t originate from a page of the application. This way, a malicious web site can send commands to another website which relies on browser stored tokens for user authorization.

Ways to prevent CSRF from your app

i) Synchronizer Token

In this solution we ensure that each request requires, in addition to our session cookie, a randomly generated token as an HTTP parameter. When a request is submitted, the server must look up the expected value for the parameter and compare it against the actual value in the request. If the values do not match, the request should fail.

ii) Origin header check

In this approach, we send an Origin header in the requests which is not allowed to be set by JavaScript. The server can then explicitly check that header and verify that the base URI matches the server’s. The server rejects browser requests where the base URI in the Origin header does not match the expected value.

iii) Double Submit Cookie

In Double Submit Cookie approach, two cookies are sent back to the browser. One is the session id and the other is a random value (similar to the synchronizer token). There are two keys to this mechanism working. The first is a mechanism built into the browser called the Same Origin Policy. This permits the script code to interact with other server endpoints only if those endpoints have the same origin (base URI) as the endpoint that delivered said script code.

Now a very valid question might pop-up in your mind, “If one cookie isn’t secure on its own, how are two cookies going to be more secure?” The key is in the second enabling mechanism: Having the second cookie included in subsequent requests in a custom header. It is up to your client script code to ensure that this is setup properly.

Is JSON Web Token (JWT) the saviour?

A JSON Web Token (JWT) pronounced “jot” is a encoded and signed JSON object that is defined in RFC 7519 that provides a compact and self-contained way for securely transmitting information between parties. The information can be verified and trusted because it is digitally signed.

JSON Web Token structure is of the form header.payload.signature.

Header: The header typically consists of two parts: the type of the token, which is JWT, and the hashing algorithm being used,

Example:{“alg”: “HS256”, “typ”: “JWT” }

Then, this JSON is Base64Url encoded to form the first part of the JWT.

Payload: Payload contains the claims. Claims are statements about an entity (typically, the user) and additional metadata. There are three types of claims: registered, public, and private claims.

  • Registered claims: Optional set of predefined claims which provide a set of useful, interoperable claims.
  • Public claims: These can be defined at will by those using JWTs.
  • Private claims: These are the custom claims created to share information between parties that agree on using them and are neither registered or public claims.

Example:{ “sub”: “1234567890”, “name”: “John Doe”, “admin”: true }

The payload is then Base64Url encoded to form the second part of the JSON Web Token.

Signature: To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

For example if you want to use the HMAC SHA256 algorithm, the signature will be created in the following way:

HMACSHA256(base64UrlEncode(header) + “.” +base64UrlEncode(payload),secret)

Why should we use JSON Web Tokens?

  • Size: JWT is more compact than SAML. This makes JWT a good choice to be passed in HTML and HTTP environments.
  • Security : SWT can only be symmetrically signed by a shared secret using the HMAC algorithm. However, JWT and SAML tokens can use a public/private key pair in the form of a X.509 certificate for signing. Signing XML with XML Digital Signature without introducing obscure security holes is very difficult when compared to the simplicity of signing JSON.
  • Parsing : parsing JWT token is usually much faster than the SAML token which is XML based.
  • Usage: JWT is used at Internet scale. This highlights the ease of client-side processing of the JSON Web token on multiple platforms, especially mobile.

At last, I would recommend watching this amazing demonstration by Dominik Kundel.

--

--