The problem in depth
The Excel exporter applies the escapeFormulas guard (enabled by default) only when the cell value is a string held in the local cellValue variable. In serializeRowUnsafe (packages/x-data-grid-premium/src/hooks/features/export/serializer/excelSerializer.ts), the singleSelect branch writes the formatted option label straight to serializedRow[castColumn.field] and never assigns cellValue, so the escape guard at the end of the loop is skipped for singleSelect cells.
As a result, a singleSelect option label that begins with =, +, -, @, a tab or a carriage return is written to the .xlsx without the leading apostrophe that neutralizes it (OWASP CSV/Excel formula injection). The boolean, number and default branches set cellValue and are escaped correctly, and the CSV exporter escapes the same value through sanitizeCellValue, so the Excel singleSelect path is the inconsistency.
Steps to reproduce
- Render a
DataGridPremium with a singleSelect column whose option label starts with a formula character:
columns={[
{
field: 'option',
type: 'singleSelect',
valueOptions: [{ value: 'a', label: '=HYPERLINK("http://evil","x")' }],
},
]}
rows={[{ id: 1, option: 'a' }]}
- Export with the default options:
apiRef.current.exportDataAsExcel() (escapeFormulas defaults to true).
- Inspect the exported cell for the
singleSelect column: it equals the raw =HYPERLINK("http://evil","x") with no leading apostrophe.
- A string-type column containing the same value is correctly prefixed with an apostrophe, and the CSV export of the singleSelect value is also escaped.
Current behavior
singleSelect cells bypass escapeFormulas, so a label beginning with a formula trigger character is exported unescaped.
Expected behavior
singleSelect cells are escaped like every other string cell when escapeFormulas is enabled (the default), matching the CSV exporter and the other column types.
Context
Exporting a Data Grid Premium that contains singleSelect columns whose labels can derive from user-controlled data. The fix routes the singleSelect label through the same cellValue escape path used by the other column types.
Your environment
Reproduced against the package source on the current master.
@mui/x-data-grid-premium: current master
Search keywords: excel export, singleSelect, escapeFormulas, formula injection, CSV injection, data grid premium, sanitize
The problem in depth
The Excel exporter applies the
escapeFormulasguard (enabled by default) only when the cell value is a string held in the localcellValuevariable. InserializeRowUnsafe(packages/x-data-grid-premium/src/hooks/features/export/serializer/excelSerializer.ts), thesingleSelectbranch writes the formatted option label straight toserializedRow[castColumn.field]and never assignscellValue, so the escape guard at the end of the loop is skipped forsingleSelectcells.As a result, a
singleSelectoption label that begins with=,+,-,@, a tab or a carriage return is written to the.xlsxwithout the leading apostrophe that neutralizes it (OWASP CSV/Excel formula injection). Theboolean,numberand default branches setcellValueand are escaped correctly, and the CSV exporter escapes the same value throughsanitizeCellValue, so the ExcelsingleSelectpath is the inconsistency.Steps to reproduce
DataGridPremiumwith asingleSelectcolumn whose option label starts with a formula character:apiRef.current.exportDataAsExcel()(escapeFormulasdefaults totrue).singleSelectcolumn: it equals the raw=HYPERLINK("http://evil","x")with no leading apostrophe.Current behavior
singleSelectcells bypassescapeFormulas, so a label beginning with a formula trigger character is exported unescaped.Expected behavior
singleSelectcells are escaped like every other string cell whenescapeFormulasis enabled (the default), matching the CSV exporter and the other column types.Context
Exporting a Data Grid Premium that contains singleSelect columns whose labels can derive from user-controlled data. The fix routes the singleSelect label through the same
cellValueescape path used by the other column types.Your environment
Reproduced against the package source on the current
master.Search keywords: excel export, singleSelect, escapeFormulas, formula injection, CSV injection, data grid premium, sanitize