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"];
|
||||
}
|
||||
|
||||
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 = {
|
||||
body: function ( data, row, column, node ) {
|
||||
var newnode = $(node);
|
||||
|
|
@ -78,7 +95,7 @@ function KohaTable(id_selector, dt_parameters, table_settings, add_filters) {
|
|||
exportOptions: {
|
||||
columns: exportColumns,
|
||||
rows: exportRows,
|
||||
format: export_format
|
||||
format: export_format_spreadsheet
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -100,7 +117,7 @@ function KohaTable(id_selector, dt_parameters, table_settings, add_filters) {
|
|||
exportOptions: {
|
||||
columns: exportColumns,
|
||||
rows: exportRows,
|
||||
format: export_format
|
||||
format: export_format_spreadsheet
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -672,6 +672,23 @@ function _dt_buttons(params){
|
|||
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 = {
|
||||
body: function ( data, row, column, node ) {
|
||||
var newnode = $(node);
|
||||
|
|
@ -691,7 +708,7 @@ function _dt_buttons(params){
|
|||
text: __("Excel"),
|
||||
exportOptions: {
|
||||
columns: exportColumns,
|
||||
format: export_format
|
||||
format: export_format_spreadsheet
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -699,7 +716,7 @@ function _dt_buttons(params){
|
|||
text: __("CSV"),
|
||||
exportOptions: {
|
||||
columns: exportColumns,
|
||||
format: export_format
|
||||
format: export_format_spreadsheet
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue