Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> SQL Injection/Insertion, Jak zapobiec włamaniu na stronę.
Najki
post
Post #1





Grupa: Zarejestrowani
Postów: 190
Pomógł: 0
Dołączył: 12.02.2004
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Pytania o streszczenie wątku, posty z "genialnymi" skryptami nadającymi się tylko na przedszkole i inne tego typu, będą bez ostrzeżenia usuwane przez moderatorów.
To mówiłem ja, Jarząbek... znaczy nospor dnia 2007-12-10
-------------------------------------------------------------------------------


SQL Injection (zwane też "SQL Insertion") to (rzekomo) najprostszy sposób włamu na stronę. Spowodowany jest on niepełnym sformułowaniem zapytań do MySQL.

Przykład. Dajemy na stronie możliwość edycji profilu. Zapytanie do SQL wygląda następująco:
  1. <?php
  2. $query = &#092;"update uzytkownicy set pole='$dane' where id='$id'\";
  3. ?>

Osoba włamująca się na stronę umieszcza całkiem prosty, odpowiedni ciąg znaków/poleceń w dowolnym polu edycji tego profilu, który wygląda np. tak (dla zmiany hasła użytkownika o dowolnie wybranym, przez atakującego numerze ID):
  1. <?php
  2. ', haslo='nowe_haslo' WHERE id = '1
  3. ?>


W taki oto prosty sposób, osoba atakująca zmieniła hasło użytkownikowi o ID=1 (zazwyczaj administrator). W podobny sposób można również wyciągnąć dowolne dane z tabeli SQL.

W każdym razie. Poszperałem, pomyślałem i zebrałem wszystko do kupy. Zamieszczam to tutaj razem, oraz proszę o rozbudowanie tego topica, gdyż nie znalazłem na tym forum więcej informacji o "SQL Injection".

Oto co możemy dokonać:
1. Możemy sformułować nasze zapytanie do SQL tak:
  1. <?php
  2. $query = 'update `uzytkownicy` set `pole`=\"'.$dane.'\" where `id`=\"'.$id.'\";';
  3. ?>

2. Przy wstawianiu numerów ID do zapytań należy stosować tzw. rzutowanie typów:
  1. <?php
  2. $id = (int)$_GET['id'];
  3. // lub
  4. $id = intval($_GET['id']);
  5. ?>

3. Przy wstawianiu tekstów, należy wyciąć niebezpieczne znaki przy pomocy funkcji:
  1. <?php
  2. $string = mysql_real_escape_string($_POST['string']); // PHP5
  3.  
  4. $string = mysql_escape_string($_POST['string']); /* lub */ $string = addslashes($_POST['string']); // PHP4
  5. ?>


Może nie ma tego dużo, ale jest to już jakaś podstawa do zabezpieczenia strony/skryptu przed prostym i niezwykle niebezpiecznym, SQL Injection. Proszę osoby obeznane w tym temacie, aby dopisały tu własne propozycje metod zabezpieczenia się przed tym atakiem.

Ten post edytował Najki 14.02.2008, 10:04:12
Go to the top of the page
+Quote Post
22 Stron V  « < 15 16 17 18 19 > »   
Start new topic
Odpowiedzi (320 - 339)
erix
post
Post #321





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Huh, z tego co pamiętam, to dało się też niektóre znaki zapisać korzystając z "wysokich kodów Unicode", a to już jest ciężko odfiltrować. (IMG:style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post
pyro
post
Post #322





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Cytat(SHiP @ 16.07.2010, 23:29:04 ) *
Wszelkie te zabezpieczenia operujące na słownikach są kretyńskie zawsze można większość z nich ominąć za pomocą komentarzy. Nawet jeśli filtrujesz np. UNION mogę napisać U/**/N/**/I/**/O/**/N albo w hex albo wykorzystując funkcję char()



@SHiP, zdaje się, że masz pisać książkę o bezpieczeństwie www, więc powiedz mi... gdzie te Twoje "U/**/N/**/I/**/O/**/N" zadziała?
Go to the top of the page
+Quote Post
SHiP
post
Post #323





Grupa: Zarejestrowani
Postów: 697
Pomógł: 47
Dołączył: 19.12.2003
Skąd: Lublin

Ostrzeżenie: (0%)
-----


@pyro: ok trochę się zapędziłem. Sprawdziłem i w nowszych wersjach MySQL to nie działa.

W oracle można użyć czegoś takiego jak execute immediate i tam umieścić zapytanie zapisane w taki sposób jak podałem wyżej i ono zadziała.
W MS SQL można użyć exec()

A jako że piszemy o mysql(chyba?) to za pomocą /**/ można w nim ładnie pousuwać białe znaki np. takie zapytanie nie ma ani jednej spacji a działa:
  1. SELECT/**/*/**/FROM/**/news;


EDIT:
albo coś jeszcze bardziej fajnego

  1. /*!SELECT*//*!**//*!FROM*//*!news*/


To działa(sic!)

Ten post edytował SHiP 16.07.2010, 23:27:00
Go to the top of the page
+Quote Post
H4eX
post
Post #324





Grupa: Zarejestrowani
Postów: 150
Pomógł: 15
Dołączył: 1.07.2010

Ostrzeżenie: (0%)
-----


Cytat(SHiP @ 16.07.2010, 23:29:04 ) *
Wszelkie te zabezpieczenia operujące na słownikach są kretyńskie zawsze można większość z nich ominąć za pomocą komentarzy. Nawet jeśli filtrujesz np. UNION mogę napisać U/**/N/**/I/**/O/**/N albo w hex albo wykorzystując funkcję char()

Jak niby wykorzystać funkcję char() ?
*, char można usuwać, a przed hex da się też zabezpieczyć.
Przyznaję, pomysł trochę nie za dobry ale można zrobić z tego log (IMG:style_emoticons/default/winksmiley.jpg)

Ten post edytował H4eX 17.07.2010, 13:38:33
Go to the top of the page
+Quote Post
SHiP
post
Post #325





Grupa: Zarejestrowani
Postów: 697
Pomógł: 47
Dołączył: 19.12.2003
Skąd: Lublin

Ostrzeżenie: (0%)
-----


  1. SELECT char(80,72,80);


==

  1. SELECT PHP

Go to the top of the page
+Quote Post
darko
post
Post #326





Grupa: Zarejestrowani
Postów: 2 885
Pomógł: 463
Dołączył: 3.10.2009
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Cytat(SHiP @ 17.07.2010, 00:11:18 ) *
EDIT:
albo coś jeszcze bardziej fajnego

  1. /*!SELECT*//*!**//*!FROM*//*!news*/


To działa(sic!)

To zapytanie akurat nie działa (IMG:style_emoticons/default/winksmiley.jpg) (IMG:style_emoticons/default/cool.gif)
Go to the top of the page
+Quote Post
SHiP
post
Post #327





Grupa: Zarejestrowani
Postów: 697
Pomógł: 47
Dołączył: 19.12.2003
Skąd: Lublin

Ostrzeżenie: (0%)
-----


@darko: jaką masz wersję mysql? I czy masz w wybranej bazie tabelę news ;]

U siebie mam mysql Ver 14.14 Distrib 5.1.36, for suse-linux-gnu (x86_64) using readline 6.0 i dziala...
Go to the top of the page
+Quote Post
darko
post
Post #328





Grupa: Zarejestrowani
Postów: 2 885
Pomógł: 463
Dołączył: 3.10.2009
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


5.0.51a-24+lenny2+spu1 (Linux debian 2.6.30-bpo.1-686 #1 SMP Mon Aug 17 14:57:26 UTC 2009 i686 GNU/Linux) i nie hula. Oczywiście podałem nazwę istniejącej tabeli w bazie (IMG:style_emoticons/default/smile.gif) I zwraca całe nic (nie ma błędów po prostu nie zwraca żądnego wyniku, a dane w tabeli są na 100%).

Ten post edytował darko 17.07.2010, 13:54:06
Go to the top of the page
+Quote Post
SHiP
post
Post #329





Grupa: Zarejestrowani
Postów: 697
Pomógł: 47
Dołączył: 19.12.2003
Skąd: Lublin

Ostrzeżenie: (0%)
-----


Hmm no to dziwne. Wygląda na to, że starsza werjsa inaczej to interpretuje lub masz pustą tabelę. A coś takiego
Cytat
mysql> /*!SELECT*//*!'PHP'*/;
+-----+
| PHP |
+-----+
| PHP |
+-----+
1 row in set (0.00 sec)


(IMG:style_emoticons/default/questionmark.gif)
Go to the top of the page
+Quote Post
darko
post
Post #330





Grupa: Zarejestrowani
Postów: 2 885
Pomógł: 463
Dołączył: 3.10.2009
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Wydzielcie ten nasz OT, jak możecie
/*!SELECT*//*!'advisors'*/;
to samo w mysql-query-browser v. 1.2.12:
Query executed in 0:00.0250. Query finished

To samo w phpmyadmin (phpMyAdmin - 2.11.8.1deb5+lenny3):
/*!SELECT*//*!'advisors'*/
Pokaż rekordy 0 - 0 (1 wszystkich, Wykonanie zapytania trwało 0.0003 sekund(y))

Dane są w tabeli advisors na milion %
Go to the top of the page
+Quote Post
set4812
post
Post #331





Grupa: Zarejestrowani
Postów: 150
Pomógł: 3
Dołączył: 13.04.2010

Ostrzeżenie: (0%)
-----


Temat ma duzo strony czy ktoś mógłby wymienic wszystkie funkcje które chronia przed sql Injection
Go to the top of the page
+Quote Post
Noidea
post
Post #332





Grupa: Zarejestrowani
Postów: 226
Pomógł: 61
Dołączył: 20.08.2010

Ostrzeżenie: (0%)
-----


W sumie to faktycznie lekki śmietnik tu się zrobił.

Ogólnie to nie ma czegoś takiego jak "funkcja chroniąca przed SQL Injection". Temat jest bardziej złożony.
Najprościej jest przerzucić się w końcu na PDO i używać prepared statements


- Inne funkcje "chroniące przed SQL Injection" to mysql_real_escape_string, pg_escape_string, itp.

Stosuje się je do danych tekstowych i tylko dla odpowiedniego systemu bazodanowego.
Jeśli użyjemy funkcji wstawiającej ukośniki przed apostrofami ('O\'Reilly'), a w naszym systemie DB znakiem ucieczki jest drugi apostrof ('O''Reilly'), to nie dość że nie zabezpieczyliśmy się przed niczym, to jeszcze wstawiamy śmieci do bazy danych.

- W przypadku danych liczbowych używamy intval, floatval

- W przypadku nazw kolumn (np. do sortowania), to stosujemy:
  1. <?php
  2.  
  3. $columns = array( 'date', 'points', 'level' );
  4.  
  5. // identyfikatory tekstowe lub liczbowe
  6. if( $_GET['orderType'] < 0 || $_GET['orderType'] >= count( $columns ) )
  7. {
  8. // ktoś próbuje mieszać, throw new Exception
  9. }
  10.  
  11. $orderColumn = $columns[$_GET['orderType']];
  12. $query = "SELECT (...) ORDER BY $orderColumn";
  13. // zapytanie
  14.  
  15.  
  16. // lub nazwy kolumn
  17. if( !in_array( $_GET['orderType'], $columns ) )
  18. {
  19. // ktoś próbuje mieszać, throw new Exception
  20. }
  21.  
  22. $query = "SELECT (...) ORDER BY $_GET[orderType]";
  23. // zapytanie
  24.  
  25. ?>



- W przypadku MySQL zamiast popularnego addslashes poleca się używanie mysql_real_escape_string


- stripslashes jest praktycznie niepotrzebny. Przydaje się tylko, żeby oczyścić dane wejściowe ze śmieci jeśli mamy włączone magic_quotes_gpc
Go to the top of the page
+Quote Post
-lukasamd-
post
Post #333





Goście







Cytat(Noidea @ 29.09.2010, 12:38:25 ) *
- W przypadku danych liczbowych używamy intval, floatval



Rzutowanie będzie szybszym rozwiązaniem.
Go to the top of the page
+Quote Post
gargamel
post
Post #334





Grupa: Zarejestrowani
Postów: 278
Pomógł: 35
Dołączył: 25.06.2010

Ostrzeżenie: (0%)
-----


A co sądzicie o metodzie (na SELECT, UPDATE itp)


  1. SELECT * FROM TABLE WHERE md5(column_name)='".md5($condition)."';


(IMG:style_emoticons/default/questionmark.gif)
Go to the top of the page
+Quote Post
Mephistofeles
post
Post #335





Grupa: Zarejestrowani
Postów: 1 182
Pomógł: 115
Dołączył: 4.03.2009
Skąd: Myszków

Ostrzeżenie: (0%)
-----


Po co? Może wystąpić kolizja, choć to mało prawdopodobne, a poza tym po co dodatkowo obciążać PHP i bazę liczeniem hasha? Wystarczą prepared statements i SQL Injection masz z głowy.
Go to the top of the page
+Quote Post
michal123
post
Post #336





Grupa: Zarejestrowani
Postów: 1
Pomógł: 0
Dołączył: 4.12.2010

Ostrzeżenie: (0%)
-----


Czy zastosowanie wyrazen regularnych z funkcja preg_match() do danych pochodzacych z formularza uchroni mnie od SQL Injection? Czy jest to niewystarczające zabezpieczenie?
Go to the top of the page
+Quote Post
pyro
post
Post #337





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Cytat(michal123 @ 4.12.2010, 19:18:04 ) *
Czy zastosowanie wyrazen regularnych z funkcja preg_match() do danych pochodzacych z formularza uchroni mnie od SQL Injection? Czy jest to niewystarczające zabezpieczenie?


Nie. A teraz przeczytaj temat.
Go to the top of the page
+Quote Post
Rid
post
Post #338





Grupa: Zarejestrowani
Postów: 715
Pomógł: 47
Dołączył: 5.12.2010

Ostrzeżenie: (0%)
-----


Ja na każdym inpucie wprowadziłem preg_match jako głowną formę zabezpieczenia,żeby mi ktoś śmieci nie wpisywał dodatkowo użyłem funkcje, która dodatkowo filtruje, każdą wprowadzoną zmienną poprzez metody stripslashes,htmlentities,strip_tags i pomocniczo trim.Jednakże ,mam wątpliwość co do metody "htmlentities". Użyłem jej w taki sposób
  1. $data= htmlentities ($data,ENT_QUOTES, 'UTF-8');
.Wiem ,że funkcja ma konwertować znaki specjalne do kodowani encji.Polskie znaki w tej metodzie ,są także postrzegane jako znaki specjalne,dlatego w metodzie użyłem zamiany encji na UTF-8 ,ale czy to ma sens???Czy np."\" nie zostanie z powrotem sprowadzony do postaci "\" zamiast do "amp&" która jest encją(IMG:style_emoticons/default/questionmark.gif) ?
Go to the top of the page
+Quote Post
propage
post
Post #339





Grupa: Zarejestrowani
Postów: 330
Pomógł: 0
Dołączył: 25.01.2008

Ostrzeżenie: (0%)
-----


A moje pytanie jest takie:

Czy jest gdzieś zestaw znaktów specialnych, bardzo często używanych w atach przez typu:
../
'--'
'<script>'
'onclick'
'char(
itd...

Myślę, że można zrobić funkcje, która przy każdym odświeżeniu strony będzie sprawdzać $_POST, $_GET, $_SERVER. w momencie, gdy któraś z tablic będzie zawierać słowo, z powyższej listy to damy bana na IP dla klienta. Wiadomo taki ban przed niczym nie zabezpieczy, ale skomplikuje trochę prace hakerowi i wytnie wszystkie boty, które nie zmieniają IP(ów).
Chciałbym tylko dostać jeśli ktoś posiada listę zwrotów, która nada się do zbudowania takiej funkcji, a o pomyśle co sądzicie?
Go to the top of the page
+Quote Post
Crozin
post
Post #340





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


@propage: A teraz wyobraź sobie, że tutaj na forum jest coś takiego. Piszesz sobie ładnie posta, dajesz wyślij i jesteś zbanowany. wtf?
Go to the top of the page
+Quote Post

22 Stron V  « < 15 16 17 18 19 > » 
Reply to this topicStart new topic
3 Użytkowników czyta ten temat (3 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 26.08.2025 - 20:31