Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

22 Stron V  « < 6 7 8 9 10 > »   
Reply to this topicStart new topic
> SQL Injection/Insertion, Jak zapobiec włamaniu na stronę.
bełdzio
post
Post #141





Grupa: Zarejestrowani
Postów: 690
Pomógł: 81
Dołączył: 6.04.2005
Skąd: Szczecin

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


Cytat(SirZooro @ 14.06.2007, 19:18:29 ) *
Kod
^[1-9][0-9]{0,8}$


Kod
echo preg_replace('/\s+/', ' ', ' a   b   c  ');


1. ctype_digit
2. str_replace

?
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #142





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

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


z ctype_digit() trzeba ostrożnie, bo jeśli nie dostanie stringa tylko int np. 34 to zwróci false, do tego jeśli string jest puszty "" to zwraca true.
dlatego jak ktoś chce użyć do sprawdzania danch np. z GET to powinien użyć takiego złożenia
  1. <?php
  2. if ( !empty($_GET['id']) && ctype_digit($_GET['id']) ){
  3.  //dobre id (string składa się z samych liczb)
  4. }else{
  5.  //Zły, pusty/zawiera inne znaki
  6. }
  7. ?>
Go to the top of the page
+Quote Post
Black-Berry
post
Post #143





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

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


Postanowiłem przyłączyć się do dyskusji. Kiepski ze mnie teoretyk więc od razu podam moj sposób rozuminienia tego o czym piszecie...
  1. <?php
  2. //clasa t_panel
  3. class t_panel
  4. {
  5. var $item_id; //pole trzymajace numer wiersza tabeli
  6. var $user_name; //pole trzymajacy nazwe pobraną z tabeli mysql
  7.  
  8. function t_panel() //konstruktor klasy
  9. {
  10. $this->item_id = $_GET["item_id"]; //pobieranie numeru przekazanego za pomocą _get
  11. if (!is_int($this->item_id) $this->item_id = 0; //ustawianie na 0 jesli nie jest liczba całk.
  12. $this->load_data_from_database();
  13. }
  14.  
  15. function load_data_from_database()
  16. {
  17. $query ="SELECT * FROM moja_tabela WHERE id=".$this->item_id." LIMIT 1";
  18. $result = mysql_query ( $query ) or die ( _MYSQL_ERROR_.":".mysql_error());
  19. $row = mysql_fetch_array($result, MYSQL_ASSOC);
  20. $this->user_name = $row["nazwa_uzytkownika"];
  21. }
  22.  
  23. function drop()
  24. {
  25. echo $this->user_name;
  26. }
  27. }
  28. ?>
Czy ktoś będzie się mógł mi włamać przy takim kodzie?

Ten post edytował Black-Berry 26.06.2007, 09:55:17
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #144





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

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


Nie, zawsze będzie 0, ponieważ tu jest błąd:
  1. <?php
  2. $this->item_id = $_GET["item_id"]; //pobieranie numeru przekazanego za pomocą _get
  3. if (!is_int($this->item_id) $this->item_id = 0;
  4. ?>

Zmienne z tablicy $_GET są zawsze typu string, więc musisz najpierw rzutować na int, bo:
Cytat
Returns TRUE if var is an integer, FALSE otherwise
Go to the top of the page
+Quote Post
Black-Berry
post
Post #145





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

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


Tyle się rozpisaliście na tym wątku, a jak ktoś (chyba słusznie) zauważył nie da sie praktycznie włamać do bazy MYSQL za pomocją SQL injection jeśli zmienne przekazywane metodą _GET są tylko i wyłącznie liczbami (a jak sądzę tak jest w większości przypadków.klk

Myślę też, że jeśli w przypadku przekazywania stringów zastosujemy funkcję real_escape_string() to włamanie SQLInjection będzie niemożliwe. Jeśli się myslę to prosze mnie skorygować bo w tym wątku czas na wniski.

Pozdrawiam.

Ten post edytował Black-Berry 3.07.2007, 10:10:18
Go to the top of the page
+Quote Post
bełdzio
post
Post #146





Grupa: Zarejestrowani
Postów: 690
Pomógł: 81
Dołączył: 6.04.2005
Skąd: Szczecin

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


  1. SELECT * FROM tabelka WHERE id = $_GET['id'];


-> $_GET['id'] = 5 or 1=1

wynik =
  1. SELECT * FROM tabelka WHERE id = 5 OR 1=1


efekt: pobranie wszystkich wpisów
Go to the top of the page
+Quote Post
Black-Berry
post
Post #147





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

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


(IMG:http://forum.php.pl/style_emoticons/default/dry.gif) że też ja na to nie wpadłem.... (IMG:http://forum.php.pl/style_emoticons/default/worriedsmiley.gif)

Sory, że dalej drążę temat ale nie chcę się obudzic z ręką w nocniku później...
Czy takie funkcje mnie ochronią przed SQL Injection? Czy powinienem do nich coś jeszcze dodać ?

  1. <?php
  2. function mysql_valid_number( $a_value )
  3. {
  4. if ( !empty( $a_value ) && ctype_digit( $a_value ) ){
  5. return $a_value;
  6. }else{
  7. return 0;
  8. }
  9. }
  10.  
  11. function mysql_valid_string( $a_value )
  12. {
  13. return mysql_real_escape_string( $a_value );
  14. }
  15.  
  16. $id = mysql_valid_number( $_GET["id"] );
  17. $name = mysql_valid_string( $_GET["name"] );
  18. $query_1 = "SELECT * FROM mytable WHERE id = ".$id."";
  19. $query_2 = "SELECT * FROM mytable WHERE name = ".$name."";
  20. ?>

EDIT: poprawiony return dla mysql_valid_string;

Ten post edytował Black-Berry 4.07.2007, 11:01:27
Go to the top of the page
+Quote Post
bełdzio
post
Post #148





Grupa: Zarejestrowani
Postów: 690
Pomógł: 81
Dołączył: 6.04.2005
Skąd: Szczecin

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


w mysql_valid_string return by się przydał
Go to the top of the page
+Quote Post
LEW21
post
Post #149





Grupa: Zarejestrowani
Postów: 20
Pomógł: 0
Dołączył: 31.01.2007

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


Black-Berry, po co tak kombinować? Po prostu do intów zawsze używaj (int) a do stringów mysql_real_escape_string albo PDO i bindParamy
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #150





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

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


Cytat(LEW21 @ 24.07.2007, 15:30:47 ) *
Black-Berry, po co tak kombinować? Po prostu do intów zawsze używaj (int) a do stringów mysql_real_escape_string albo PDO i bindParamy

A wiesz co uzyskasz po takim czymś:
  1. <?php
  2. $strIn = '-2';
  3. $intT = (int)$strIn;
  4. var_dump($intT);
  5. if( ctype_digit($strIn) ){
  6.  echo "Tylko cyfry";
  7. }else{
  8.  echo "Nie tylko cyfry";
  9. }
  10. ?>


A trzeba pilnować, ja coś ma być liczbą dodatnią niech nią będzie, bo potem gdzieś ktoś nie przewidzi, że może być ujemną i się posypie, a czasem jest tak że nie wywala błędu i trzeba szukać.
Aby jakiś algorytm działał poprawnie, muszą być spełnione wszystkie warunki początkowe.
Go to the top of the page
+Quote Post
NoiseMc
post
Post #151





Grupa: Zarejestrowani
Postów: 398
Pomógł: 10
Dołączył: 24.11.2004
Skąd: Łódź

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


Cytat
$strIn = '-2';

Jezeli ktos poda liczbe ujemna jako id rekordu, ktory ma zostac pobrany, a nie ma rekordu o takim id to nie dostanie z bazy nic ale o zadnym wlamaniu w ten sposob nie ma mowy.
Ja osobiscie stosuje rzutowanie (int) przy liczbach, a przy stringach robie sobie parametryzowane zapytanie PDO i bindParam i to starczy w zupelnosci.
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #152





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

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


@NoiseMc
Wiesz ale nie musi być to ID rekordu i nie zawsze musi działać jak myślisz, najlepiej jest zabezpieczyć tak, aby dostawał tylko to co oczekujesz.
Bo na tym to wszystko polega, że masz dostać tylko to co powinieneś, wtedy nie martwisz się o jakieś inne dziwne przypadki.
Go to the top of the page
+Quote Post
NoiseMc
post
Post #153





Grupa: Zarejestrowani
Postów: 398
Pomógł: 10
Dołączył: 24.11.2004
Skąd: Łódź

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


Ale po co kombinowac ...
  1. <?php
  2. // url/?action=show&id=1
  3. $id = (int)$_GET['id']; // $id = 1 - rekord istnieje i go dostaniesz
  4.  
  5. // url/?action=show&id=-1
  6. $id = (int)$_GET['id']; // $id = -1 - rekord moze nie istniec nic nie dostajesz
  7.  
  8. // url/?action=show&id=zlosliwy sql'; --
  9. $id = (int)$_GET['id']; // $id = 0 - rowniez nic nie dostajesz
  10. ?>

Wystarczy w zupelnosci ... jezeli user poda w url-u prawidlowy ID to dostaje prawidlowy rekord ... jezeli nie to dostaje 'nic'. Nie chodzi o to zeby dostawac to co oczekujesz tylko o to zeby radzic robie z tym czego nie oczekujesz (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Ten post edytował NoiseMc 9.08.2007, 16:26:43
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #154





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

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


Ech, ciągle ograniczasz się do ID, do tego ja mam podejście że jak robić to dobrze, a kontrola tego co się dostaje ma być dokładna, nie wiem co potem będę chciał z tym robić, ale najlepiej jak jest tym co chcę, a nie coś "co działa".

Edit: literówka

Ten post edytował Sedziwoj 9.08.2007, 18:16:49
Go to the top of the page
+Quote Post
NoiseMc
post
Post #155





Grupa: Zarejestrowani
Postów: 398
Pomógł: 10
Dołączył: 24.11.2004
Skąd: Łódź

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


Ja pisze o sposobach zabezpieczenia sie przed wstrzyknieciem zlosliwego SQL, a nie o walidacji danych wejsciowych. Jak wyprowadzasz psa na spacer to nie musisz sprawdzac czy nalezy do gatunku gryzacych ... wystarczy ze mu zalozysz kaganiec (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) tak wiec aby skutecznie ochronic sie przed SQL Injection wystarczy w zupelnosci to co napisal LEW21 i ja. Jezeli natomiast chodzi o walidacje danych wejsciowych bo na przyklad cena produktu musi byc liczba a jego adres url nie moze zawierac znakow specjalnych to w pelni sie z Toba zgadzam powinno sie sprawdzac wszystko ... a do tego uzywam Zend_Validate_* - bardzo prosta w uzyciu metoda, ktora w polaczeniu z Zend_Filter jest prosta, wygodna i porzadna.

Ten post edytował NoiseMc 9.08.2007, 19:14:56
Go to the top of the page
+Quote Post
Endzio
post
Post #156





Grupa: Zarejestrowani
Postów: 25
Pomógł: 0
Dołączył: 10.09.2007

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


Witam.
Używam kodu
  1. <?php
  2. function filtr($zmienna)
  3. {
  4. $zmienna = htmlspecialchars(trim($zmienna));
  5. $zmienna = str_replace("r\n", "<br />", $zmienna);
  6. $zmienna = str_replace("'", "&#_039;", $zmienna); //Bez znaku "_"
  7. return $zmienna;
  8. }
  9.  
  10. $autor = filtr($_POST['autor']);
  11. $tresc = filtr($_POST['tresc']);
  12. $sql = mysql_query("insert into shoutbox values ('NULL', '$autor', '$tresc')") or die("Błąd: ".mysql_error());
  13. ?>

Oraz standardowe pytanie (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif)
Czy moje rozwiązanie jest bezpieczne, co byście zmienili?
Go to the top of the page
+Quote Post
Black-Berry
post
Post #157





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

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


Dołączam się do pytania... możebyśmy napisali wspólnie 2 ostateczne wersje funkcji czyszczących string oraz liczby typu float (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
@Sedziwoj Pomóż chłopie bo chyba tylko ty wiesz o co naprawdę chodzi (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Podrawiam.

Edit: błędy.

Ten post edytował Black-Berry 11.09.2007, 11:37:25
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #158





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

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


Jak sprawdzać dane typu string? To zależy co może w nich być a co nie...
Co do liczb jeśli liczba może być tylko dodatnia całkowita preferuję, a jest z GET (ważne, bo w tej metodzie zmienna musi być tylu string)
  1. <?php
  2. $cos = '4342';
  3. if( !empty($cos) && ctype_digit($cos ) ){
  4.  echo "tak";
  5.  $int = (int)$cos;
  6. }else{
  7.  echo "nie";
  8. }
  9. ?>

To jest dobre do sprawdzania np. ID
Przy liczbach które mogą być ujemne, lub/i zmiennoprzecinkowe możne użyć is_numeric() (ale trzeba pamiętać aby rzutować na typ oczekiwany, czyli nie pomijać (int)) ale znakiem dziesiętnym jest "." nie "," co może być problemem.
Jeśli mamy "," to wtedy trzeba użyć preg_match() i wzorze typu '/[-+]?[1-9][0-9]*([\\.,][0-9]*)?/' lub zamienić "," na "." i robić tą poprzednią metodą.

Wracając do string'ów, to na prawdę zależy co powinno być, a czego nie powinno. I o tym już było pisane, po znaj ' jest dla html właściwie obojętny, ale dla SQL może być zabójczy. Tylko że czasem go można zamienić używając htmlspecialchars() czy też można htmlentities() ale to zależy od specyfikacji, przy bazie mysql_escape_string() czy mysql_real_escape_string(), pg_escape_string() itd. itp.

@Endzio
Dla mysql NULL to jest typ, zaleca się
  1. <?php
  2. $str = 'cos ' . $cos . '...';
  3. ?>

czyli aby zmienne nie były w ciągu znaków, (przy zapytaniu SQL gdzie jest wiele ' można użyć ", ale też zmienne są wyizolowane od ciągu).


EDIT:
P.S. Ja tam nie znam się na tym dobrze... tylko trochę wiem.

Ten post edytował Sedziwoj 11.09.2007, 13:16:56
Go to the top of the page
+Quote Post
piter2k1
post
Post #159





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 6.02.2007

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


Co do pierwszego postu:

Kod
<?php
$query = "update uzytkownicy set pole='$dane' where id='$id'\";
?>


Ja zrobił bym po prostu:
Kod
<?php
$id = settype($_GET['id'], 'integer');
$query = "update uzytkownicy set pole='$dane' where id='$id'\";
?>
Go to the top of the page
+Quote Post
Kicok
post
Post #160





Grupa: Zarejestrowani
Postów: 1 033
Pomógł: 125
Dołączył: 17.09.2005
Skąd: Żywiec

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


Cytat
Ja zrobił bym po prostu:


A co zwraca funkcja settype" title="Zobacz w manualu PHP" target="_manual? Chyba pomyliło Ci się z intval" title="Zobacz w manualu PHP" target="_manual ;]
Go to the top of the page
+Quote Post

22 Stron V  « < 6 7 8 9 10 > » 
Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 24.08.2025 - 15:04