Ik bouw mijn site nu op door alle pagina's uit een database te laden.
De pagina's worden nu aangeroepen met bijv: www.mysite.com?id=2.
In dit geval zijn het alleen getallen, maar bij veel andere sites zie ik ook gewoon woorden.
Maar nu de uiteindelijke vraag.
Als ik dus nu de kijk of id een getal is en dan met sql de datbase uitlees is dan nog sql injection mogelijk?
Als je checkt of $id een nummeriek getal is, zouden er nooit letters of tekens gebruikt kunnen worden, dus dan is het veilig.
Als je niet alleen nummerieke getallen wilt gebruiken moet je mysql_real_escape_string() over je $id halen als je daarmee wat uit je database haalt.
Beetje raar dat je alle pagina's in een db zet en daarna weeruit haalt om er een ID van te maken. Dit kan ook met een gewoon case scriptje.
<?php
//Toegestane paginas in array.
$allow_pages = array('home','page1','page2','page3','page4','page5');
//Kijken of de GET bestaat, en of ie in de array zit.
if(isset($_GET['page']) && in_array($_GET['page'],$allow_pages)){
//Kijken of de file ook echt bestaat.
if(file_exists("submap/".$_GET['page'].".php")){
//Pagina includen
include("submap/".$_GET['page'].".php");
}else{
//Home pagina includen
include("home.php");
}
}else{
//Home pagina includen
include("home.php");
}
?>
Dus als ik doe SELECT password FROM users zou dit wel werken... dus nog niet echt proof. je moet gewoon zorgen ongeacht de SQL syntax dat die niet uitgevoerd wordt.
ik doe meestal hetzelfde als jelle, een array met de pagina's die geladen mogen worden, daarna kijken of de $_GET in die array voorkomt. Dat is volgens mij wel veilig.
als je zeker wil zijn tegen SQL-injectie bouw je code dan zo op:
(php5 code)
if( isset($_GET['var']) {
if( is_numeric($_GET['var']) {
$var = $_GET['var'];
str_ireplace("DELETE","",$var);
str_ireplace("DROP","",$var);
str_ireplace("ALTER","",$var);
str_ireplace("GRANT","",$var);
str_ireplace("MODIFY","",$var);
str_ireplace("INSERT","",$var;
str_ireplace(";","",$var);
$QUERY = "SELECT x FROM y WHERE pageID='$var'";
}
}
Deze code zou je moeten beschermen tegen injecties. Tevens stript hij ook elk keyword nog eens uit je offset in de SQL
als je gewoon mysql_real_escape_string() gebruikt is het niet nodig om die woorden DELETE, DROP etc eruit te vissen. en dat is niet waterdicht. Zie tutorials over Mysql Injection.
@Arne: Wanneer je eerst met is_numeric() controleert of een variabele TRUE is, dan heeft het weinig zin om vervolgens nog met str_replace() aan de slag te gaan. Je weet namelijk al 100% zeker dat DELETE, DROP, etc. niet in deze variabele aanwezig zal zijn. De variabele zou in dat geval namelijk een FALSE opleveren.
Kortom, een zinloos stukje code waar nooit iets zinvols mee wordt gedaan.
Overigens kun je beter ctype_digit() gebruiken i.p.v. is_numeric(), zie de handleiding voor de verschillen.