Bug #43225 [ReO]: fputcsv incorrectly handles cells ending in \ followed by "
| From: | cmb@php.net | Date: | Mon, 11 Sep 2017 23:53:10 +0000 |
| Subject: | Bug #43225 [ReO]: fputcsv incorrectly handles cells ending in \ followed by " | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-211078@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=43225&edit=1
ID: 43225
Updated by: cmb@php.net
Reported by: ed at bronto dot com
Summary: fputcsv incorrectly handles cells ending in \
followed by "
Status: Re-Opened
Type: Bug
Package: Filesystem function related
Operating System: Centos
PHP Version: 5.2.4
Block user comment: N
Private report: N
New Comment:
> Still not fixed after almost 10 years?
It is not as simple. We first have to understand why fputcsv() and
friends support an escape character, which is an unrecognized
concept for RFC 4180; however, this RFC is informal and never made
it to a standard, so an escape character may make perfect sense.
But how exactly is it supposed to work?
Anyhow, "disabling" the escape character as plentysu already said,
is suffienct to get the desired result, see
<https://3v4l.org/eW2Mt>. This should be possible in a
more
intuitive way, though, see request #51496.
Previous Comments:
------------------------------------------------------------------------
[2017-04-25 09:38:24] enumag at gmail dot com
Still not fixed after almost 10 years? The thing is this can result in formula injection.
http://blog.securelayer7.net/how-to-perform-csv-excel-macro-injection/
For example I have this string (it should go into one cell):
=,test'\","",=cmd|' /C calc'!A0"
According to the article I sanitize it by escaping the = at the beginning with an apostrphe.
'=,test'\","",=cmd|' /C calc'!A0"
Because of this bug however this string can still cause an injection because this bug causes the
string to split into multiple cells and the second = is not escped.
------------------------------------------------------------------------
[2015-09-16 04:33:26] plentysu at kkbox dot com
One thinking to
disable escape method: fputcsv($handle, $array, ',',
'"', "\0")
------------------------------------------------------------------------
[2015-07-25 22:14:45] marc at ermshaus dot org
The issues with PHPâs CSV functions also seem to be exploitable.
<?php
$handle = fopen('php://memory', 'w+b');
fputcsv($handle, [
'foo bar\\', # 1
'baz quz', # 2
'x', # 3
'y', # 4
'z', # 5
'foo\\\\",bar' # 6
]);
rewind($handle);
var_dump(fgetcsv($handle));
// array(6) {
// [0]=> string(18) "foo bar\",baz quz"" # 1
// [1]=> string(1) "x" # 2 (was # 3)
// [2]=> string(1) "y" # 3 (was # 4)
// [3]=> string(1) "z" # 4 (was # 5)
// [4]=> string(5) "foo\\" # 5
// [5]=> string(4) "bar"" # 6
// }
3v4l.org: http://3v4l.org/LTnC1
------------------------------------------------------------------------
[2014-09-17 12:46:13] lbarnaud@php.net
To summarize the related bugs: fputcsv() seems to be using inconsistent and broken escaping of the
enclosing char (") :
- " followed by \ are not escaped
- " not followed by \ are escaped by doubling them (e.g.
" becomes ""); leading to inconsistent escaping method
- \ themselves are not escaped, leading to generation of invalid CSV if a field is
terminated by \: "foo bar\",baz
- With the input \\", the " is still considered to be escaped
Due to this combinaison of bugs, it is impossible to parse the CSV generated by the following call:
fputcsv(STDOUT, ['foo\"bar', 'foo""bar', 'foo
bar\\']);
Output is:
"foo\"bar","foo""""bar","foo bar\"
Trying to parse this with a parser using the doubled-char escaping method will break on the first
field.
Trying to parse this with a parser using the backslash escaping method will break on the 2nd and 3rd
fields.
Trying to parse this with a parser allowing both methods will break on the 3rd field. Without the
3rd field, parsing this CSV document would result in loss of information (some \ or
" from the original input would be lost).
------------------------------------------------------------------------
[2014-08-21 23:55:57] maris dot radu+phpnet at gmail dot com
Just not to confuse people, aharvey@php.net said it's fixed in "5.3.22 and 5.4.12",
but in fact I tested in 5.4.31 and it's not fixed.
Looking at the patch commit it seems it's tagged with php-5.6.0beta4, so I guess will only be
available in 5.6.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=43225
--
Edit this bug report at https://bugs.php.net/bug.php?id=43225&edit=1