Databashantering‎ > ‎php‎ > ‎

SQL injections

SQL-injections är en vanlig angreppsmetod mot databasdrivna webbapplikationer. Det hela går ut på att mata in värden i t.ex. ett forumulär som sedan körs mot databasen där en SQL-fråga är inbakad i strängen. I det här exemplet kommer vi gå igenom hur SQL-injections fungerar men även hur vi med funktionen mysq_real_escape_string kan skydda mot detta.


Vi tar ett exempel där användare har skyddat data med en enkel inloggning

Om vi tänker oss att tabellen users innehåller detta:
SELECT * FROM users;
+---+---------+---------+----------- -+
|id |username |password |allergy      |
+---+---------+---------+-------------+
|1  |homer    |abc123   |no beer      |
|2  |superman |Kent     |kryptonite   |
|3  |batman   |adamwest |zombies      |
|4  |indiana  |jones    |snakes       |
|5  |macgyver |#d¤5L9§9 |Chuck Norris |
+---+---------+---------+-------------+

Och på deras sida går det logga in via ett forumlär:

<form action="login.php" method="POST">
    
Användarnamn: <input type="text" name="username" /><br />
    
Lösenord: <input type="password" name="password" /><br />
    <
input type="submit" />
</
form>
I login.php:
<?php
include('dbconnect.php');

if(isset(
$_POST['username']) && isset($_POST['password'])) {
    
$username $_POST['username'];
    
$password  $_POST['password'];

    
$sql "SELECT * FROM users WHERE username='$username' AND password='$password'";
    
$result mysql_query($sql);
    
$num_result mysql_num_rows($result);
    if(
$num_result 0){
        
$user mysql_fetch_assoc($result);
        
        echo 
"Hej $user[username] <br />";
        echo 
"Du är allergisk mot: $user[allergy]";
    }else{
        echo 
"fel användarnamn eller lösenord";
    }
}
?>

Under normala omständigheter loggar användare in på sidan genom att fylla i användarnamn och lösenord som sedan kommer testas mot databasen med en SQL-fråga.
Vi stätter upp scenariot att MacGyvers ärkefiende Murdoc vill ha reda på sin nemesis alergi men han kan givetvis inte gissa sig till MacGyvers lösenord. Oturligt nog så har Murdoc god kännedom om hur SQL-injections fungerar. Han fyller därför i:
Användarnamn: Haxx0r
Lösenord: ' OR 42=42 AND username='macgyver

$sql i login.php kommer då se ut så här:

SELECT * FROM users WHERE username='Haxx0r' AND password='' OR 42=42 AND username='macgyver'

Vilket kommer resultera i att frågan går igenom.
Vips så har Murdoc fått reda på att MacGyver är allergisk mot Chuck Norris.

Lyckligtvis var det bara ett skämt då MacGyver och Chuck Norris är mycket goda vänner. Så de båda slår sina kloka huvuden ihop och ändrar på login.php för att se till att inte Lex Luthor, Mr Burns eller någon annan ondsint person gör intrång.
<?php
include('dbconnect.php');

if(isset(
$_POST['username']) && isset($_POST['password'])) {

    //lägger till \ framför tecken som '
    
$username  mysql_real_escape_string($_POST['username']);
    
$password  mysql_real_escape_string($_POST['password']);

    
$sql "SELECT * FROM users WHERE username='$username' AND password='$password'";
    echo 
"<pre>$sql</pre>";
    
$result mysql_query($sql);
    
$num_result mysql_num_rows($result);
    if(
$num_result 0){
        
$user mysql_fetch_assoc($result);
        
        echo 
"Hej $user[username] <br />";
        echo 
"Du är allergisk mot: $user[allergy]";
    }else{
        echo 
"fel användarnamn eller lösenord";
    }
}
?>

Ett intrångförsök som tidigare kommer alttså leda till att $sql ser ut så här:
SELECT * FROM users WHERE username='Haxx0r' AND password='\' OR 42=42 AND username=\'macgyver'
Vilketer leder till:
"fel användarnamn eller lösenord"


För mer läsning på ämnet se:
http://www.swesecure.com
http://www.unixwiz.net/techtips/sql-injection.html


Comments