Open
Description
Symfony version(s) affected
5.4.45
Description
When csv_escape_formulas
is set to true
then CsvEncoder
will escape strings that start with +, -, =, and others to prevent Excel from interpreting them as formulas and potentially causing a code execution attack. See https://georgemauer.net/2017/10/07/csv-injection.html for more details.
However CsvEncoder
currently casts everything to a string before checking the starting characters meaning that negative number get escaped because the string starts with -. This means that when opened in a spreadsheet application that column is no longer treated as a number.
I do not believe negative numbers to be an attack vector so they do not need to be escaped.
How to reproduce
<?php
use PHPUnit\Framework\TestCase;
use Symfony\Component\Serializer\Encoder\CsvEncoder;
class CsvEncoderTest extends TestCase
{
public function testNegativeInteger(): void
{
$encoder = new CsvEncoder();
$data = [
['a' => '-1', 'b' => -1],
['a' => '0', 'b' => 0],
['a' => '+1', 'b' => 1],
];
$expectedResult = <<<CSV
a,b
'-1,-1
0,0
'+1,1
CSV;
$result = $encoder->encode($data, 'csv', [
CsvEncoder::ESCAPE_FORMULAS_KEY => true,
]);
$this->assertSame($expectedResult, $result);
}
public function testNegativeFloat(): void
{
$encoder = new CsvEncoder();
$data = [
['a' => '-1.1', 'b' => -1.1],
['a' => '0.1', 'b' => 0.1],
['a' => '+1.1', 'b' => 1.1],
];
$expectedResult = <<<CSV
a,b
'-1.1,-1.1
0.1,0.1
'+1.1,1.1
CSV;
$result = $encoder->encode($data, 'csv', [
CsvEncoder::ESCAPE_FORMULAS_KEY => true,
]);
$this->assertSame($expectedResult, $result);
}
}
Possible Solution
Exclude values of type integer and of type float from the escaping.
Additional Context
No response