php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47802 PDO_MYSQL doesn't use the charset parameter
Submitted: 2009-03-27 08:53 UTC Modified: 2012-03-06 01:44 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: disbursement at dublin dot com Assigned: mysql
Status: Closed Package: MySQL related
PHP Version: 5.2.9 OS: all
Private report: No CVE-ID:
 [2009-03-27 08:53 UTC] disbursement at dublin dot com
Description:
------------
	static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
{
...
	struct pdo_data_src_parser vars[] = {
		{ "charset",  NULL,	0 },
		{ "dbname",   "",	0 },
		{ "host",   "localhost",	0 },
		{ "port",   "3306",	0 },
		{ "unix_socket",  PDO_MYSQL_UNIX_ADDR,	0 },
	};

The option "charset"/vars[0] is never used, but would be a nice feature.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-01-02 02:36 UTC] jani@php.net
-Package: Feature/Change Request +Package: MySQL related
 [2011-01-07 15:39 UTC] kalle@php.net
Automatic comment from SVN on behalf of kalle
Revision: http://svn.php.net/viewvc/?view=revision&revision=307224
Log: Implemented FR #47802, support for character sets in DSN strings for PDO_MYSQL
 [2011-01-07 15:40 UTC] kalle@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: kalle
 [2011-01-07 15:40 UTC] kalle@php.net
Implemented in trunk for now
 [2011-01-07 18:18 UTC] kalle@php.net
Automatic comment from SVN on behalf of kalle
Revision: http://svn.php.net/viewvc/?view=revision&revision=307228
Log: Added test case for #47802 and fixed macro name after the move to mysql_options()
 [2011-01-17 10:54 UTC] kalle@php.net
Automatic comment from SVN on behalf of kalle
Revision: http://svn.php.net/viewvc/?view=revision&revision=307529
Log: MFT: Implemented FR #47802 (Support for setting character sets in DSN strings)
 [2011-01-17 11:46 UTC] kalle@php.net
-Status: Assigned +Status: Closed
 [2011-01-17 11:46 UTC] kalle@php.net
Will appear in PHP 5.3.6 :)
 [2011-04-18 22:34 UTC] ircmaxell at gmail dot com
Re-opening this as it has security implications for 5.2.x.  It should be 
backported and re-released as a security fix for 5.2.x.

As it stands now, PDO::quote() does not protect against security vulnerabilities 
without the ability to set the character set in the C api.  5.3.6 closes this 
hole when supplied with the optional charset parameter (by appropriately setting 
the character set).  However this will need to be expressed in the documentation 
(I will file another issue on this topic).

Proof Of Concept Code:

$dsn = 'mysql:dbname=INFORMATION_SCHEMA;host=127.0.0.1;charset=GBK';
$pdo = new PDO($dsn, $user, $pass);
$pdo->exec('SET NAMES GBK');
$string = chr(0xbf) . chr(0x27) . ' OR 1 = 1; /*';
$sql = "SELECT TABLE_NAME 
            FROM INFORMATION_SCHEMA.TABLES 
            WHERE TABLE_NAME LIKE ".$pdo->quote($string).";";
$stmt = $pdo->query($sql);
var_dump($stmt->rowCount());

Expected: int(0)
Actual: the number of tables on the server
 [2011-04-18 22:38 UTC] colder@php.net
-Status: Closed +Status: Re-Opened
 [2011-04-18 22:38 UTC] colder@php.net
Re-opening because of 5_2 backport request by some user.
 [2011-04-19 01:07 UTC] johannes@php.net
-Status: Re-Opened +Status: To be documented -Assigned To: kalle +Assigned To:
 [2011-04-19 01:07 UTC] johannes@php.net
If a developer shots himself it is noting we can prevent. Tis does not justify a security release of PHP as the only one who can exploit this is the one writing code ...

This should however be made clear in the documentation: Executing SET NAMES doesn't tell anything to the client library (libmysql / mysqlnd used by PHP) so they can't do proper encoding. Therefore only Latin 1, Utf-8 and other encodings using lower 7 bits in an ASCII compatible way can be used safely. For other encodings the mentioned option, introduced later in 5.3.6 should be used.
 [2011-04-19 01:58 UTC] ircmaxell at gmail dot com
I won't argue the decision, but I'd like to clarify one point.  Right now, in 
5.2.x (and <=5.3.5) it's impossible to write a secure query using PDO::quote.  So 
if you use another character set, it would automatically make all code vulnerable 
to SQL Injection (with no built-in method to fix it).  So that leaves existing 
the code 3 options: Switch to MySQLi, Implement their own quoting mechanism, or 
switch to prepared statements (the best solution).  But as it stands, the API 
does not deliver its promise. 

Just an observation...
 [2011-04-19 11:38 UTC] johannes@php.net
You can write secure code - if you are using a supported encoding (iso-8859-1/latin1, utf-8, ...)
 [2012-03-06 01:44 UTC] johannes@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: mysql
 [2012-03-06 01:44 UTC] johannes@php.net
Thank you for your bug report. This issue has already been fixed
in the latest released version of PHP, which you can download at 
http://www.php.net/downloads.php


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sat Apr 19 06:02:27 2014 UTC