Защита от атак CSRF в Аурелии

В Aurelia пока нет поддержки защиты CSRF, в отличие от заголовка AngularJS XSRF-TOKEN, который автоматически устанавливается на всех запросах XHR с помощью инфраструктуры AngularJS.

Как я должен защищать приложение Aurelia от атак CSRF? Должен ли я использовать свою собственную поддержку на основе OWASP CSRF Cheat Sheet, или есть ли альтернативы для Aurelia уже?

Ответ 1

Вы должны сделать это довольно легко, используя Aurelia HTTP-перехватчики (см. примеры в документах). Перед каждым запросом вы можете отправить свой токен. Это можно сделать как с обычным aurelia-http-client, так и с новым стандартом aurelia-fetch-client.

Ваш код может выглядеть так:

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;
                }
            });
        });
    }

    ...

}

По каждому запросу ваш токен будет отправлен. Вам придется обрабатывать проверку на стороне сервера. Вы можете легко настроить свой код, чтобы ваш первоначальный запрос мог захватить токен, или вы могли бы передать токен обратно в качестве части вашей полезной нагрузки для проверки подлинности, или если бы вы хотели, чтобы вы даже могли хранить токен в локальном браузере и использовать его путь.

Вы даже можете сделать еще один шаг и реализовать проверку подлинности JWT. Если вы используете node.js, у меня есть небольшой пост в блоге, в котором описывается, как я реализовал JWT в Express. Там плагин на Github называется aurelia-auth, который обрабатывает JWT, и там в блоге о его внедрении в блоге Aurelia.

Ответ 2

Вот пример перехватчика, который читает токен из заголовка ответа, если он существует, и устанавливает его автоматически при каждом запросе, который ему нужен.

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;
  }
}

Вы зарегистрируете его в своем клиенте http/fetch, например:

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());
});