Prevents CSV Formula Injection
The EscapeFormula
Formatter formats CSV records to reduce CSV Formula Injection in imported Spreadsheet programs.
Usage with CSV objects
The EscapeFormula
class uses the formatter capabilities of the Writer
object to escape formula injection.
public function __construct(string $escape = "'", array $special_chars = [])
public function escapeRecord(array $record): array
public function unescapeRecord(array $record): array
EscapeFormula::unescapeRecord
is available since version 9.11.0
The EscapeFormula::__construct
method takes two (2) arguments:
- the
$escape
parameter which will be used to prepend the record field, which defaults to'
; - the
$special_chars
parameter which is anarray
with additional characters that need to be escaped. By default, the following characters at the start of any record field content will be escaped+
,-
,=
,@
,\t
,\r
; - for more information see OWASP - CSV Injection
use League\Csv\EscapeFormula;
use League\Csv\Writer;
$formatter = new EscapeFormula();
$writer = Writer::createFromPath('php://temp', 'r+');
$writer->addFormatter($formatter->escapeRecord(...));
$writer->insertOne(['2', '2017-07-25', 'Important Client', '=2+5', 240, null]);
$writer->toString();
//outputting a CSV Document with all CSV Formula Injection escaped
//"2,2017-07-25,\"Important Client\",\"\t=2+5\",240,\n"
Conversely, if you obtain a CSV document containing escaped formula field you can use the Esca[eFormula::unescapeRecord
to remove any escaping character.
use League\Csv\EscapeFormula;
use League\Csv\Reader;
$formatter = new EscapeFormula();
$reader = Reader::createFromPath('/path/to/my/file.csv');
$reader->addFormatter($formatter->unescapeRecord(...))
$reader->first();
// returns ['2', '2017-07-25', 'Important Client', '=2+5', '240', '']
// the escaping characters are removed.
Usage with PHP stream resources
You can use the EscapeFormula
to format your records before calling fputcsv
or SplFileObject::fputcsv
.
use League\Csv\EscapeFormula;
$resource = fopen('/path/to/my/file', 'r+');
$formatter = new EscapeFormula("`");
foreach ($iterable_data as $record) {
fputcsv($resource, $formatter->escapeRecord($record));
}
Conversely, if you have a CSV document with escaped formula, you can access the original content using the new
EscapeFormula::unescapeRecord
to remove any escaping character.
use League\Csv\EscapeFormula;
$resource = fopen('/path/to/my/file', 'r');
$formatter = new EscapeFormula("`");
while (($data = fgetcsv($resource)) !== false) {
$record = $formatter->unescapeRecord($data);
}