[ADD] client-side CSRF support
* add CSRF token as core.csrf_token * add CSRF tokens to client-generated and/or JS-submitted forms * remove broken "compatibility" mode of web.ajax.post /cc @dmo-odoo I've no idea how that was supposed to work, from looking things up all modern browsers seem to support FormData, and old IEs which don't don't support fallbacks either and would require submitting an actual form as fallback so...
This commit is contained in:
committed by
Olivier Dony
parent
7753ed7ce4
commit
cea29e0c01
@@ -2,6 +2,7 @@
|
||||
<t t-name="ImportView">
|
||||
<t t-set="_id" t-value="_.uniqueId('export')"/>
|
||||
<form action="" method="post" enctype="multipart/form-data" class="oe_import">
|
||||
<input type="hidden" name="csrf_token" t-att-value="csrf_token"/>
|
||||
<input type="hidden" name="session_id"
|
||||
t-att-value="widget.session.session_id"/>
|
||||
<input type="hidden" name="import_id"/>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
odoo.define('web.ajax', function (require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var time = require('web.time');
|
||||
var utils = require('web.utils');
|
||||
|
||||
@@ -238,6 +239,11 @@ function get_file(options) {
|
||||
method: 'POST'
|
||||
}).appendTo(document.body);
|
||||
}
|
||||
if (core.csrf_token) {
|
||||
$('<input type="hidden" name="csrf_token">')
|
||||
.val(core.csrf_token)
|
||||
.appendTo($form_data);
|
||||
}
|
||||
|
||||
var hparams = _.extend({}, options.data || {}, {token: token});
|
||||
_.each(hparams, function (value, key) {
|
||||
@@ -292,19 +298,16 @@ function post (controller_url, data) {
|
||||
};
|
||||
|
||||
var Def = $.Deferred();
|
||||
var compatibility = !(typeof(FormData));
|
||||
var postData = compatibility ? new FormDataCompatibility() : new FormData();
|
||||
var postData = new FormData();
|
||||
|
||||
$.each(data, function(i,val) {
|
||||
postData.append(i, val);
|
||||
});
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
if(compatibility) {
|
||||
postData.setContentTypeHeader(xhr);
|
||||
postData = postData.buildBody();
|
||||
if (core.csrf_token) {
|
||||
postData.append('csrf_token', core.csrf_token);
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
if(xhr.upload) xhr.upload.addEventListener('progress', progressHandler(Def), false);
|
||||
|
||||
var ajaxDef = $.ajax(controller_url, {
|
||||
|
||||
@@ -988,7 +988,8 @@
|
||||
<t t-name="HiddenInputFile">
|
||||
<div t-attf-class="oe_hidden_input_file #{fileupload_class or ''}" t-att-style="fileupload_style">
|
||||
<form class="o_form_binary_form" t-att-target="fileupload_id"
|
||||
method="post" enctype="multipart/form-data" t-att-action="fileupload_action || '/web/binary/upload'">
|
||||
method="post" enctype="multipart/form-data" t-att-action="fileupload_action || '/web/binary/upload'">
|
||||
<input type="hidden" name="csrf_token" t-att-value="csrf_token"/>
|
||||
<input type="hidden" name="session_id" value="" t-if="widget.session.override_session"/>
|
||||
<input type="hidden" name="callback" t-att-value="fileupload_id"/>
|
||||
<t t-raw="0"/>
|
||||
|
||||
@@ -301,6 +301,13 @@
|
||||
<t t-call="web.layout">
|
||||
<t t-set="head">
|
||||
<t t-call-assets="web.assets_common"/>
|
||||
<script type="text/javascript">
|
||||
odoo.define('web.csrf', function (require) {
|
||||
var token = "<t t-esc="request.csrf_token(None)"/>";
|
||||
require('web.core').csrf_token = token;
|
||||
require('qweb').default_dict.csrf_token = token;
|
||||
});
|
||||
</script>
|
||||
<t t-call-assets="web.assets_backend"/>
|
||||
<!--[if lte IE 9]> <link rel="stylesheet" href="/web/static/src/css/ie.css"/> <![endif]-->
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -88,8 +88,7 @@
|
||||
enctype="multipart/form-data"
|
||||
target="fileframe"
|
||||
class="form-inline">
|
||||
<!-- why is this template rendered client side? -->
|
||||
<!-- input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/-->
|
||||
<input type="hidden" name="csrf_token" t-att-value="csrf_token"/>
|
||||
<div class="well">
|
||||
<div class="form-group pull-left">
|
||||
<input type="file" name="upload" t-att-accept="widget.accept" multiple="multiple" style="position: absolute; opacity: 0; width: 1px; height: 1px;"/>
|
||||
|
||||
@@ -142,16 +142,23 @@ var error = function(data, url) {
|
||||
$error.modal('show');
|
||||
};
|
||||
|
||||
function _add_input(form, name, value) {
|
||||
var param = document.createElement('input');
|
||||
param.setAttribute('type', 'hidden');
|
||||
param.setAttribute('name', name);
|
||||
param.setAttribute('value', value);
|
||||
form.appendChild(param);
|
||||
}
|
||||
var form = function (url, method, params) {
|
||||
var form = document.createElement('form');
|
||||
form.setAttribute('action', url);
|
||||
form.setAttribute('method', method);
|
||||
|
||||
if (core.csrf_token) {
|
||||
_add_input(form, 'csrf_token', core.csrf_token);
|
||||
}
|
||||
_.each(params, function (v, k) {
|
||||
var param = document.createElement('input');
|
||||
param.setAttribute('type', 'hidden');
|
||||
param.setAttribute('name', k);
|
||||
param.setAttribute('value', v);
|
||||
form.appendChild(param);
|
||||
_add_input(form, k, v);
|
||||
});
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
|
||||
@@ -130,6 +130,13 @@
|
||||
<t t-call-assets="website.assets_frontend" t-js="false"/>
|
||||
<t t-call-assets="web.assets_common" t-css="false"/>
|
||||
<t t-call-assets="website.assets_frontend" t-css="false"/>
|
||||
<script type="text/javascript">
|
||||
odoo.define('web.csrf', function (require) {
|
||||
var token = "<t t-esc="request.csrf_token(None)"/>";
|
||||
require('web.core').csrf_token = token;
|
||||
require('qweb').default_dict.csrf_token = token;
|
||||
});
|
||||
</script>
|
||||
|
||||
<t t-raw="head or ''" name='layout_head'/>
|
||||
</head>
|
||||
|
||||
Reference in New Issue
Block a user