[xsrf] issue tokens via chrome vars and inject manually

This commit is contained in:
spalger 2015-11-09 22:29:44 -06:00
parent 5cbb952954
commit 8c1a709a07
5 changed files with 41 additions and 19 deletions

View file

@ -4,27 +4,17 @@ export default function (kbnServer, server, config) {
const token = config.get('server.xsrf.token');
const disabled = config.get('server.xsrf.disableProtection');
const stateOpts = {
isSecure: config.get('server.ssl.enabled'),
isHttpOnly: false,
path: '/',
};
server.decorate('reply', 'issueXsrfToken', function () {
return token;
});
server.ext('onPostAuth', function (req, reply) {
if (disabled) return reply.continue();
if (disabled || req.method === 'get') return reply.continue();
if (req.method === 'get' && !req.state['XSRF-TOKEN'] && !req.headers['x-xsrf-token']) {
reply.state('XSRF-TOKEN', token, stateOpts);
}
const attempt = req.headers['kbn-xsrf-token'];
if (!attempt) return reply(forbidden('Missing XSRF token'));
if (attempt !== token) return reply(forbidden('Invalid XSRF token'));
if (req.method === 'get' || req.headers['x-xsrf-token'] === token) {
return reply.continue();
}
if (!req.headers['x-xsrf-token']) {
return reply(forbidden('Missing XSRF token'));
}
return reply(forbidden('Invalid XSRF token'));
return reply.continue();
});
}

View file

@ -66,13 +66,14 @@ module.exports = async (kbnServer, server, config) => {
}
server.decorate('reply', 'renderApp', function (app) {
let payload = {
const payload = {
app: app,
nav: uiExports.apps,
version: kbnServer.version,
buildNum: config.get('pkg.buildNum'),
buildSha: config.get('pkg.buildSha'),
vars: defaults(app.getInjectedVars(), defaultInjectedVars),
xsrfToken: this.issueXsrfToken(),
};
return this.view(app.templateName, {

View file

@ -24,6 +24,7 @@ module.exports = function (chrome, internals) {
a.href = '/elasticsearch';
return a.href;
}()))
.config(chrome.$setupCsrfRequestInterceptor)
.directive('kbnChrome', function ($rootScope) {
return {
template: function ($el) {

View file

@ -0,0 +1,28 @@
import $ from 'jquery';
import { set } from 'lodash';
export default function (chrome, internals) {
chrome.getXsrfToken = function () {
return internals.xsrfToken;
};
$.ajaxPrefilter(function ({ kbnCsrfToken = internals.xsrfToken }, originalOptions, jqXHR) {
if (kbnCsrfToken) {
jqXHR.setRequestHeader('kbn-xsrf-token', kbnCsrfToken);
}
});
chrome.$setupCsrfRequestInterceptor = function ($httpProvider) {
$httpProvider.interceptors.push(function () {
return {
request: function (opts) {
const { kbnCsrfToken = internals.xsrfToken } = opts;
if (kbnCsrfToken) {
return set(opts, ['headers', 'kbn-xsrf-token'], kbnCsrfToken);
}
}
};
});
};
}

View file

@ -18,6 +18,7 @@ var internals = _.defaults(
rootController: null,
rootTemplate: null,
showAppsLink: null,
xsrfToken: null,
brand: null,
nav: [],
applicationClasses: []
@ -30,6 +31,7 @@ $('<link>').attr({
}).appendTo('head');
require('./api/apps')(chrome, internals);
require('./api/xsrf')(chrome, internals);
require('./api/nav')(chrome, internals);
require('./api/angular')(chrome, internals);
require('./api/controls')(chrome, internals);