The check_query documentation says 'Prepare user input for use in a database query, preventing SQL injection attacks.' But the code itself is a simple addslashes. This is simply not correct -- for mysql, yes, but the world is not just mysql. There are _escape_string functions for that: mysql_escape_string, pg_escape_string, sqlite_escape_string... Read the manual for pg_escape_string: "Use of this function is recommended instead of addslashes()." Or read sqlite_escape_string: "addslashes() should NOT be used to quote your strings for SQLite queries; it will lead to strange results when retrieving your data." Ooooops.
So I propose moving check_query() declaration from bootstrap.inc to database.*.inc. I've already written a letter to the devel list about this, but drumm said "code is better than talk" so here is a patch.
At this moment, this does absolutely nothing, only opens the possibility to use the aforementioned escape_string functions.
But database.sqlite.inc simply will not work without this change.
Comment | File | Size | Author |
---|---|---|---|
#12 | mysql_escape_patch_0.txt | 573 bytes | chx |
#11 | mysql_escape_patch.txt | 572 bytes | chx |
#9 | db_escape_string_0.txt | 20.88 KB | chx |
#8 | db_escape_string.txt | 20.87 KB | chx |
#6 | check_output_patch_0.txt | 1.6 KB | chx |
Comments
Comment #1
drummLooks straightfoward enough.
Is there any reason to not put in pg_escape_string() now?
Comment #2
chx CreditAttribution: chx commentedActually, yes. Read on the mentioned manual page: "Note: This function requires PostgreSQL 7.2 or later." I have no idea how the check it. There is a pg_version() but I will leave this postgres business to someone who has a working postgres install to code and check this thing.
Comment #3
Chris Johnson CreditAttribution: Chris Johnson commentedPostgreSQL 7.2 was released February 4, 2002. Major production releases 73. and 7.4, along with many point releases, have been issued since then. Current production is 7.4.6 and 8.0 is in the 4th revision of beta.
It seems pretty safe to assume that any Drupal installation using PostgreSQL would have version 7.2 or later. Document if a user encounters errors with PostgreSQL that they need to check the version is 7.2 or later.
Comment #4
Dries CreditAttribution: Dries commented+1
I suggest creating a db_escape_string() function, and removing check_query() all together.
Comment #5
Gábor Hojtsy+1 on Dries
Comment #6
chx CreditAttribution: chx commenteddb_escape_string sounds find to me, it's really a better name, thanks Dries. But removing check_query? I'd suggest deprecating it and removing it later. I am afraid It would break a lot of custom modules.
Here is a slightly modified patch with pg_escape_string included and documented.
Comment #7
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedWe were never afraid of breakign things for the good of the project. Please don't change this policy.
Comment #8
chx CreditAttribution: chx commentedLet's do it.
Comment #9
chx CreditAttribution: chx commentedSomething funny happened to the PostgreSQL db_escape_string comment and I have missed it, sorry. Reposting the patch.
Comment #10
Dries CreditAttribution: Dries commentedI committed the patch. Thanks chx. Keep it coming.
I've also updated the upgrade notes at http://drupal.org/node/12347.
I'll update some contributed modules unless someone objects.
Comment #11
chx CreditAttribution: chx commentedKeep it coming? Well, let's see the MySQL case... It's far from being trivial, and I expect some controversy over it.
Comment #12
chx CreditAttribution: chx commentedOK, here is mysql version a bit corrected, this should get into 4.6 -- addslashes is not a correct way any more.
Comment #13
Dries CreditAttribution: Dries commentedCan we read up on that somewhere?
Comment #14
Gábor HojtsyDries, sure: http://php.net/mysql_escape_string and http://php.net/mysql_real_escape_string. The latter also uses the connections charset settings to properly escape, so it is the best (but is not available in old PHP versions). The addslashes page user notes also have more information.
Comment #15
Dries CreditAttribution: Dries commentedaddslashes()
has been working for ages (and is simpler code-wise). I guess themysql_
functions are slightly more secure or not even that? That aside, I'm not really a big fan ofversion_compare()
s. Also note that the patch violates Drupal's coding standards (again) but that's easy enough to fix.Comment #16
chx CreditAttribution: chx commentedI can only repeat what Goba said: . mysql_real_escape_string uses the connections charset settings to properly escape, so it is the best (but is not available in old PHP versions).
Comment #17
Steven CreditAttribution: Steven commentedActually, Drupal does nothing to ensure the database character set is set to UTF-8 (can it?). Thus, escaping with mysql_real_escape_string() is not advised.
Comment #18
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedAccordign to Steven's last comment we should not use the mysql specific functions.
Comment #19
Cvbge CreditAttribution: Cvbge commentedFirst, we require PHP >= 4.3.3 so mysql_real_escape_string() is allways available, so the version check can be skipped.
Second, I don't understand Steven's remark about UTF. There is no mention of UTF in the function's documentation. It should work for any encoding.
Comment #20
Dries CreditAttribution: Dries commentedComment #21
(not verified) CreditAttribution: commented