CVE-2020-26256 (TypeScript, published 2020-12-08T22:15Z)
Description: value: Fast-csv is an npm package for parsing and formatting CSVs or any other delimited value file in node. In fast-cvs before version 4.3.6 there is a possible ReDoS vulnerability (Regular Expression Denial of Service) when using ignoreEmpty option when parsing. This has been patched in `v4.3.6` You will only be affected by this if you use the `ignoreEmpty` parsing option. If you do use this option it is recommended that you upgrade to the latest version `v4.3.6` This vulnerability was found using a CodeQL query which identified `EMPTY_ROW_REGEXP` regular expression as vulnerable.
Severity: LOW (CVSS v3 base score: 6.5)
Weakness: CWE-400 \u2014 Uncontrolled Resource Consumption
The product does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources.
Repository: https://github.com/C2FO/fast-csv
Files changed:
packages/parse/__tests__/issues/issue540.spec.ts
packages/parse/src/parser/Parser.ts
packages/parse/src/parser/RowParser.ts
Commit message: fix: Simplify empty row check by removing complex regex


Vulnerable code:
const EMPTY_ROW_REGEXP = /^\s*(?:''|"")?\s*(?:,\s*(?:''|"")?\s*)*$/;

        if (this.parserOptions.ignoreEmpty && EMPTY_ROW_REGEXP.test(row.join(''))) {

Fixed code:
import { EOL } from 'os';
import { parseString, RowMap, RowArray } from '../../src';

describe('Issue #540 - https://github.com/C2FO/fast-csv/issues/540', () => {
    const CSV_CONTENT = [
        ' , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , -',
    ].join(EOL);

    const expectedRows = [
        [
            ' , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,' +
                ' , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,' +
                ' , , , , , , , , , , , , , , -',
        ],
    ];

    it('allow transforming to any object shape', () => {
        return new Promise((res, rej) => {
            const invalid: RowArray[] = [];
            const rows: RowMap[] = [];
            parseString(CSV_CONTENT, { ignoreEmpty: true, delimiter: '\t' })
                .on('data-invalid', (row: RowArray) => invalid.push(row))
                .on('data', (r) => rows.push(r))
                .on('error', rej)
                .on('end', (count: number) => {
                    expect(rows).toEqual(expectedRows);
                    expect(invalid).toHaveLength(0);
                    expect(count).toBe(expectedRows.length + invalid.length);
                    res();
                });
        });
    });
});
        if (this.parserOptions.ignoreEmpty && RowParser.isEmptyRow(row)) {
const EMPTY_STRING = '';

    static isEmptyRow(row: RowArray): boolean {
        return row.join(EMPTY_STRING).replace(/\s+/g, EMPTY_STRING) === EMPTY_STRING;
    }