Bug 37727: Prevent CSV Formula injection via DataTables
This change prevents CSV Formula injection on DataTables exports by escaping formula with a single quote prefix as per OWASP recommendations. Test plan: 0. Apply patch 1. Go to http://localhost:8081/cgi-bin/koha/members/memberentry.pl ?op=edit_form&destination=circ&borrowernumber=51 2. Add the following in a "Circulation note" =SUM(1+1) 3. Go to http://localhost:8081/cgi-bin/koha/members/member.pl ?quicksearch=1&circsearch=1&searchmember=koha 4. Click "Export" and choose "Excel" and "CSV" 5. Open those downloaded files in Excel 6. Note that the =SUM(1+1) function is prefixed with a single quote, and is not automatically executed Signed-off-by: Magnus Enger <magnus@libriotech.no> Works as advertised. The problematic "cell" is exported as "'=SUM(1+1)". Signed-off-by: Chris Cormack <chris@bigballofwax.co.nz> Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de> Signed-off-by: wainuiwitikapark <wainuiwitikapark@catalyst.net.nz>
This commit is contained in:
parent
2896429708
commit
dcb5cc1051
|
|
@ -35,6 +35,23 @@ function KohaTable(id_selector, dt_parameters, table_settings, add_filters) {
|
||||||
exportColumns = dt_parameters["exportColumns"];
|
exportColumns = dt_parameters["exportColumns"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const export_format_spreadsheet = {
|
||||||
|
body: function ( data, row, column, node ) {
|
||||||
|
var newnode = $(node);
|
||||||
|
|
||||||
|
if ( newnode.find(".noExport").length > 0 ) {
|
||||||
|
newnode = newnode.clone();
|
||||||
|
newnode.find(".noExport").remove();
|
||||||
|
}
|
||||||
|
let trimmed_str = newnode.text().replace( /\n/g, ' ' ).trim();
|
||||||
|
const unsafeCharacters = /^[=+\-@\t\r]/;
|
||||||
|
if ( unsafeCharacters.test(trimmed_str) ){
|
||||||
|
trimmed_str = "'" + trimmed_str;
|
||||||
|
}
|
||||||
|
return trimmed_str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var export_format = {
|
var export_format = {
|
||||||
body: function ( data, row, column, node ) {
|
body: function ( data, row, column, node ) {
|
||||||
var newnode = $(node);
|
var newnode = $(node);
|
||||||
|
|
@ -78,7 +95,7 @@ function KohaTable(id_selector, dt_parameters, table_settings, add_filters) {
|
||||||
exportOptions: {
|
exportOptions: {
|
||||||
columns: exportColumns,
|
columns: exportColumns,
|
||||||
rows: exportRows,
|
rows: exportRows,
|
||||||
format: export_format
|
format: export_format_spreadsheet
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -100,7 +117,7 @@ function KohaTable(id_selector, dt_parameters, table_settings, add_filters) {
|
||||||
exportOptions: {
|
exportOptions: {
|
||||||
columns: exportColumns,
|
columns: exportColumns,
|
||||||
rows: exportRows,
|
rows: exportRows,
|
||||||
format: export_format
|
format: export_format_spreadsheet
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -672,6 +672,23 @@ function _dt_buttons(params){
|
||||||
exportColumns = settings["exportColumns"];
|
exportColumns = settings["exportColumns"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const export_format_spreadsheet = {
|
||||||
|
body: function ( data, row, column, node ) {
|
||||||
|
var newnode = $(node);
|
||||||
|
|
||||||
|
if ( newnode.find(".noExport").length > 0 ) {
|
||||||
|
newnode = newnode.clone();
|
||||||
|
newnode.find(".noExport").remove();
|
||||||
|
}
|
||||||
|
let trimmed_str = newnode.text().replace( /\n/g, ' ' ).trim();
|
||||||
|
const unsafeCharacters = /^[=+\-@\t\r]/;
|
||||||
|
if ( unsafeCharacters.test(trimmed_str) ){
|
||||||
|
trimmed_str = "'" + trimmed_str;
|
||||||
|
}
|
||||||
|
return trimmed_str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var export_format = {
|
var export_format = {
|
||||||
body: function ( data, row, column, node ) {
|
body: function ( data, row, column, node ) {
|
||||||
var newnode = $(node);
|
var newnode = $(node);
|
||||||
|
|
@ -691,7 +708,7 @@ function _dt_buttons(params){
|
||||||
text: __("Excel"),
|
text: __("Excel"),
|
||||||
exportOptions: {
|
exportOptions: {
|
||||||
columns: exportColumns,
|
columns: exportColumns,
|
||||||
format: export_format
|
format: export_format_spreadsheet
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -699,7 +716,7 @@ function _dt_buttons(params){
|
||||||
text: __("CSV"),
|
text: __("CSV"),
|
||||||
exportOptions: {
|
exportOptions: {
|
||||||
columns: exportColumns,
|
columns: exportColumns,
|
||||||
format: export_format
|
format: export_format_spreadsheet
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue