Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protecting against CSRF attacks in Aurelia

In Aurelia, there doesn't seem to be any support for CSRF protection yet, as opposed to AngularJS's XSRF-TOKEN header which is set automatically on all XHR requests by the AngularJS framework.

How should I go about protecting an Aurelia app from CSRF attacks? Should I roll my own support based on the OWASP CSRF Prevention Cheat Sheet, or are there any alternatives out there for Aurelia already?

like image 298
Svein Fidjestøl Avatar asked Jul 14 '15 06:07

Svein Fidjestøl


2 Answers

You should be able to do this yourself fairly easily by using Aurelia's HTTP interceptors (see examples in the docs). Before every request, you can send your token. This can be done with both the conventional aurelia-http-client and the new standard aurelia-fetch-client.

Your code might look like this:

export class MyRestAPI {
    static inject () { return [HttpClient]; } // This could easily be fetch-client

    constructor (http) {
        this.http = http.configure(x => {
            x.withBaseUrl(myBaseUrl);
            x.useStandardConfiguration();
            x.withInterceptor({
                request: function (request) {
                    request.headers.set('XSRF-TOKEN', myAwesomeToken);
                    return request;
                }
            });
        });
    }

    ...

}

On every request, your token would be sent. You'd have to handle the validation on the server side. You could easily set up your code so that your initial request could grab a token, or you could pass a token back as part of your authentication payload, or if you wanted to you could even store a token in the browser's localstorage and use it that way.

You could even go a step further and implement JWT authentication. If you're using node.js, I have a small blog post that describes how I implemented JWT in Express. There's a plugin on Github called aurelia-auth that handles JWT, and there's a blog post on its implementation on the Aurelia blog as well.

like image 119
jedd.ahyoung Avatar answered Sep 22 '22 11:09

jedd.ahyoung


Here is a sample interceptor that reads the token from the response header if it exists and sets it automatically on every request that needs it.

import {Interceptor, HttpResponseMessage, RequestMessage} from "aurelia-http-client";

class CsrfHeaderInterceptor implements Interceptor {
  private static readonly TOKEN_HEADER = 'X-CSRF-Token';

  private latestCsrfToken: string;

  response(response: HttpResponseMessage): HttpResponseMessage {
    if (response.headers.has(CsrfHeaderInterceptor.TOKEN_HEADER)) {
      this.latestCsrfToken = response.headers.get(CsrfHeaderInterceptor.TOKEN_HEADER);
    }
    return response;
  }

  request(request: RequestMessage): RequestMessage {
    if (this.latestCsrfToken) {
      if (['POST', 'PUT', 'PATCH'].indexOf(request.method) >= 0) {
        request.headers.add(CsrfHeaderInterceptor.TOKEN_HEADER, this.latestCsrfToken);
      }
    }
    return request;
  }
}

You register it in your http/fetch client with for example:

httpClient.configure((config) => {
  config
    .withBaseUrl("/api/") // adjust to your needs
    .withHeader('Accept', 'application/json') // adjust to your needs
    .withHeader('X-Requested-With', 'XMLHttpRequest') // adjust to your needs
    .withInterceptor(new CsrfHeaderInterceptor());
});
like image 43
fracz Avatar answered Sep 21 '22 11:09

fracz