Prevent csv export injections (#14347)
**Small Security Issue:** CSV exports were vulnerable to formula injection attacks when users entered values starting with =, +, -, or @. (only happens if a logged-in user injects corrupted data) Solution: - Added ZWJ (Zero-Width Joiner) protection that prefixes dangerous values with invisible Unicode character - This is the best way to preserve original data while preventing Excel from executing formulas - Added import cleanup to restore original values when re-importing Changes: - New sanitizeValueForCSVExport() function for security - Updated all CSV export paths to use both security + formatting functions - Added comprehensive tests covering attack vectors and international characters - Also added cursor rules for better code consistency --------- Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
This commit is contained in:
+5
-2
@@ -3,7 +3,8 @@ import { spreadsheetImportFilterAvailableFieldMetadataItems } from '@/object-rec
|
||||
import { getCompositeSubFieldLabelWithFieldLabel } from '@/object-record/spreadsheet-import/utils/spreadsheetImportGetCompositeSubFieldLabelWithFieldLabel';
|
||||
import { SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsCompositeFieldTypeConfigs';
|
||||
import { SETTINGS_NON_COMPOSITE_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs';
|
||||
import { escapeCSVValue } from '@/spreadsheet-import/utils/escapeCSVValue';
|
||||
import { formatValueForCSV } from '@/spreadsheet-import/utils/formatValueForCSV';
|
||||
import { sanitizeValueForCSVExport } from '@/spreadsheet-import/utils/sanitizeValueForCSVExport';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
@@ -122,7 +123,9 @@ export const useDownloadFakeRecords = () => {
|
||||
|
||||
const formatToCsvContent = (rows: string[][]) => {
|
||||
const escapedRows = rows.map((row) => {
|
||||
return row.map((value) => escapeCSVValue(value));
|
||||
return row.map((value) =>
|
||||
formatValueForCSV(sanitizeValueForCSVExport(value)),
|
||||
);
|
||||
});
|
||||
|
||||
const csvContent = [...escapedRows.map((row) => row.join(','))].join('\n');
|
||||
|
||||
Reference in New Issue
Block a user