In Drupal 6, queries are issued with db_query()
. Using %-modifiers, query arguments are substituted into the query after being filtered. Strings %s (and only strings) are ultimately run through mysqli_real_escape_string()
(using db_escape_string()
).
Looking at the php docs for mysqli_real_escape_string()
, I see the following security warning:
The character set must be set either at the server level, or with the API function
mysqli_set_charset()
for it to affectmysqli_real_escape_string()
.
The answer to another question about mysql_real_escape_string / SQL Injection explains that:
Another way to get yourself into hot water using mysql_real_escape_string is when you set the database connection encoding using the wrong method. You should do this:
mysql_set_charset('utf8', $link);
You can also do this though:
mysql_query("SET NAMES 'utf8'", $link);
The problem is that the latter bypasses the mysql_ API, which still thinks you're talking to the database using latin1 (or something else). [...] This can be used for injection attacks in certain multibyte string situations.
Drupal does not call mysqli_set_charset(), and instead issues the query 'SET NAMES utf8'. This can be seen in db_connect().
In order to properly protect Drupal 6 against SQL Injection, does the charset need to be set at the server level?