diff --git a/packages/x-data-grid/src/hooks/features/export/serializers/csvSerializer.ts b/packages/x-data-grid/src/hooks/features/export/serializers/csvSerializer.ts index 7df03e0600f5..0589aba5d346 100644 --- a/packages/x-data-grid/src/hooks/features/export/serializers/csvSerializer.ts +++ b/packages/x-data-grid/src/hooks/features/export/serializers/csvSerializer.ts @@ -10,16 +10,16 @@ function sanitizeCellValue(value: unknown, csvOptions: CSVOptions): string { if (csvOptions.shouldAppendQuotes || csvOptions.escapeFormulas) { const escapedValue = valueStr.replace(/"/g, '""'); - // Make sure value containing delimiter or line break won't be split into multiple cells - if ([csvOptions.delimiter, '\n', '\r', '"'].some((delimiter) => valueStr.includes(delimiter))) { - return `"${escapedValue}"`; - } if (csvOptions.escapeFormulas) { // See https://owasp.org/www-community/attacks/CSV_Injection if (['=', '+', '-', '@', '\t', '\r'].includes(escapedValue[0])) { - return `'${escapedValue}`; + return `"'${escapedValue}"`; } } + // Make sure value containing delimiter or line break won't be split into multiple cells + if ([csvOptions.delimiter, '\n', '\r', '"'].some((delimiter) => valueStr.includes(delimiter))) { + return `"${escapedValue}"`; + } return escapedValue; } diff --git a/packages/x-data-grid/src/tests/export.DataGrid.test.tsx b/packages/x-data-grid/src/tests/export.DataGrid.test.tsx index 0e6b3745103b..76852db95927 100644 --- a/packages/x-data-grid/src/tests/export.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/export.DataGrid.test.tsx @@ -106,12 +106,12 @@ describe(' - Export', () => { expect(csv).to.equal( [ 'name', - "'=1+1", - "'+1+1", - "'-1+1", - "'@1+1", - "'\t1+1", - '"\r1+1"', + '"\'=1+1"', + '"\'+1+1"', + '"\'-1+1"', + '"\'@1+1"', + '"\'\t1+1"', + '"\'\r1+1"', '",=1+1"', '"value,=1+1"', ].join('\r\n'),