Escape problemen met PHP i.c.m. databases
Controleer altijd of get_magic_quotes_gpc() en get_magic_quotes_runtime() aan staan. Als 1 van deze twee aan staat, worden variabelen binnen PHP die enkele (') of dubbele (") quotes of backslashes (\) bevatten automagisch escaped. Dat wil zeggen dat een string die in PHP binnen komt via GET, POST of een cookie (gpc) die een ', " of \ bevat automagisch een \ voor die character krijgt. Bekijk het volgende voorbeeld:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<input
name="test"
type="text"
value="Test: ', " and \"
/>
<input type="submit" />
</form>
<pre>
<?
if ( get_magic_quotes_gpc () ) {
echo 'Magic quoting with get, post or cookie is enabled', "\n";
}
print_r ( $_GET );
?>
Uitvoer met get_magic_quotes_gpc aan, na submit:
2
3
4
5
Array
(
[test] => Test: \', \" and \\
)
Het is het overwegen waard om zelf de controle te houden op het escapen van variabelen, om te voorkomen dat je bijvoorbeeld in <input ...> velden een ongewenste backslash krijgt.
Mijn voorkeur heeft het dan ook om in de code te checken of er al ge-escaped is, en zo ja: die escape characters weer te verwijderen:
Uiteraard is het ook een optie om je configuratie helemaal naar je hand te zetten, maar je kunt een reden om dat niet globaal te doen en de magic quotes directives kun je niet altijd per script aan of uit zetten, behalve magic_quotes_runtime (zie set_magic_quotes_runtime (). Daarnaast is het het overwegen waard om je scripts zo portable mogelijk te maken (onafhankelijk van configuraties)
2
3
4
5
6
7
8
9
10
11
set_magic_quotes_runtime ( 0 );
if ( get_magic_quotes_gpc () ) {
foreach ( $_POST as $key => $value ) {
$_POST [ $key ] = stripslashes ( $value );
}
foreach ( $_GET as $key => $value )
// etcetera ...
}
?>
Vervolgens kun je met je eigen escape functies de juiste escapes doen:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
define ( 'QUOTE_SINGLE', 39 );
define ( 'QUOTE_DOUBLE', 34 );
define ( 'QUOTE_BACKTICK', 96 );
function mysql_escape ( $string, $quote_char_code = QUOTE_SINGLE ) {
$quote_char = chr ( $quote_char_code );
return
$quote_char .
str_replace (
array ( '\\', $quote_char ),
array ( '\\\\', '\\' . $quote_char ),
$string
)
$quote_char;
}
// ....
$query = "
INSERT INTO
table(fieldname)
VALUES(
" . mysql_escape_string (
'Dit " is \' een string \\ met wat \ bullshit \\\' '
) . "
);
";
?>
Overigens is het ook te overwegen de ANSI-SQL wijze van escapen te hanteren, door een enkele quote te escapen met een extra enkele quote:
2
3
4
5
function ansi_sql_escape ( $string ) {
return str_replace ( "'", "''", $string );
}
?>
Om goed te testen of je escaping wel goed werkt, probeer het volgende in te voeren in je database door middel van een formuliertje:
Wanneer je bij inserten van deze string geen foutmelding krijgt en je krijgt exact dezelfde string terug bij het uitlezen van die string uit je database, werkt je escaping perfect:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$query = '
INSERT INTO
table(fieldname)
VALUES(
' . mysql_escape ( $_GET [ 'string' ] ) . '
);
';
mysql_query ( $query )
or trigger_error ( "Fout: " . mysql_error () . "<br>query: " . $query );
$id = mysql_insert_id ();
$query = '
SELECT
fieldname
FROM
table
WHERE
field_id=' . $id;
$res = mysql_query ( $query )
or trigger_error ( "Fout: " . mysql_error () . "<br>query: " . $query );
$selected_field = mysql_result ( $res, 0, 0 );
echo 'inserted: ', $_GET [ 'string' ], '<br>';
echo 'retrieved: ', $selected_field, '<br>';
echo 'ok?: ', $selected_field == $_GET [ 'string' ], '<br>';
}
?>
<form method="get">
<input type="text" name="string" />
<input type="submit" />
</form>
Inhoudsopgave
- HELP! Mijn POST en GET forms werken niet (meer)
- ... is not a valid MySQL resource index
- Mijn sessie-variabelen worden niet opgeslagen
- Mijn file-upload form werkt niet.
- Ik heb een multiple select of meerdere checkboxes,
- Escape problemen met PHP i.c.m. databases
- multiviews
- Mod_rewrite
- Hoe werkt dat GROUP BY nu eigenlijk?
- Bij een javascript-submit of drukken op enter word
- Spaties van een <input ... value=...> worden niet
- Help! die aggregate functies
- wordt nog toegevoegt
- Ik kan de fout echt niet vinden!