[SQL Injection] Testy nie powiodły się

0

Witam ponownie,
chcę poruszyć dziś kwestię SQL Injection, o którym jest bardzo głośno. Mówi się że z formularza można "zaatakować" bazę danych np: wpisując x' OR '1'='1. Wykonałem testy i nie mogłem pobrać danych z bazy. Bezpośrednio z kodu działa, ale z formularza już nie. Wykonałem sobie próbny plik:

echo '
<form method="POST">
<input type="text" name="name" value=""/>
<input type="submit" value="OK" />
</form>';


if($_POST['name'] != "")
{
$name = "x' or '1'='1";
$db = new Pobierz("SELECT * FROM sqltest WHERE name='".$name."' ORDER BY id");

foreach($db->getAll() as $ele){
   foreach($ele as $ele2){
	echo $ele2." - ";
   }
  echo "<br />";
}
}

Co testowałem (podany kod php zastępuje linijkę: $name = "x' or '1'='1";):

index Co zrobiłem ? Wynik testu
1 Powyższy kod prezentuje podanie x' OR '1'='1. Jest to jedyna działająca opcja, ale nie tak to ma wyglądać działa
2 Wpisanie w formularz wartości: height' or '1'='1 błąd
3
$name = $_POST['name'];

| błąd
4 | Jeżeli usuniemy powyższy kod i bezpośrednio do zapytania SQL podamy $name | błąd
5 | Jeżeli usuniemy powyższy kod i bezpośrednio do zapytania SQL podamy $_POST['name'] | błąd
6 | Wpisanie do formularza

x' OR '1'='1

| błąd - dodaje \ przed '
7 | Wpisanie do formularza

x\' OR \'1\'='1

| błąd - dodaje \ przed '
8 | Wpisanie do formularza (ze znakiem ' w kodzie dziesiętnym)

&#039;x&#039; OR &#039;1&#039;=&#039;1&#039;

| błąd - jedyny sposób by pobrał zawartość jako x' OR '1'='1 bez dodawania znaku ****. Mimo to brak reakcji (jak zwrócimy echo dla całości to wygląda tak: SELECT * FROM sqltest WHERE name='x' OR '1'='1' ORDER BY id, a mimo to nic się nie dzieje)

Jeszcze jakieś inne testy, ale nie pamiętam. Sprawdzane było na przeglądarkach: Firefox, Explorer, Chrome - i nic. Może wy wiecie co zrobić by to zadziałało. Wszelkie testy robię na WebServ 2.0 i nie ustawiałem żadnych zabezpieczeń (poza standardem ustawień) ???

Jeżeli są jakieś błędy interpunkcyjne to nie zwracajcie na nie uwagi. Słowo błąd oznacza brak pożądanej reakcji kodu.

1

magic_quotes_gpc ratuje ci tyłek, anyway jest niezalecany i denerwuje tych którzy wiedzą jak się zabezpieczać, a mimo to slashuje im na chama zmienne... Wyłącz w php.ini tą zdeprecjonowaną opcję.

0

To ja się rozpisałem a to taka mała kwestia. Mimo to jeżeli jest taka opcja to jest potrzebne dalsze zabezpieczenie ? Nie chodzi mi o serwery gdzie tego nie ma, tylko gdzie istnieje.

0

Trafisz na serwer gdzie masz wyłączone magic_quotes_gpc i masz niezły problem. Nie zaleca się używania tego, całe "zabezpieczenie" zdeprecjonował zespół PHP i ma zostać usunięte w następnych wersjach. Lepiej się zabezpieczyć we własnym zakresie i mieć pewność.

0

tutaj masz przykładowy sposób na ominięcie magic_quotes: http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string (sposób się zmienia zależnie od użytego w bazie danych kodowania - tutaj masz sposób na kodowanie UTF-8, ale warunkiem jest, że zapytanie będzie przepuszczone wcześniej przez funkcję utf8_decode (zdarza się często w krajach korzystających z latin1))
poza tym wystarczy, że gdzieś dasz wartość liczbową bez cudzysłowu typu WHERE id='.$name i masz kapliczkę

magic_quotes to zło rozpieszczające koderów i zwalniające ich z myślenia o prawdziwych zabezpieczeniach
warto się podwójnie zabezpieczyć na wypadek swoich przeoczeń i na przykład przy logowaniu często spotyka się sprawdzenie czy liczba userów z danym ID i hasłem jest >0 i jeśli tak to logujemy się na dane z pierwszej krotki. A skoro zapytanie mialo zwrócić dokładnie jednego usera to powinno sprawdzić raczej czy liczba zwróconych rekordów jest dokładnie równa 1, czyż nie? Program się przez to nie wydłuży

SQL Injection to nie mit skoro przeprowadzanych jest tyle ataków z jego udziałem - niedawno ofiarą padła nawet o ironio strona mysql: http://www.varlog.pl/2011/03/mysql-com-shackowane/

0

Generalnie zalecam używanie jakiegoś wrappera do SQL. Jest sporo nakładek poczynając od tych, które pomagają podstawiać zmienne, po takie które zapytanie w pełni zmieniają w obiekt.

//przykład z użyciem wrappera
Query::getInstance()
   ->select('something', 'foo')
   ->from('jakas_tabela')
   ->where('something', EQ, $costam)
   ->execute();

Czyż nie piękne? Korzystając z czegoś takiego nie da się praktycznie zrobić podatności na SQL Injection.

1 użytkowników online, w tym zalogowanych: 0, gości: 1