Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ PHP _ SQL Injection/Insertion

Napisany przez: Najki 24.11.2004, 23:13:57

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 = http://www.php.net/intval($_GET['id']);
  5. ?>

3. Przy wstawianiu tekstów, należy wyciąć niebezpieczne znaki przy pomocy funkcji:
  1. <?php
  2. $string = http://www.php.net/mysql_real_escape_string($_POST['string']); // PHP5
  3.  
  4. $string = http://www.php.net/mysql_escape_string($_POST['string']); /* lub */ $string = http://www.php.net/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.

Napisany przez: Vengeance 24.11.2004, 23:34:40

Cytat(Najki @ 2004-11-25 00:13:57)
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. Numer ID warto ustawiać w sposób $_GET['id'], lub $_POST['id'], można też ustawić go w nast. sposób:
  1. <?php
  2. $id = (int)$_GET['id'];
  3. ?>


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.

punkt 1. twojego "zabezpieczenia" nie ma nic do rzeczy z rzeczywistym bezpieczeństwem przynajmniej wg mnie

punkt 2. ja stosuje po prostu addslashes() i filtruje dane z POST GET COOKIE itd. tzn jak ma byc liczba do liczba a nie string smile.gif

stosujac gotowe skrypty ala phpbb itd. dopisuje zawsze w jakims glownym pliku
usuwanie s url-a wystapien wyrazow "<script>" i "UNION" co zabezpiecza przez script kiddie

Napisany przez: ActivePlayer 25.11.2004, 00:06:02

Z tego co wiem to mysql nie wykonuje zapytan typu "zapyta1;zapyt2" od sstrony php wiec tego nei masz sie co bac... co do filtrowania danych...

http://pl.php.net/mysql_escape_string

Napisany przez: Najki 25.11.2004, 00:22:22

Cytat(Vengeance @ 2004-11-25 00:34:40)
punkt 1. twojego "zabezpieczenia" nie ma nic do rzeczy z rzeczywistym bezpieczeństwem przynajmniej wg mnie

Gdzieś znalazłem informację, że niby jednak to ma pomóc (głównie chodzi o średnik tam też o średnik na końcu zapytania)
Cytat(Vengeance @ 2004-11-25 00:34:40)
punkt 2. ja stosuje po prostu addslashes() i filtruje dane z POST GET COOKIE itd. tzn jak ma byc liczba do liczba a nie string

Czy czasem $_POST, $_GET i $_COOKIE nie mają automatycznie dodawanych slash'y ?
Cytat(Vengeance @ 2004-11-25 00:34:40)
stosujac gotowe skrypty ala phpbb itd. dopisuje zawsze w jakims glownym pliku
usuwanie s url-a wystapien wyrazow "<script>" i "UNION" co zabezpiecza przez script kiddie

Tak będzie OK? (nie znam się na wyrażeniach regularnych, a chciałbym, aby w tym topicu wszystko było jasno opisane, co by nikt problemów nie miał)
  1. <?php
  2. http://www.php.net/preg_replace( '%<script>%', '', $zmienna );
  3. ?>

Napisany przez: Kinool 25.11.2004, 08:48:38

zabezpieczenie w stylu:

  1. <?php
  2. $query = 'update `uzytkownicy` set `pole`=\"'.$dane.'\" where `id`=\"'.$id.'\";';
  3. ?>
to jak juz powiedziano zadne zabezpieczenie a pozatym zmnijsza wydajnosc zapytania, umieszczanie wartosci liczbowych w momiedzy " " powiduje iz MySQL mysli ze ma do czynienia ze znakami (stringami) i niepotzrebnie musi konwertowac typy.

Przylacze sie do tego co juz powiedziano, uzywac Zmiennych globalnych, i filtrowac wszystko, to co ma byc liczba to konwertowac na liczbe np:
  1. <?php
  2. $_GET['id'] = http://www.php.net/intval($_GET['id']);
  3. ?>
a to co ma byc stringiem dodawac slashe (addslashes).

Podstawowa zasada to nie ufac nikomu i spodziewac sie najgorszego!
budowac aplikacje tak by wytrzymaly wybuch nuklearny smile.gif

w jednym ze swoich projektw zrobilem petle na foreach ktora z kazdego elemenu tablicy ($_GET, $_POST, $_COOKIE) zamieniala ewentualn wystapienia wyrazen takich jak "SELECT, UPDATE, INSERT, DELETE, WHERE AND" dodajac do nich np twarda spacje &nbsp; lub jakis inny znak co powodowalo ze ew. zapytanie bylo by z gory obarczone bledem.

coprawda rozwiazanie takie nie jest eleganckie bo wszystkie wystapienia tych wyrazeni byly zamieniane nawet jesli ktos nie mial zlych intencji ale sa one bardzo zadko uzywane w naszym slownictwie a dodanie np. twardej spacji praktycznie niczego nie zmienia w wygladzie takiego komentarza, posta etc.

Napisany przez: johnson 6.12.2004, 09:23:12

Cytat(Kinool @ 2004-11-25 07:48:38)
to co ma byc stringiem dodawac slashe (addslashes)

nie rozumiem dlaczego wszyscy piszą o addslashes, przecież php automatycznie dodaje slashe do wszystkich zmiennych $_GET i $_POST i włamanie opisane przez Najki
  1. <?php
  2. ', haslo='nowe_haslo' WHERE id = '1

nie ma prawa zadziałać.

Czy mógłby ktoś wyjaśnić mi tą sytuację?

Napisany przez: Najki 6.12.2004, 09:29:56

Owszem dodaje, ale chyba tylko, gdy na serwerze jest włączone magic_quotes_gpc ?
A jeśli nie to jakim prawem kolega mi się włamał? snitch.gif

Napisany przez: Seth 6.12.2004, 12:32:14

Dodam jeszcze te dwa linki:
http://www.nextgenss.com/papers/SecondOrderCodeInjection.pdf
http://hacking.pl/download.php?file=get&id=113

Napisany przez: morrison 26.02.2005, 17:20:37

Temat ciekawy, ale w zasadzie nie wiem jeszcze co moglbym zrobic w swojej aplikacji aby uniemozliwic taki atak i aby bylo to zrobione w profesjonalny sposob. Gdyby ktos mogl zerknac na kod i pomoc mi.
Oto kod ktory sluzy do sprawdzenia hasla i nazwy usera:

  1. <?php
  2.  
  3. // utworzenie krotkich nazw zmiennych i spr. czy dane sa przek. w zm. sesji
  4. if (!http://www.php.net/isset($_SESSION['nazwa_uz']))
  5. $_SESSION['nazwa_uz'] = $HTTP_POST_VARS['nazwa_uz'];
  6. if (!http://www.php.net/isset($_SESSION['haslo']))
  7. $_SESSION['haslo'] = $HTTP_POST_VARS['haslo'];
  8.  
  9. //spr. czy zostalo nadane nowe haslo
  10. if (http://www.php.net/isset($_SESSION['nowe_haslo']))
  11. $_SESSION['haslo'] = $_SESSION['nowe_haslo'];
  12.  
  13. if (($_SESSION['nazwa_uz'] && $_SESSION['haslo']) || ($_SESSION['nazwa_uz'] == '' || $_SESSION['haslo'] == ''))
  14. // proba logowania, sprawdzenie czy podano login oraz haslo
  15. {
  16. if (loguj($_SESSION['nazwa_uz'], $_SESSION['haslo']))
  17. {
  18. // jesli uzytkownik znajduje sie w bazie danych rejestracja identyfikatora
  19. $HTTP_SESSION_VARS['prawid_uzyt'] = $_SESSION['nazwa_uz'];
  20.  
  21.  
  22. }
  23. else
  24.  
  25. ?>


a to kod funkcji wykonujacej to sprawdzenie:
  1. <?php
  2.  
  3. function loguj($nazwa_uz, $haslo)
  4. // sprawdzenie nazwy uzytkownika i hasla w bazie danych
  5. // jezeli sie �zgadza, zwraca true
  6. // jezeli nie, zwraca false
  7. {
  8. // polaczenie z baza danych
  9. $lacz = lacz_bd();
  10. if (!$lacz)
  11. return false;
  12.  
  13. // sprawdzenie unikatowosci nazwy uzytkownika
  14. $wynik = http://www.php.net/mysql_query(&#092;"select * from uzytkownik 
  15.  where nazwa_uz='$nazwa_uz'
  16.  and haslo = password('$haslo')&#092;");
  17. if (!$wynik)
  18.  return false;
  19.  
  20. if (http://www.php.net/mysql_num_rows($wynik) > 0)
  21.  return true;
  22. else 
  23.  return false;
  24. }
  25.  
  26. ?>

Chcialbym uniknac mozliwosci wlamania, poprzez wpisanie kodu SQL do pola haslo i uzytkownik:)

Napisany przez: ActivePlayer 26.02.2005, 21:45:06

przyklad:

  1. <?php
  2.  
  3. $sql = http://www.php.net/mysql_query(&#092;"SELECT * FROM news WHERE id=\".$_GET['id']);
  4.  
  5. ?>


wywołanie normalne:
Kod
news.php?id=1
news.php?id=25
itd


wywołanie zmodyfikowane przez kogostam
np.
Kod
news.php?id=1;DROP%20TABLE%20news;


zabezpieczenie? ja znalazlem pare...

1. dodanie id2

  1. <?php
  2.  
  3. if(http://www.php.net/md5($_GET['id']*4)!=$_GET['id2'])http://www.php.net/die('Błędny url');
  4.  
  5. ?>


2. wymuszenie typu

  1. <?php
  2.  
  3. $id = (int)$_GET['id'];
  4.  
  5. ?>


3. mysql_escape_string

  1. <?php
  2.  
  3. $id = http://www.php.net/mysql_escape_string($_GET['id']);
  4.  
  5. ?>


ale mam wrazenie ze to dalej nie o to biega... z tych 3 które przedstawilem to pierwsze wydaje mi sie być najrozsądniejsze...

Napisany przez: sopel 26.02.2005, 23:41:07

Cytat(ActivePlayer @ 2005-02-26 21:45:06)
ale mam wrazenie ze to dalej nie o to biega... z tych 3 które przedstawilem to pierwsze wydaje mi sie być najrozsądniejsze...

osobiscie uwazam ze dosc dobrym rozwiazaniem jest odpowiednie zarządzanie uprawnieniami, np. stworzyc konto dla www, gdzie moga byc tylko SELECT, INSERT, UPDATE, ewentualnei DELETE

druga sprawa, czy probowales w praktyce wykonac przedstawione przez ciebie polecenie? standardowo (nie jestem pewny czy da sie to przestawic tak zeby bylo inaczej) przez mysql_querynie wykonasz dwóch zapytań

Napisany przez: Vengeance 27.02.2005, 14:44:07

przez mysql_query() nie. ale funckje postgreSQL już to dopuszczają :/
Dlatego userzy tego drugiego mają większy problem.

Co do zabezpieczenia, nie wiem czym się tak przejmujecie? ;]
Ja stosuje jedynie addslashes() oraz usuwam slowo 'UNION' ze zmiennych

Napisany przez: Riklaunim 27.02.2005, 14:49:14

dość często jest WHERE coś = liczba gdzie coś jest polem auto_increment i ma wartości liczbowe.. wystarczy przed wykonaniem zapytania sprawdzić czy is_numeric parametr dla Where

Napisany przez: MoD 27.02.2005, 17:45:48

Ja do liczb stosuje najczęściej http://pl.php.net/ereg (zwłaszcza w UPDATE, w grze MMORPG). Wtedy mam pewność że osoba która wpisze np -1230 nie wyrządzi mi żadnych szkód. A zabezpieczanie skryptów można trenować na wspomnianym przeze mnie wyżej ExoFusion. Jak ktoś go tak zabezpieczy, że nie będzie żadnych (no, może nie żadnych, a prawie żadnych) błędów to będzie się miał czym pochwalić (ja znałem 2 gry na 10 które były w miarę zabezpieczone, ale i tak padły - właśnie przez SQL Injection)

Napisany przez: MStaniszczak 28.02.2005, 03:21:48

Cytat
Ja do liczb stosuje najczęściej ereg (zwłaszcza w UPDATE, w grze MMORPG). Wtedy mam pewność że osoba która wpisze np -1230 nie wyrządzi mi żadnych szkód. A zabezpieczanie skryptów można trenować na wspomnianym przeze mnie wyżej ExoFusion. Jak ktoś go tak zabezpieczy, że nie będzie żadnych (no, może nie żadnych, a prawie żadnych) błędów to będzie się miał czym pochwalić (ja znałem 2 gry na 10 które były w miarę zabezpieczone, ale i tak padły - właśnie przez SQL Injection)


Hmmm.... wykonanie ereg zajmuje nieco czasu (jak to wyrażeń regularnych). Chyba jednak lepiej się nieco przyłożyć i pobawić kombinacją is_numeric(), is_integer(), intval() i warunkami. Chyba każdy wie jakiego mniej więcej zakresu się spodziewa? Jak nie chcesz liczb ujemnych to po porostu wycinasz je warunkiem i już…
Po co z armatą na muchy;-)

Pozdrawiam
Marcin Staniszczak

Napisany przez: Vengeance 1.03.2005, 17:20:41

@MStaniszczak: podobnież "is_numeric(), is_integer(), intval()" nie są zawsze dobrym wyjściem. Gdzieś czytałem, iż Zend Engine działa tak, iż te funkcje sprawdzają tylko typ zmiennej. Może to doprowadzać do przekłamań, dlatego niektórzy właśnie stosują eregi (co w tamtym artykule także polecano).

Napisany przez: MStaniszczak 1.03.2005, 23:15:12

@Vengeance:
Więc działa to tak:
is_numeric() - sprawdza czy cos co podałeś jako argument jest cyfrą. Dokładniej czy nie ważne czy cyfra jest stringiem ('123') czy cyfrą (123) czy cyfrą ułamkową (123.123). Jeśli jest cyfrą zwraca true;

is_integer() - zwraca true TYLKO wtedy gdy parametr:
a) jest cyfra
b) jest typu integer (czyli dla '123' nie zwróci true)
c) jest cyfrą CAŁKOWITĄ (czyli dla 123.123 nei zwróci true).
WSZYSTKIE te punkty muszą być spełnione jednocześnie

intval() - nic nie sprawdza... Zamienia parametr na integera (jesli zaczyna się od cyfry). Czyli:

  1. <?php
  2. $i = http://www.php.net/intval('123')
  3. ?>

powoduje przepisanie do $i wartości 123 typu INTEGER.
  1. <?php
  2. $i = http://www.php.net/intval('123 ala ma kota')
  3. ?>

działa podobnie - w $i otrzymujemy INTEGER-a o wartości 123.
Dodatkowo intval() ignoruje początkowe białe znaki i oczywiście poprawnie obsługuję znaki +/- przed cyfrą.
W przypadku niepoprawnego parametru podanego do intval:
  1. <?php
  2. $i = http://www.php.net/intval('ala ma kota');
  3. ?>

zwraca 0 (czyli w przykładzie $i otrzymuje wartość 0).

I NIE MA ODSTPSTW OD TYCH REGÓŁ.
Zamieszanie może powstać gdy się nie wie jak te funkcje działają (jest ich więcej - to tylko 3 z całej grupy). Ale to tak jak z operatorami...
Zobacz co da w wyniku:
  1. <?php
  2. $ret = '123 ala'+'123ma kota';
  3. http://www.php.net/echo $ret;
  4. ?>


Pozdrawiam
Marcin Staniszczak

Napisany przez: Vengeance 2.03.2005, 22:22:51

@MStaniszczak: ja tam nie wiem smile.gif Mówie tylko co czytałem. Skoro ktoś to dostrzegł w kodzie Zend Engine (może go analizowałeś, ja nie) to miał jakieś powody by tak twierdzić smile.gif Może już to poprawili albo coś. Przytaczam tylko swoją "wiedzę" na ten temat, choc sam także używam is_integer() itp.

Napisany przez: MStaniszczak 2.03.2005, 22:43:20

@Vengeance: Ano analizowałem Zend Engina dość dokładnie (jeszcze raz mnie to czeka).
Oto funkcja odpowiedzialna za is_numeric (która nie jest częścią Zend Engine-u):

Kod
PHP_FUNCTION(is_numeric)
{
    zval **arg;
    int result;

    if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
  WRONG_PARAM_COUNT;
    }

    switch (Z_TYPE_PP(arg)) {
  case IS_LONG:
  case IS_DOUBLE:
     RETURN_TRUE;
     break;

  case IS_STRING:
     result = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), NULL, NULL, 0);
     if (result == IS_LONG || result == IS_DOUBLE) {
    RETURN_TRUE;
     } else {
    RETURN_FALSE;
     }
     break;

  default:
     RETURN_FALSE;
     break;
    }
}


A to np. is_string:
Kod
PHP_FUNCTION(is_string)
{
    php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_STRING);
}

do tego php_is_type:
Kod
static void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type)
{
    pval **arg;

    if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only one argument expected");
  RETURN_FALSE;
    }

    if (Z_TYPE_PP(arg) == type) {
  if (type == IS_OBJECT) {
     zend_class_entry *ce;
     ce = Z_OBJCE_PP(arg);
     if (!strcmp(ce->name, INCOMPLETE_CLASS)) {
    RETURN_FALSE;
     }
  }
  if (type == IS_RESOURCE) {
     char *type_name;
     type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);
     if (!type_name) {
    RETURN_FALSE;
     }
  }
  RETURN_TRUE;
    } else {
  RETURN_FALSE;
    }
}


A is_integer, is_double, is_real ma jeszcze ładniejszą postać (sam sprawdź). To nie może działać źle - używaj bez obaw;-)

Pozdrawiam
Marcin Staniszczak

Napisany przez: krzemian 3.03.2005, 17:09:35

W PHPBB też jest coś takiego używane, ale - znowu - nie prościej użyć rzutowania typów? Ostatnio zrobiłem coś takiego na zmiennej $id z GET'a i nawet jeśli dałem id=3fk5 to jeśli zrzutowałem to na (int) otrzymywałem 35. Chyba o to wam chodzi, nie?

Napisany przez: Seth 3.03.2005, 18:08:48

To o czym piszesz sprawdza sie przy liczbach, natomiast do ciagow znakow trzeba juz inaczej do tego podchodzic.

Napisany przez: MStaniszczak 3.03.2005, 20:40:59

@krzemian:

Cytat
Ostatnio zrobiłem coś takiego na zmiennej $id z GET'a i nawet jeśli dałem id=3fk5 to jeśli zrzutowałem to na (int) otrzymywałem 35. Chyba o to wam chodzi, nie?


Ciekawe co piszesz - sprawdź co zwróci skrypt...
  1. <?php
  2. $x = '3fk5';
  3. $a = (int)'3fk5';
  4. $b = (int)$x;
  5.  
  6. http://www.php.net/echo $a.'<br>'.$b;
  7. ?>


A teraz popróbuj:

  1. <?php
  2. $a = '1abc';
  3. $b = '2ii';
  4. $d = '-3ala ma kota a kot ma ale';
  5.  
  6. $ret = $a+$b;
  7. http://www.php.net/echo $ret.'<br>';
  8.  
  9. $ret += $d;
  10. http://www.php.net/echo $ret.'<br>';
  11.  
  12. $ret = $b*$d;
  13. http://www.php.net/echo $ret.'<br>';
  14.  
  15. ?>


Pozdrawiam
Marcin Staniszczak

Napisany przez: ActivePlayer 3.03.2005, 21:23:10

Moze ktos napisze klase, lub zbiór funkcji, alby uniknąc tego typu problemów, tylko ze... tu problem nie polega na tym, co zrobic zeby sprawdzic jaki typ danych user wpisze, tylko raczej na tym jak mądrze napisac zapytanie.

Napisany przez: MStaniszczak 3.03.2005, 23:18:12

Ja używam czegoś takiego (ma już swoje latka - dodałem tylko public;-):

  1. <?php
  2. require_once(ROOT_PATH.'Libraries/Tools/email.inc.php');
  3.  
  4. http://www.php.net/define('VALIDATE_EMAIL', 1);
  5. http://www.php.net/define('VALIDATE_STRING', 2);
  6. http://www.php.net/define('VALIDATE_INTEGER', 3);
  7. http://www.php.net/define('VALIDATE_DOUBLE', 4);
  8. http://www.php.net/define('VALIDATE_POSTCODE', 5);
  9. http://www.php.net/define('VALIDATE_BOOLEAN', 6);
  10.  
  11. class Validate {
  12. private function checkStrSize($value, $minSize, $maxSize) {
  13. if(http://www.php.net/strlen(http://www.php.net/trim($value))>$maxSize || http://www.php.net/strlen(http://www.php.net/trim($value))<$minSize)
  14. return false;
  15. else
  16. return true;
  17. }
  18.  
  19. //array( array('typ', 'value', 'min', 'max', 'correct')
  20. public function check($array) {
  21. $ret = http://www.php.net/array(true, $array);
  22.  
  23. $count = http://www.php.net/count($array);
  24. for($i=0; $i<$count; $i++) {
  25. switch($array[$i][0]) {
  26. case VALIDATE_EMAIL: // e-mail
  27. if(!tverifyEmail($array[$i][1])) {
  28. $ret[0] = false;
  29. $ret[1][$i][4] = false;
  30. } else
  31. $ret[1][$i][4] = true;
  32. break;
  33. case VALIDATE_STRING: // string
  34. if(!$this->checkStrSize($array[$i][1], $array[$i][2], $array[$i][3])) {
  35. $ret[0] = false;
  36. $ret[1][$i][4] = false;
  37. } else
  38. $ret[1][$i][4] = true;
  39. break;
  40. case VALIDATE_INTEGER: //integer
  41. if(!http://www.php.net/is_numeric($array[$i][1]) || 
  42. (http://www.php.net/strpos($array[$i][1], ',')!==false) || (http://www.php.net/strpos($array[$i][1], '.')!==false) ||
  43. $array[$i][1]<$array[$i][2] || $array[$i][1]>$array[$i][3]) {
  44. $ret[0] = false;
  45. $ret[1][$i][4] = false;
  46. } else
  47. $ret[1][$i][4] = true;
  48. break;
  49. case VALIDATE_DOUBLE: // double
  50. if(!http://www.php.net/is_numeric($array[$i][1]) || $array[$i][1]<$array[$i][2] || $array[$i][1]>$array[$i][3]) {
  51. $ret[0] = false;
  52. $ret[1][$i][4] = false;
  53. } else
  54. $ret[1][$i][4] = true;
  55. break;
  56. case VALIDATE_POSTCODE:
  57. if(!@http://www.php.net/ereg('^[0-9]{2}-[0-9]{3}$', $array[$i][1])) {
  58. $ret[0] = false;
  59. $ret[1][$i][4] = false;
  60. } else
  61. $ret[1][$i][4] = true;
  62. break;
  63. case VALIDATE_BOOLEAN:
  64. if(!http://www.php.net/is_bool($array[$i][1])) {
  65. $ret[0] = false;
  66. $ret[1][$i][4] = false;
  67. } else
  68. $ret[1][$i][4] = true;
  69. break;
  70. }
  71. }
  72.  
  73. return $ret;
  74. }
  75. }
  76. ?>


A plik email.inc.php:
  1. <?php
  2. if (http://www.php.net/strtoupper(http://www.php.net/substr(PHP_OS, 0, 3)) === 'WIN')
  3. $OS_detect = 'Windows NT';
  4. else
  5. $OS_detect = 'Unix';
  6.  
  7. function checkdnsrrWinNT($host, $type = '') {
  8. if(!http://www.php.net/empty($host)) {
  9.  
  10. if($type=='')
  11. $type = 'MX';
  12.  
  13. @http://www.php.net/exec(&#092;"nslookup -type=$type $host\", $output);
  14.  
  15. while(list($k, $line)=http://www.php.net/each($output)) {
  16. if(http://www.php.net/eregi( &#092;"^$host\", $line)) {
  17. return true;
  18. }
  19. }
  20. return false;
  21. }
  22. }
  23.  
  24.  
  25. function multiOScheckdnsrr($host, $type='') {
  26. http://www.php.net/global $OS_detect;
  27.  
  28. if(http://www.php.net/strcmp($OS_detect,'Windows NT')===0)
  29. return checkdnsrrWinNT($host, $type);
  30. else
  31. if(http://www.php.net/strcmp($OS_detect, 'Unix')===0) {
  32. if(http://www.php.net/strcmp($type, '')===|| http://www.php.net/strcmp($type, 'MX')===0)
  33. return checkdnsrr($host, MX);
  34. elseif(http://www.php.net/strcmp($type, 'A')===0)
  35. return checkdnsrr($host, A);
  36. elseif(http://www.php.net/strcmp($type, 'NS')===0)
  37. return checkdnsrr($host, NS);
  38. elseif(http://www.php.net/strcmp($type, 'SOA')===0)
  39. return checkdnsrr($host, SOA);
  40. elseif(http://www.php.net/strcmp($type, 'PTR')===0)
  41. return checkdnsrr($host, PTR);
  42. elseif(http://www.php.net/strcmp($type, 'CNAME')===0)
  43. return checkdnsrr($host, CNAME);
  44. elseif(http://www.php.net/strcmp($type, 'AAAA')===0)
  45. return checkdnsrr($host, AAAA);
  46. elseif(http://www.php.net/strcmp($type, 'ANY')===0)
  47. return checkdnsrr($host, ANY);
  48. }
  49. }
  50.  
  51. function verifyEmail($email) {
  52. $wholeexp = '/^(.+?)@(([a-z0-9.-]+?).[a-z]{2,5})$/i';
  53. $userexp = &#092;"/^[a-z0-9~!#$%&()-_+=[];:'\",./]+$/i\";
  54. if(http://www.php.net/preg_match($wholeexp, $email, $regs)) {
  55. $username = $regs[1];
  56. $host = $regs[2];
  57. if(multiOScheckdnsrr($host, 'MX')) {
  58. if(http://www.php.net/preg_match($userexp, $username)) {
  59. return true;
  60.  }else {
  61.  return false;
  62.  }
  63.  }else {
  64.  return false;
  65.  }
  66. }else {
  67. return false;
  68. }
  69. }
  70. ?>


Dalej validuje już w odpowiednich funkcjach - inaczej chyba ciężko;-)

Pozdrawiam
Marcin Staniszczak

Napisany przez: docent 4.03.2005, 00:18:29

no to i moje 3 grosze. primo: nie ma to jak szczyt lenistwa:

Kod
foreach($_REQUEST as $key => $item) $$key = addslashes($item);


mam nadzieje, ze sie podoba tongue.gif oczywiscie nie wszedzie uzyteczne, niekoniecznie optymalne i nie zawsze dzialamy tylko na $_REQUEST. ale mniej wiecej juz znacie geneze smile.gif mozliwe modyfikacje oczywiscie:

Kod
foreach($_POST as $key => $item) $_POST[$key] = addslashes($item);


itd... smile.gif zamiast addslashes mozna dac intvalue, albo i obydwa.. jesli nie frunie duzo danych to i tak nie bedzie roznicy w czasie wykonywania skryptu - a nie trzeba z dokladnoscia ksiegowego sprawdzac czy o czyms (czyt. ktorejs zmiennej) nie zapomnielismy

pierwsza metoda (dla nei wiedzacych) symuluje niejako Register Globals na On, czyli zamiast odwolywac sie do strval($_REQUEST['zmienna']) mozemy po wykonaniu tamtego odwolac sie po prostu do $zmienna, ktora juz jest sparsowana pod kategm 'nieporzadanej' zawartosci

EDIT:

dziala oczywiscie i w druga strone. jesli do $rekord zczytamy sobie jakies dane z bazy danych to mozna sobie leniwie wrzucic:

Kod
foreach($rekord as $key => $item) $rekord[$key] = stripslashes($item);


tylko nalezy pamietac, aby czytac dane za pomcoa mysql_fetch_assoc lub row - nie mysql_fetch_array, gdyz wtedy mamy podwojne klucze w tablicy i wiadomo co sie stanie smile.gif

Napisany przez: Vengeance 4.03.2005, 19:04:20

@docent: szczerze to zadna nowosc snitch.gif

----
Przez chwilke pomyslalem, ze mozna by zmienne przekazyawc przez:
www.site.com?int[postID]=4&string[mode]=showAll&bool[save]=true

I robic odpowiednie petle na tablicach, stosujac odpowiednie funkcje smile.gif

Napisany przez: MStaniszczak 4.03.2005, 19:08:24

Cytat
Przez chwilke pomyslalem, ze mozna by zmienne przekazyawc przez:
www.site.com?int[postID]=4&string[mode]=showAll&bool[save]=true

I robic odpowiednie petle na tablicach, stosujac odpowiednie funkcje smile.gif


I otrzymali byśmy w GET coś takiego:-) Więc bardzo miło;-)

Kod
Array
(
    [int] => Array
        (
            [postID] => 4
        )

    [string] => Array
        (
            [mode] => showAll
        )

    [bool] => Array
        (
            [save] => true
        )

)


Pozdrawiam
Marcin Staniszczak

Napisany przez: docent 4.03.2005, 23:48:57

Cytat(Vengeance @ 2005-03-04 20:04:20)
@docent: szczerze to zadna nowosc snitch.gif

----
Przez chwilke pomyslalem, ze mozna by zmienne przekazyawc przez:
www.site.com?int[postID]=4&string[mode]=showAll&bool[save]=true

I robic odpowiednie petle na tablicach, stosujac odpowiednie funkcje smile.gif

heihei ja nie mowie, ze nowowsc - ale informacja dla tych, ktorzy nie znaja smile.gif a istotnie - jest pomocna :] bardziej mnie interesowalo zdanie innych na ten temat - sposob w zasadzie sam sobie stwrozylem (choc pewnie kazdy na to wpadl we wlasnym zakresie) i interesowalo mnie tylko zdanie innych w tej kwestii smile.gif

Napisany przez: tara 2.04.2005, 17:32:31

w sumei można też tak, np. dla newsów:

  1. <?php
  2.  
  3. if(http://www.php.net/isset($_GET['id'])) {
  4.   $query1 = &#092;"SELECT MAX(ID) FROM newsy\";
  5. list($d) = http://www.php.net/mysql_fetch_row(http://www.php.net/mysql_query ($query1));
  6.  
  7. if ($_GET['id']> $d) {
  8. http://www.php.net/print &#092;"Blad\";
  9. } else {
  10.  
  11. // kod 
  12.  
  13. }
  14. }
  15.  
  16. ?>


To blokuje wysiwetlanie newsa np. 9999 jak i tekstu. w zmiennej id.

Napisany przez: limak 11.04.2005, 21:05:08

Cytat
To blokuje wysiwetlanie newsa np. 9999 jak i tekstu. w zmiennej id.
no dobra, ale to niewiele ma do zabiezpieczenia przed SQL Injection...
akurat wyswietlenie newsa nr 99999 nie wprowadza zadej nowej mozliwosci ataku....

wracając do tematu....

http://www.phpsolmag.org/pl/modules/wmpdownloads/visit.php?cid=1&lid=6

tutaj jest darmowy artykuł z magazynu php solutions

Napisany przez: tara 11.04.2005, 21:06:48

heh no ale jak ktoś wprawdzi DROP TABLE itp. to też zablokuje winksmiley.jpg

Napisany przez: MoD 11.04.2005, 21:33:24

Cytat(MStaniszczak @ 2005-02-28 04:21:48)
Hmmm.... wykonanie ereg zajmuje nieco czasu (jak to wyrażeń regularnych). [...]

Szczerze mówiąc, to wolę stracić tą sekundę w czasie wykonywania skryptu niż stracić na bezpieczeństwie. I mniejszy bałagan w kodzie - jedna funkcja zamiast szeregu IF. A wyrażenie regularne można w razie czego łatwo zmodyfikować jeśli się znajdzie błąd.

Napisany przez: tarlandil 29.04.2005, 07:47:36

IMHO dosc wygodna i bezpieczne rozwiazanie:

  1. <?php
  2.  
  3. function CheckValue($type,$v,$default=&#092;"\")
  4. {
  5. if (!function_exists(&#092;"CheckValue_$type\")) return \"\";
  6. $func=&#092;"CheckValue_$type\";
  7. return $func($v,$default);
  8. }
  9.  
  10. function SQLValue($type,$v,$default=&#092;"\")
  11. {
  12. if (!function_exists(&#092;"SQLValue_$type\")) return \"\";
  13. $func=&#092;"SQLValue_$type\";
  14. return $func($v,$default);
  15. }
  16. ?>


a potem definiujemy swoje funckje sprawdzajace
  1. <?php
  2.  
  3. function CheckValue_int($v,$default=&#092;"\")
  4. {
  5. if (!http://www.php.net/is_numeric($v)) return (int)$default;
  6. return (int) $v;
  7. }
  8.  
  9. function SQLValue_int($v,$default=&#092;"\")
  10. {
  11. return CheckValue_int($v,$default);
  12. }
  13.  
  14. function CheckValue_ident($v,$default=&#092;"\")
  15. {
  16. $v=http://www.php.net/trim($v);
  17. if (!http://www.php.net/preg_match(&#092;"/^([wd]+)$/\",$v)) return $default;
  18. return $v;
  19. }
  20.  
  21. function SQLValue_ident($v,$default=&#092;"\")
  22. {
  23. $v=CheckValue_ident($v,$default);
  24. $v=http://www.php.net/addslashes($v);
  25. return &#092;"'$v'\";
  26. }
  27.  
  28. function CheckValue_text($v,$default=&#092;"\")
  29. {
  30. $v=http://www.php.net/trim($v);
  31. $v=http://www.php.net/htmlspecialchars($v,ENT_QUOTES);
  32. return $v;
  33. }
  34.  
  35. function SQLValue_text($v,$default=&#092;"\")
  36. {
  37. $v=CheckValue_text($v,$default);
  38. $v=http://www.php.net/addslashes($v);
  39. return &#092;"'$v'\";
  40. }
  41.  
  42. itd..
  43.  
  44. ?>


a wykoanie zapytania np tak:
  1. <?php
  2.  
  3. $result=$sql->SendQuery(http://www.php.net/sprintf(
  4. &#092;"select * from przedmiot where id=%s and parent=%s;\",
  5. SQLValue(&#092;"ident\",$GLOBALS[\"id\"]),
  6. SQLValue(&#092;"ident\",$GLOBALS[\"parent\"])
  7. ));
  8.  
  9. ?>


I w ten sposob nawet przy braku magic quotes czy tez mozliwosci wielu zapytan w jednemy poleceniu, nikt nie przepcha zadnego zlosliwego kodu.

Napisany przez: J4r0d 8.05.2005, 17:11:33

Cytat(Vengeance @ 2005-02-27 13:44:07)
przez mysql_query() nie. ale funckje postgreSQL już to dopuszczają :/
Dlatego userzy tego drugiego mają większy problem.

Co do zabezpieczenia, nie wiem czym się tak przejmujecie? ;]
Ja stosuje jedynie addslashes() oraz usuwam slowo 'UNION' ze zmiennych

Cytat
przez mysql_query() nie. ale funckje postgreSQL już to dopuszczają :/
Dlatego userzy tego drugiego mają większy problem.

A jak go rozwiązać?
Cytat
Co do zabezpieczenia, nie wiem czym się tak przejmujecie? ;]
Ja stosuje jedynie addslashes() oraz usuwam slowo 'UNION' ze zmiennych

Przecież addslashes() to tosamo co mysql_escape_string() worriedsmiley.gif

Napisany przez: sopel 8.05.2005, 17:35:35

Cytat(J4r0d @ 2005-05-08 17:11:33)
Cytat(Vengeance @ 2005-02-27 13:44:07)
przez mysql_query() nie. ale funckje postgreSQL już to dopuszczają :/
Dlatego userzy tego drugiego mają większy problem.

Co do zabezpieczenia, nie wiem czym się tak przejmujecie? ;]
Ja stosuje jedynie addslashes() oraz usuwam slowo 'UNION' ze zmiennych

Cytat
przez mysql_query() nie. ale funckje postgreSQL już to dopuszczają :/
Dlatego userzy tego drugiego mają większy problem.

A jak go rozwiązać?
Cytat
Co do zabezpieczenia, nie wiem czym się tak przejmujecie? ;]
Ja stosuje jedynie addslashes() oraz usuwam slowo 'UNION' ze zmiennych

Przecież addslashes() to tosamo co mysql_escape_string() worriedsmiley.gif

1. np. mozna przefiltrowac ciag wyrzucajac wszelkie sredniki

2. funkcja nie sa sobie rownoznaczne

mysql_real_escape_string() calls MySQL's library function mysql_escape_string, which prepends backslashes to the following characters: NULL, \x00, \n, \r, \, ', " and \x1a.

addslashes() : Returns a string with backslashes before characters that need to be quoted in database queries etc. These characters are single quote ('), double quote ("), backslash (\) and NUL (the NULL byte).

Napisany przez: johnson 8.05.2005, 17:46:29

Cytat(J4r0d @ 2005-05-08 16:40:02)
Więc, które rozwiązanie bezpieczniejsze? Stosować addslashes() ?

Nie rozumiem o co Wam chodzi z tym addslashes().
Czy chodzi o podwójne stosowanie addslashes()?
Raz przecież robi to samo php. Otrzymując dane z formularzy dostajemy postać:
To jest \"smaczny deser\"
Czy trzeba to jeszcze raz potraktować addslashes() i otrzymać:
To jest \\\"smaczny deser\\\"
i dopiero wtedy wrzucać do bazy? Już od dawna mnie frapuje ten problem smile.gif czy może ktoś to wyjaśnić?

Napisany przez: sopel 8.05.2005, 17:48:08

addslashes() (jeden raz!!!) powinno w zupelnosci wystarczyc. przy sotsowaniu mysql_escape_string moze sie pojawic porblem przy wyciganiu danych z bazy i stosowaniu stripslashes()

Napisany przez: Peter Riley 8.05.2005, 17:49:40

Smieszne sa te wasze rozwazania, nie szkoda czasu?
Przypomina mi to wiare w zabobony.
Addslashes zalatwia calkowice sprawe, sprobujcie sie wlamac bez mozliwosci uzycia apostrofu. Mozecie wpisywac UNION, srednik i co tylko chcecie, ale to nic nie da, bo i tak co najwyzej zostanie wciagniete do bazy jako czesc stringa.
Do liczb is_numeric i wystarczy.

Napisany przez: J4r0d 8.05.2005, 17:56:50

Cytat
Nie rozumiem o co Wam chodzi z tym addslashes().
Czy chodzi o podwójne stosowanie addslashes()?


Chodzi o to, że slash dodawany jest jeżeli włączona jest jakaś opcja (już nie pamiętam o jaką chodziło - szukaj na pierwszej stronie tego topicu).
A jak dodadsz addslashes() to nawet jak dodawanie slasha jest wyłączone to ty massz pewność.

Cytat
Smieszne sa te wasze rozwazania, nie szkoda czasu?
Przypomina mi to wiare w zabobony.

Bezpieczeństwo - szkoda czasu? worriedsmiley.gif Nie dla mnie :roll2:
Cytat
Addslashes zalatwia calkowice sprawe, sprobujcie sie wlamac bez mozliwosci uzycia apostrofu. Mozecie wpisywac UNION, srednik i co tylko chcecie, ale to nic nie da, bo i tak co najwyzej zostanie wciagniete do bazy jako czesc stringa.
Do liczb is_numeric i wystarczy.

Skoro tak mówisz to będę tak robił. Jaby co to wiemy do kogo z pretensjami tongue.gif

Dziękuje za odpowiedź i pozdrawiam

Napisany przez: Peter Riley 8.05.2005, 18:43:03

Cytat(J4r0d @ 2005-05-08 16:56:50)
Bezpieczeństwo - szkoda czasu?  worriedsmiley.gif  Nie dla mnie :roll2:

A co z bezpieczenstwem ma wspolnego kasowanie ciagow typu UNION ze zmiennej, w ktorej i tak kazdy apostrof zostanie wysleszowany? Nic.
addslash lub magic quote zalatwia calkowicie sprawe sql injection, oczywiscie pozostaje sprawdzenie czy nadeslane dane mieszcza sie w dozwolonym zakresie, ale to juz inna historia.

Napisany przez: J4r0d 8.05.2005, 19:08:08

Cytat(Peter Riley @ 2005-05-08 17:43:03)
oczywiscie pozostaje sprawdzenie czy nadeslane dane mieszcza sie w dozwolonym zakresie, ale to juz inna historia.

Możesz rozwinąć?

Napisany przez: Peter Riley 8.05.2005, 19:47:55

Cytat(J4r0d @ 2005-05-08 18:08:08)
Cytat(Peter Riley @ 2005-05-08 17:43:03)
oczywiscie pozostaje sprawdzenie czy nadeslane dane mieszcza sie w dozwolonym zakresie, ale to juz inna historia.

Możesz rozwinąć?

Po prostu musimy sprawdzic, czy przeslane wartosci maja odpowiedni przedzial, czyli np. wpisana ilosc sztuk nie przekracza stanu magazynu. W przypadku wartosci tekstowych mozna porownac wyszukac ciagu w zadeklarowanej wczesniej tablicy lub uzyc switch of. Jednak to wszystko nie ma nic wspolnego ze sql injection, przed ktorym pelna obrone zapewnia defaultowa konfguracja php, a jesli wylaczymy magic quote, pozostanie addslashes.

Napisany przez: sopel 8.05.2005, 22:14:33

Cytat(Peter Riley @ 2005-05-08 18:43:03)
addslash lub magic quote zalatwia calkowicie sprawe sql injection

smiem twierdzic ze jest to zbyt odwazne stwierdzenie. wyobraz sobie taka sytuace :

URL: www.strona.php?articleid=12
filtrujemy: $id = addslashes($_GET['articleid'])
wstawiamy w zapytanie : query = 'SELECT * FROM articles WHERE id='.$id;

i teraz np. URL www.strona.php?articleid=12 OR 1

jak widzisz w tym przykladzie (co prawda dosc naiwnym) addslashes nie zalatwilo sprawy...

Napisany przez: Kinool 9.05.2005, 00:14:50

panowie!!!!

juz ktos pisal o tym ze wiemy co "spodziewamy" sie otrzymac jesli chodzi o liczby to nie addslashes tylko intval() lub settype()

$id = intval($_GET['articleid']);

i jesli gosc wklepie tam cokolwiek to i tak bedzie zutowane na liczbe
nawet ze wzglegow optymalizacji lepiej jest wykonac zapytanie
SELECT * FROM table WHERE id=10
niz
SELECT * FROM table WHERE id='10'
poniewaz MySQL nie musi robic konwersji

addslashes uzywamy jesli mamy doczynienia z wartosciami textowymi lub mieszanymi

tak na marginesie to zadna funkcja nie zwalnia od myslenia!

Napisany przez: Peter Riley 9.05.2005, 01:28:44

Cytat(sopel @ 2005-05-08 21:14:33)
smiem twierdzic ze jest to zbyt odwazne stwierdzenie.

To chyba oczywiste, ze musimy sprawdzic czy liczby rzeczywiscie sa liczbami, przy okazji sprawdzajac ich zakres. Zreszta pisalem o tym wyzej. Dodam tylko, ze ja sklaniam sie raczej do sprawdzania typu, a nie konwersji na sile. Jesli typ sie nie zgadza, to mail do admina i die().

Nie jest to odwazne stwierdzenie tylko fakt. Zaloze sie, ze ci co usuwaja UNION i sredniki z ciagow, na wszelki wypadek klikaja "zastosuj" w windowsowych okienkach tuz przed kliknieciem "ok" :-)

Napisany przez: ktuvok 14.05.2005, 20:58:57

Dorzucę się do tego wątku i powiem, że moim zdaniem najlepszym zabezpieczeniem jest:

1. ustawienie w php.ini opcji get_magic_quotes_gpc na ON

2. stosowana równolegle z powyższym funkcja czyszcząca otrzymane dane - od razu uprzedzam, że wbrew nazwie nie dotyczy ona tylko danych przesyłanych metodą POST:

  1. <?php
  2.  
  3. function OczyscPost($Zmienna, $Rozmiar)
  4. {
  5. if (http://www.php.net/get_magic_quotes_gpc())
  6. {
  7. $Zmienna = http://www.php.net/stripslashes($Zmienna);
  8. }
  9. $Zmienna = http://www.php.net/trim(http://www.php.net/strip_tags(http://www.php.net/str_replace(&#092;"\"\", \"\", $Zmienna)));
  10. $Zmienna = http://www.php.net/substr(http://www.php.net/str_replace(&#092;"'\",\"\", $Zmienna),0,$Rozmiar);
  11. $Zmienna = http://www.php.net/sprintf(&#092;"%s\",$Zmienna);
  12. return $Zmienna;
  13. }
  14.  
  15. ?>


3. Funkcja zapewniająca dodatkowe filtrowanie dla identyfikatorów, przekazywanych w URL'u:
  1. <?php
  2.  
  3. function DoCyfry($Zmienna)
  4. {
  5. $Zmienna = http://www.php.net/intval($Zmienna);
  6. if(http://www.php.net/is_int($Zmienna))
  7. {
  8. return $Zmienna;
  9. }
  10. else
  11. {
  12. return 0;
  13. }
  14. }
  15.  
  16. ?>


Zastosowanie:
  1. <?php
  2.  
  3. $Nazwisko = OczyscPost($_POST['Nazwisko'], 40);
  4. $ID = DoCyfry(OczyscPost($_GET['ID'], 10));
  5.  
  6. ?>


Jakieś uwagi?

Pozdrawiam,
K

Napisany przez: Vengeance 14.05.2005, 21:44:37

Cytat(Peter Riley @ 2005-05-08 19:43:03)
Cytat(J4r0d @ 2005-05-08 16:56:50)
Bezpieczeństwo - szkoda czasu?  worriedsmiley.gif  Nie dla mnie :roll2:

A co z bezpieczenstwem ma wspolnego kasowanie ciagow typu UNION ze zmiennej, w ktorej i tak kazdy apostrof zostanie wysleszowany? Nic.
addslash lub magic quote zalatwia calkowicie sprawe sql injection, oczywiscie pozostaje sprawdzenie czy nadeslane dane mieszcza sie w dozwolonym zakresie, ale to juz inna historia.

Hyh... kompletnie się z Tobą nie zgodzę :]

Union da się wiele razy wykorzystać nie stosując nawet jednego apostrofu!
Więc samo używanie addslashes() w przypadku posiadania MySQL 4 nie jest bezpieczne !

Napisany przez: bolas 16.05.2005, 23:02:57

a takie pytanko jeszcze.
czy umozliwienie stosowania wszystkich znakow np. spacji przy tworzeniu loginu podczas rejestracji jest niebezpieczne ?

Napisany przez: bolas 18.05.2005, 14:56:35

wszystkie znaki - oczywiscie przy wlaczanej dyrektywie gpc_magic_quotes

ktuvok - uzywam podobnego mechanizmu i na razie nie ma problemow (moze dlatego, ze nikt nie robil testow, albo nie zauwazono, ze cos jest nie tak). dodatkowo uzywam htmlspecialchars.

Napisany przez: kubatron 22.05.2005, 10:18:04

Nie wiem czy był dawany ten link lecz jeśli nie to prosze o usunięcie postu, a takto ciekawy art do przeczytanie http://www.computerworld.pl/artykuly/31505.html

Napisany przez: gu35t 29.06.2005, 19:08:01

mozna sie legalnie sprawdzic:
http://peanix.ath.cx/

wiecej na:
http://forum.cc-team.org/viewtopic.php?t=6488
http://forum.cc-team.org/viewtopic.php?t=6680

sqli[taki bylejaki winksmiley.jpg]:
http://sld.org.pl/index.php?view=1&art_id=6945)%20union%20select%20*%20from%20cms_articles/*&pid=18&ret_id=16&rsid=4

i troche info:
http://www.microsoft.com/poland/technet/article/art008.mspx
http://www.unixwiz.net/techtips/sql-injection.html
http://www.google.pl/search?hl=pl&biw=1019&q=Blind+SQL+Injection&btnG=Szukaj&lr=
http://www.sitepoint.com/article/sql-injection-attacks-safe
http://www.securiteam.com/securityreviews/5DP0N1P76E.html
http://www.google.pl/search?hl=pl&biw=1019&q=sql+injection+paper&btnG=Szukaj&lr=
http://www.google.pl/search?hl=pl&biw=1019&q=sql+injection+faq&btnG=Szukaj&lr=
http://www.google.pl/search?hl=pl&biw=1019&q=sql+injection+howto&btnG=Szukaj&lr=
http://www.google.pl/search?hl=pl&biw=1019&q=sql+injection+getting+names+of+column&btnG=Szukaj&lr=
http://blogs.wdevs.com/colinangusmackay/archive/2004/09/25/652.aspx

troche o union:
http://www.really-fine.com/SQL_union.html

a tak wogule to wszystko na google jest tylko miej troche cierpliowsci i MYSL.

pozdro

Cytat
Union da się wiele razy wykorzystać nie stosując nawet jednego apostrofu!
Więc samo używanie addslashes() w przypadku posiadania MySQL 4 nie jest bezpieczne !

prawda vee smile.gif

Napisany przez: logeen 6.07.2005, 13:03:21

Cytat(Vengeance @ 2005-05-14 20:44:37)
Union da się wiele razy wykorzystać nie stosując nawet jednego apostrofu!
Więc samo używanie addslashes() w przypadku posiadania MySQL 4 nie jest bezpieczne !

Mam w takim razie pytanko: w jaki sposób wykonać SQL Injection w takim skrypcie:
  1. <?php
  2. // Łączenie z serwerem MySQL itd.
  3.  
  4. // Logowanie administratora:
  5. http://www.php.net/mysql_query('SELECT * FROM admins WHERE user_login = '' . (get_magic_quotes_gpc() ? $_POST['login'] : addslashes($_POST['login'])) . '' AND user_password = '' . (get_magic_quotes_gpc() ? $_POST['password'] : addslashes($_POST['password'])) . ''');
  6.  
  7. // Zmiana hasła:
  8. http://www.php.net/mysql_query('UPDATE users SET user_password = '' . (get_magic_quotes_gpc() ? $_POST['password'] : addslashes($_POST['password'])) . '' WHERE user_id = ' . http://www.php.net/abs(http://www.php.net/intval($_GET['user_id'])));
  9.  
  10. // Albo:
  11. http://www.php.net/mysql_query('UPDATE users SET user_password = '' . (get_magic_quotes_gpc() ? $_POST['password'] : addslashes($_POST['password'])) . '' WHERE user_login = '' . (get_magic_quotes_gpc() ? $_GET['login'] : addslashes($_GET['login'])) . ''');
  12.  
  13. // Operacje końcowe: zamykanie połączenia itd.
  14. ?>

Jakoś nie widzę tutaj możliwości wykorzystania UNION poprzez SQL Injection dry.gif

Napisany przez: Vengeance 7.07.2005, 19:53:24

Wiadomym jest, że nie w każdym się da... ale są przypadki gdzie tak jest. Przecież w UNION najczęściej chodzi o wyciągnięcie danych... więc nie musisz używać apostrofu. Gdy ktoś zrobi błąd w takim miejscu, iż użycie apostrofu nie jest wymagane (a najczęściej jest właśnie tylko w dyrektywach WHERE) to droga otwarta.

Napisany przez: johnson 7.07.2005, 20:04:31

Nie zapominajmy, że przy union włamywacz musi znać nazwę tabeli i pól w tabeli mysql, a w przypadku, jeśli ktoś pisze skrypty sam i nie używa gotowców, prawdopodobieństwo, że włamywacz odgadnie nazwę tabeli i pola jest IMHO bardzo małe.

Napisany przez: Vengeance 7.07.2005, 20:07:40

IMHO pokaz mi programiste co nie trzyma loginow i hasel w tabeli nazwą zblizonej do 'users' :]

Pozatym... wywolujac kontrolowane bledy SQL mozna czesto poznac spora czesc struktury bazy SQL.

Ale ogólnie to masz racje snitch.gif

Napisany przez: logeen 7.07.2005, 21:03:48

Cytat(Vengeance @ 2005-07-07 18:53:24)
Gdy ktoś zrobi błąd w takim miejscu, iż użycie apostrofu nie jest wymagane (a najczęściej jest właśnie tylko w dyrektywach WHERE) to droga otwarta.

Tutaj się zgodzę, ale powiedzcie mi w takim razie, po co sztucznie wywalać UNION ze wszystkich danych podstawianych do zapytania, jeżeli można je tak zabezpieczyć, że nigdy nie będzie możliwości wykonania SQL injection (np. tak jak zaprezentowałem powyżej)? Czy to nie jest paranoja? Gdyby programiści IPB byli tak na to wyczuleni, to na tym forum w treści postów w ogóle nie dałoby się wpisać słowa "UNION" i jeszcze kilku innych, a jak widać da się smile.gif

Napisany przez: Vengeance 7.07.2005, 23:35:32

Dlatego, że w takim forum wykonuje się masę zapytań i nie zawsze wszystkie 100% sprawdzisz. Więc lepiej w jednym miejscu filtrować niebezpieczne dane... by potem mieć pewność że do każdego zapytania dotrą w odpowiedniej formie... i że nie zapomnieliśmy gdzieś czegoś filtrować.

Napisany przez: logeen 8.07.2005, 01:01:33

To jasne, ale zależy, co rozumiesz przez "filtrować". Jeżeli filtrowaniem nazywamy np. używanie funkcji "addslashes" czy "intval", to OK. Ale jeżeli to ma polegać na bezcelowym usuwaniu np. wszystkich wystąpień słowa "UNION" i innych podobnych z danych przesyłanych przez użytkownika, a podstawianych do zapytania, to ja tego nie rozumiem. Po co to usuwać, skoro i tak w żaden sposób nie może zaszkodzić, jeżeli odpowiednio przefiltrujemy dane? Na dodatek przez takie postępowanie zupełnie niepotrzebnie eliminujemy sobie możliwość wstawienia do bazy danych niektórych słów, co może być akurat potrzebne. Spróbujcie napisać np. tutorial używania unii w SQL, jeżeli z każdego tekstu wstawianego do bazy będziecie czyścić to słowo ;-)

Jak ktoś nie filtruje danych, to i tak żadne usuwanie "UNION" itp. mu nie pomoże, bo SQL injection można wykonać na wiele innych sposobów, kiedy nie przefiltrujemy danych wejściowych...

Napisany przez: Vengeance 8.07.2005, 01:16:42

1. A kto mówi że strona musi traktować o czymś gdzie wystąpi UNION.
2. Zobacz ile skryptów (np. phpbb) jest podatnych na tego typu ataki

Napisany przez: logeen 8.07.2005, 02:34:26

ad.1) Czyli co? Jeżeli zamierzasz zbudować np. forum dyskusyjne przeznaczone do dyskusji na temat języka SQL, to nie będzie się go dało zabezpieczyć, bo w takim przypadku usuwanie "UNION" z treści wysyłanych postów jest absolutnie nie do przyjęcia, a tylko to dałoby wystarczające zabezpieczenie?

ad.2) Skrypty są podatne, ponieważ programiści zapomnieli przefiltrować dane. Gdyby to zrobili, to by nie były podatne. Usuwanie "UNION" tutaj nic nie zmieni, ponieważ jeżeli dane wejściowe potraktujemy odpowiednio "addslashes" czy "intval", to żadne "UNION" przemycone w treści nam nie zaszkodzi. Do tego właśnie zmierzało moje pytanie, na które do tej pory nikt nie odpowiedział jasno i wyraźnie: czy jeśli stosujemy odpowiednią filtrację danych (np. taką jak zaprezentowałem), to wstawienie przez użytkownika "UNION" w danych wejściowych może się źle skończyć?

Napisany przez: MStaniszczak 8.07.2005, 09:39:00

Nie ma sensu nic wywalać (filtrować żadnych słów). Grunt to dobrze wstawiać slashe a tam gdzie ich nie można dodać (np. identyfikatory) stosować odpowiednio is_number, is_integer, intval etc… Nie da rady o tym zapomnieć;-)

Dobry sposobem mogą być filtry w frameworku;-) Ew. klasa z metodami sprawdzającymi dane odpowiednich typów, a wówczaj wystarczy już coś w stylui:

  1. <?php
  2. try {
  3.  $id = CheckData::integer($_GET[&#8216;id’]);
  4.  $name = CheckData::string($_POST[&#8216;name’]);
  5.  $postcode = CheckData::postcode($_POST[&#8216;postCode’]);
  6. } catch(DataFormatException $e) {
  7.  http://www.php.net/echo &#092;"Zły format danych\";
  8. }
  9. ?>


Czy jakoś tak;-) Przy takiej organizacji łatwiej nawet poprawić ew. błąd czy luke w sposobie sprawdzania danych;-)

Pozdrawiam
Marcin Staniszczak

Napisany przez: Imperior 8.07.2005, 09:45:52

Oświećcie mnie proszę i powiedzcie, gdzie przy zdrowych zmysłach programista może zostawić lukę, że można użyć UNION bez ani jednego apostrofa? Przecież to jest możliwe tylko przy czymś takim:

  1. SELECT *
  2. FROM users WHERE id = $string


O czym wogóle rozmawiacie... tak robią tylko początkujący-nieuświadomieni.

Napisany przez: Vengeance 8.07.2005, 12:17:30

Imperior... są nawet tacy co robią

  1. SELECT *
  2. FROM users $warunki


Widac, ze analizowales malo skryptów i mało skomplikowanych zapytań widziałeś.

Cytat
tak robią tylko początkujący-nieuświadomieni

O ile mi wiadomo, to forum i ten wątek jest także dla takich a my staramy się ich uświadomić co może być błędem.

@logeen:
AD2. Prawdopodobnie masz racje i wykorzystanie wszędzie odpowiednich filtrów intval() itd... wystarczy, ALE

Mała opowieść:
Cytat
Zostałem adminem forum szkolnego. Obecnie jedyna możliwość posiadania dość fajnego i darmowego forum to phpBB. Pozatym
wcześniej też takie tam było i użytkownicy się przyzwyczaili.
Zrobiłem update do najnowszej wersji, ale wiadomo że i tak znajdą jakieś błędy (i znaleźli). Trzeba było więc zastosować właśne zabezpieczenia. Przecież nie będę naprawiał całego phpBB i w odpowiednich miejscach dawał intval() tam gdzie oni zapomnieli!

Zrobilem tak więc filtrację danych z GET i usuwam wszystkie "UNION".
Jeśli znajdziesz mi podobne w szybkosći implementacji i pod względem bezpieczeństwa rozwiązanie to z chęcią wysłucham.

A na forum dalej można pisać UNION gdyż filtruje tylko GET (phpBB do wszelkich rzeczy używa naszczęście tablic GET/POST/COOKIE a nie jedzie na superglobalach.

Napisany przez: logeen 8.07.2005, 12:36:26

@Vengeance: Z tą opowieścią, to się z Tobą zgodzę. Z tym, że są pewne "ale":

1. Ten temat chyba raczej miał na celu przedstawienia zasad takiego pisania skryptów, aby nie były podatne na SQL injection, a nie poprawiania gotowych skryptów. Więc w przypadku, który podałeś, takie postępowanie może być uzasadnione, ale chyba raczej nie w sytuacji, kiedy piszemy cały skrypt od nowa.

2. Jeżeli w sytuacji, którą przedstawiłeś, nie przefiltruje się odpowiednio danych, to i tak usuwanie "UNION" niekoniecznie da 100% bezpieczeństwo, bo przecież są inne sposoby wykonania SQL injection niż tylko za pomocą unii. Natomiast faktycznie w sytuacji konieczności porawiania istniejących dziurawych skryptów, lepsze takie zabezpieczenie niż żadne.

3. Dane $_POST też przecież można spreparować, po prostu tworząc odpowiedni formularz i go wysyłając do skryptu sad.gif Co wiecej, można zrobić tak, żeby taki formularz wysłał nieświadomie administrator forum.

Napisany przez: Vengeance 8.07.2005, 12:53:05

@logeen: Ale powiedzmy sobie prawde, że fora szkolne "hakują" tylko gówniarze co potrafią jedynie ściągnąć sploita z internetu. A te korzystają wyłącznie z GET i najczęściej właśnie z UNION (w przypadku phpBB). Ja nie mówie o pełnym zabezpieczeniu gotowca (bo to niemożliwe) ale o "zawężeniu kręgu niebezpieczeństwa" :]

Chyba doszliśmy do porozumienia smile.gif

Napisany przez: johnson 8.07.2005, 12:57:26

Mówcie co chcecie, ale czy jest ktoś w stanie podać konkretny zestaw zabezpieczeń, który ustrzeże nas przed atakami poprzez php (oczywiście takie, które zależą od programisty) czy może nie ma sposobu na 100%-owe zabezpieczenie skryptów?

Napisany przez: logeen 8.07.2005, 13:32:36

@johnson:
Odpowiedź brzmi: pełna filtracja (tzn. "addslashes", "intval" itp.) wszystkich danych zewnętrznych, które podstawiamy do zapytania SQL. Oczywiście jeżeli piszesz skrypt od zera, bo jeżeli poprawiasz bezpieczeństwo jakiegoś dziurawego gotowca, to trudno Ci będzie sprawdzić wszystkie linie kodu (ale nie jest to niewykonalne, bo tak naprawdę musimy odszukać tylko miejsca wywoływania zapytań SQL i sprawdzić, czy wszystkie zmienne podstawiane do kodu SQL są przefiltrowane) - wtedy można się dodatkowo zdecydować na rozwiązanie podane przez Vengeance, choć i tak nie będzie to pełne zabezpieczenie, niemniej powinno powstrzymać większość script kiddies.

Napisany przez: brachu 8.07.2005, 14:22:05

jezeli mozna wtracic swoje 3 grosze.... to testowalem swoj system zlecen i o dziwo nie mozna sie do niego dostac za pomoca SQL injection, zasluga jest to domyslnych ustawien serwera oraz kilku funkcji sprawdzajacych poprawnosc - ktore wcale nie byly pisane w tym celu.... ogolnie warto jest pisac funkcje sprawdzajace poprawnosc wpisanych przez uzytkownika wartosci - nawet po to aby uniknac wpisywania glupot w wypadku gdy uzytkownikowi pomieszaja sie pola formularza winksmiley.jpg

pozdrawiam

Napisany przez: MStaniszczak 8.07.2005, 14:53:21

A tu http://www.gajdaw.pl/varia/xss.html macie coś o atakcha na strony (nie SQL Injection więc troche OT;-) )

Pozdrawiam
Marcin Staniszczak

Napisany przez: moron 25.08.2005, 09:58:28

czyli co? mysql_escape_string, stripslashes questionmark.gif
moglby ktos napisac jakas funkcje ktora by to robila?

Napisany przez: logeen 25.08.2005, 19:37:06

  1. <?php
  2. /**
  3.  * Wstawia znaki unikowe w zapytaniach, dzieki czemu zapobiega atakowi "SQL injection".
  4.  * @param string $text Ciag tekstowy do zamiany
  5.  * @param resource $handle Identyfikator polaczenia
  6.  * @return string Ciag tekstowy po zamianie
  7.  */
  8. function mysql_escape($text, $handle=NULL)
  9. {
  10.     if (http://www.php.net/version_compare(http://www.php.net/phpversion(), '4.3.0', '>='))
  11.     {
  12.         if ($handle) return http://www.php.net/mysql_real_escape_string($text, $handle);
  13.         return http://www.php.net/mysql_real_escape_string($text);
  14.     }
  15. if (http://www.php.net/version_compare(http://www.php.net/phpversion(), '4.0.3', '>=')) return http://www.php.net/mysql_escape_string($text);
  16.     return http://www.php.net/addslashes($text);
  17. }
  18. ?>

Napisany przez: qeuw 28.09.2005, 14:47:54

Jak można zabazpieczyć stronę jeżeli mam where id=$_GET['id'] and password=$password, wtedy wpisując kod w $_GET['id']= '7 --'
Zaniecha mi sprawdzanie hasła. Te funckje działają tylko w ściśle określonych przypadkach. Jak można było by zabezpieczyc przed pytaniami or,select,delete, into,update, w tablicy _GET, i mieć jakąś tam pewność że skrypt będzie zabezpieczony.

Napisany przez: ActivePlayer 28.09.2005, 15:14:44

Cytat
Jak można zabazpieczyć stronę jeżeli mam where id=$_GET['id'] and password=$password, wtedy wpisując kod w $_GET['id']= '7 --'

uzyj is_numeric na $_GET['id']

Napisany przez: h.4 28.09.2005, 18:05:34

Mam takie pytanie...

  1. <?php
  2.  
  3. $_POST['komentarz'] = http://www.php.net/mysql_real_escape_string($_POST['komentarz'];
  4. $_POST['komentarz2'] = http://www.php.net/mysql_real_escape_string($_POST['komentarz2'];
  5. $_POST['komentarz3'] = http://www.php.net/mysql_real_escape_string($_POST['komentarz3'];
  6.  
  7. ?>


i teraz jak zrobic zeby wszystkie dane z _POST przepuscic przez mysql_real_escape_string bez koniecznosci powtarzania tej funkcji do kazdej zmiennej... tylko zrobic to hurtem smile.gif

please help

Napisany przez: ActivePlayer 28.09.2005, 18:54:36

Cytat
a jeśli zamiast _GET będzie _POST z jakimś tekstem?

to obejmiesz te dane w ' i wykonasz na nich mysql_escape_string()

Napisany przez: wojto 28.09.2005, 20:45:54

Cytat(h.4 @ 2005-09-28 19:05:34)
i teraz jak zrobic zeby wszystkie dane z _POST przepuscic przez mysql_real_escape_string bez koniecznosci powtarzania tej funkcji do kazdej zmiennej... tylko zrobic to hurtem smile.gif

  1. <?php
  2. foreach($_POST as $a => $b) {
  3. $_POST[$a] = http://www.php.net/mysql_real_escape_string($b);
  4. }
  5.  
  6. ?>
?

Napisany przez: qeuw 28.09.2005, 21:08:04

Otóz zrobilem funckje która zamienia wyrażenia sql na np. z UnIoN na !union!. Sądze że to w miare skuteczna metota gdzyż zawiera popularną składnie sql + wyrażenia opisane w phpmyadminie na stronie ze statystykami. A co to tej pętli to się bardzo mi przyda smile.gif

Napisany przez: logeen 29.09.2005, 19:58:27

Cytat(qeuw @ 2005-09-28 20:08:04)
Otóz zrobilem funckje która zamienia wyrażenia sql na np.  z UnIoN na !union!. Sądze że to w miare skuteczna metota...

Fakt... tylko po co? KAŻDE zapytanie można skutecznie zabezpieczyć przed SQL Injection, bez usuwania z niego słów kluczowych SQLa, a jedynie poprzez odpowiednią filtrację danych, przed podstawieniem ich do zapytania. Przez "Filtrację" rozumiem wykonania np. addslashes (albo lepiej funkcji, którą podałem wcześniej) lub np. intval tam, gdzie jest to konieczne - w zależności od kontekstu. Ciekaw jestem jak rozwiążesz sprawę, kiedy "UNION" powinno się zapisać w bazie danych, np. w jakiejś treści wyświetlanej później na stronie WWW? Fakt, można zamieniać np. na "!union!", a potem przy wyświetlaniu z powrotem na "UNION", ale po co? Jak ktoś mi pokaże jak wykorzystać "UNION" do wykonania SQL Injection w prawidłowo zabezpieczonym skrypcie - np. takim, jak podawałem w tym temacie kilka postów wcześniej - to będę bardzo wdzięczny. Wg mnie jest to niemożliwe. Po co w takim razie narzucać sobie jakieś sztuczne ograniczenia, polegające na niemożności wystąpienia w rekordach bazy danych jakichś słów (np. "UNION")?

Napisany przez: MalyKazio 15.01.2006, 12:40:44

Prawdę mówiąc ten temat jest strasznie zaśmiecony. Niby ktoś pisał, że ma być też pomoca dla początkujących a jedyną rzeczą przydatną dla mnie, jako bardzo początkującego, było słowo addslashes. Niestety nic poza tym... Ani jak to wykorzystać ani jak to potem wyciągnąć z bazy danych... trochę szkoda bo gdy założyłem temat z prośbą o prostą odpowiedź ( http://forum.php.pl/index.php?showtopic=40200 ) to mi się trochę "oberwało" a temat przyklejony to dla początkującego uzytkownika czarna magia.

Napisany przez: Vengeance 15.01.2006, 12:50:59

MalyKazio: Znów ci się "oberwie" odemnie osobiście, bo skoro piszesz, że w tym temacie nic nie znalazłeś prócz addslashes() to śmię twierdzić, że czytać nie potrafisz i analizować kodów też nie!

Wiadomo, ile ludzi tyleż opini, dlatego w tym wątku znaleść można prawdziwe multum informacji o tym jak się zabezpieczyć. I nikt nie napiszę Ci jednego 100% sposobu - bo taki nie istnieje. Każdy ma jakieś zalety i wady, każda osoba faworyzuje innych.

Ktoś ci napiszę "używaj addslashes" a potem odnajdą lukę w tej funkcji i cała koncepcja bierze w łęb :]

Jeśli szukasz posegregowanych informacji to odsyłam do książek i artykułów. Tutaj jest forum, i nikt nie będzie edytował każdego postu tak aby początkujący mógł odczytać to jako książkę :/ A że się 5 stron czytać dokładnie ludziom nie chce.... no sorry.

Napisany przez: the_foe 23.02.2006, 02:40:09

  1. <?php
  2. $win="\xA5\xC6\xCA\xA3\xD1\xD3\x8C\x8F\xAF\xB9\xE6\xEA\xB3\xF1\xF3\x9C\x9F\xBF";
  3. $iso="\xA1\xA6\xAC\xB1\xB6\xBC";
  4. $preg="/[^".$win.$iso."A-Za-z0-9_ -!@#\$%\^*\(\)\+=\{\}:;,.\\|\/\?]/s";
  5.  
  6. foreach ($_GET as $k=>$v){
  7. $_GET[$k]=http://www.php.net/preg_replace($preg,"\\1",$v);
  8. }
  9. foreach ($_POST as $k=>$v){
  10. $_POST[$k]=http://www.php.net/preg_replace($preg,"\\1",$v);
  11. }
  12. foreach ($_COOKIE as $k=>$v){
  13. $_COOKIE[$k]=http://www.php.net/preg_replace($preg,"\\1",$v);
  14. }
  15.  
  16. ?>


i po sprawie, nikt nie podskoczy
(mozna jeszcze trimowac, ale preg_replace nie przpusci chyba zero byte?)

Napisany przez: kofaniutki_misio 26.02.2006, 19:46:34

Witam,

Czytałem posty na temat zabezpieczeń na stronie i zebrałem wszystko do kupy i wyszło mi coś takiego:

  1. <?
  2.  
  3. Function logs($msg) 
  4. { 
  5. http://www.php.net/global $HTTP_USER_AGENT, $_SERVER; 
  6. $url = http://www.php.net/sprintf("%s%s%s","http://",$_SERVER['HTTP_HOST'],$_SERVER['REQUEST_URI']); 
  7. $plik='http'; 
  8. if($_SERVER['HTTPS']=='on') 
  9.  { 
  10. $plik.='s'; 
  11. } 
  12. $plik.='://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']; 
  13. if($_SERVER['QUERY_STRING']>' ') 
  14. { 
  15. $plik.='?'.$_SERVER['QUERY_STRING']; 
  16. } 
  17. if ($_SERVER["HTTP_X_FORWARDED_FOR"]) 
  18. { 
  19. if ($_SERVER["HTTP_CLIENT_IP"]) 
  20. { 
  21. $mz_user['proxy']=$_SERVER["HTTP_CLIENT_IP"]; 
  22. }else 
  23. { 
  24. $mz_user['proxy']=$_SERVER["REMOTE_ADDR"]; 
  25. } 
  26. $mz_user['ip']=$_SERVER["HTTP_X_FORWARDED_FOR"]; 
  27. }else 
  28. { 
  29. if ($_SERVER["HTTP_CLIENT_IP"]) 
  30. { 
  31. $mz_user['ip']=$_SERVER["HTTP_CLIENT_IP"]; 
  32. }else 
  33. { 
  34. $mz_user['ip']=$_SERVER["REMOTE_ADDR"]; 
  35. } 
  36. } 
  37. $h=@http://www.php.net/fopen('logs/logs.txt','a'); // pamietaj aby ustawic chmod na 622 
  38. @http://www.php.net/fwrite($h,http://www.php.net/date('H:i:s d-m-Y').'  ip: '.$mz_user['ip'].' proxy: '.$mz_user['proxy'].' plik: '.$plik.' url: '.$url.' atak na zmienną: $'.$msg.' '); 
  39. @http://www.php.net/fclose($h); 
  40. return $msg; 
  41. } 
  42.  
  43. //zabezpieczenia zmiennych
  44.  
  45. $akcja = $_GET['akcja'];
  46. $id = (int)$_GET['id'];
  47.  
  48. http://www.php.net/preg_replace( '%<script>%', '', $akcja);
  49. http://www.php.net/preg_replace( '%UNION%', '', $akcja);
  50.  
  51. $akcja = http://www.php.net/mysql_escape_string($akcja); 
  52.  
  53. if(!http://www.php.net/ereg ("[a-z_]", $akcja)) {
  54.  logs('akcja');
  55.  http://www.php.net/die('Naruszenie zasad bezpiczeństwa! Twoj adres IP został pobrany.');}
  56.  
  57. if(!http://www.php.net/ereg ("[0-9]", $id)) {
  58.  logs('id');
  59.  http://www.php.net/die('Naruszenie zasad bezpiczeństwa! Twoj adres IP został pobrany.');}
  60.  
  61.  
  62. //koniec zabezpiczeń zmiennych
  63.  
  64. ?>


funkcja logs wyrzuca do pliku bardzo przydatne informacje o gościu który próbuje cos namieszać. W postaci np:

"18:21:38 26-02-2006
ip: 127.0.0.1
proxy:
plik: http://localhost/~www/zabezpieczenia.php
url: http://localhost/~www/zabezpieczenia.php
atak na zmienną: $akcja"


Co tu jest niepotrzebne? a co źle!!

Dodam ze metoda ma pobierac z linku dwie zmienne $akcja i $id dla późniejszego użycia zapytania SQL. $akcja ma zawierać tylko ciąg małych literek a $id tylko liczbe.

Pozdrawiam.

Napisany przez: vedeney 28.02.2006, 14:33:07

Sorry that not Polish,
but your functions are so funny smile.gif

e.g.
Why do you make global $_SERVER?questionmark.gif?

  1. <?php
  2. http://www.php.net/global $HTTP_USER_AGENT, $_SERVER;
  3. ?>

I can`t explane it.

  1. <?php
  2. http://www.php.net/preg_replace( '%UNION%', '', $akcja)
  3. ?>

AND
Kod
UNI/**/ON

OOPS tongue.gif

  1. <?php
  2.  
  3. foreach ($_GET as $k=>$v){
  4. $_GET[$k]=http://www.php.net/preg_replace($preg,"\\1",$v);
  5. }
  6. foreach ($_POST as $k=>$v){
  7. $_POST[$k]=http://www.php.net/preg_replace($preg,"\\1",$v);
  8. }
  9. foreach ($_COOKIE as $k=>$v){
  10. $_COOKIE[$k]=http://www.php.net/preg_replace($preg,"\\1",$v);
  11. }
  12. ?>

Have you ever here about $_REQUEST?questionmark.gif No?

Napisany przez: kofaniutki_misio 28.02.2006, 22:08:23

hej vedeney. funkcja logs, jest przepisana. Global mozna wyrzucic. Ale czemu nie rozumiesz zastosowania tego kodu:

  1. <?php
  2. http://www.php.net/preg_replace( '%UNION%', '', $akcja);
  3. ?>


chcialem żeby nie mozna bylo użyć polecenia UNION.

  1. <?php
  2. http://mojastron.php?id=10 UNION SELECT TOP 1 TABLE_NAME FROM
  3. INFORMATION_SCHEMA.TABLES--
  4. ?>


wyciągania wszystkich tabel.

Napisany przez: dr_bonzo 28.02.2006, 23:28:36

  1. <?php
  2. $age = $_GET[ 'age' ]; // pomiijam sprawdzanie czy to w ogole istnieje
  3. $name = $_GET['name' ];
  4.  
  5. $intAge = http://www.php.net/intval( $age )
  6. $strName = mysql_real_escape( $name ); // moglem pomylic nazwe funkcji
  7. $sql = "SELECT some_column FROM users WHERE age = " . $intAge . " AND name = '" . $strName . "'";
  8. ?>

i to tyle, zadne pregi, bo po co

gdy pod $age wstawisz "UNION .....blalba.... --"
$intAge == 0

gdy pod $name wstawisz "UNION .....blalba.... --"
sql wyglada tak
  1. SELECT some_column
  2. FROM users
  3. WHERE age = 0 AND name = 'UNION.... blalbba..--'


bylo to juz wspominane na poczatku (lub dalej tongue.gif) tego watka ale zginelo w masie postow probujacych to uzyskac.

Napisany przez: vedeney 1.03.2006, 08:53:31

Ok! I`ve understand you, But your code didn`t prevent such hack as

Kod
http://mojastron.php?id=10 UN/**/ION SEL/**/ECT bla bla bla....

Which will be executed without any problems;
or
Kod
http://mojastron.php?id=BENCHMARK(1000000,MD5(NOW()))

or
Kod
http://mojastron.php?id=BENCHMARK(1000000,BENCHMARK(1000000,BENCHMARK(1000000,MD5(NOW()))))

It`s DOS through MySql-injection aaevil.gif

Napisany przez: the_foe 2.03.2006, 19:35:09

Cytat(vedeney @ 2006-02-28 14:33:07)
  1. <?php
  2. foreach ($_GET as $k=>$v){
  3. $_GET[$k]=http://www.php.net/preg_replace($preg,"\\1",$v);
  4. }
  5. foreach ($_POST as $k=>$v){
  6. $_POST[$k]=http://www.php.net/preg_replace($preg,"\\1",$v);
  7. }
  8. foreach ($_COOKIE as $k=>$v){
  9. $_COOKIE[$k]=http://www.php.net/preg_replace($preg,"\\1",$v);
  10. }
  11. ?>

Have you ever here about  $_REQUEST?questionmark.gif No?

Yes, I've heard about $_REQUEST. But it's another stupid thing like register_globals on is. Let the manual speak:

Cytat
$_REQUEST
    Variables provided to the script via the GET, POST, and COOKIE input mechanisms, and which therefore cannot be trusted. The presence and order of variable inclusion in this array is defined according to the php variables_order configuration directive. This array has no direct analogue in versions of php prior to 4.1.0. See also import_request_variables().


Ain't simple?
if you use _REQUEST, as foreach source, you won't be able to set cookie, set GET, set POST with the same string name! You will be forced to remember about it all time.

Additionaly, here's no problem with my code, you can use _REQUEST in spite of. If you realy like it.

Napisany przez: LamaMASTER 5.04.2006, 17:53:33

Cytat
zabezpieczenie w stylu:
  1. <?php
  2. $query = 'update `uzytkownicy` set `pole`="'.$dane.'" where `id`="'.$id.'";';
  3. ?>
to jak juz powiedziano zadne zabezpieczenie a pozatym zmnijsza wydajnosc zapytania, umieszczanie wartosci liczbowych w momiedzy " " powiduje iz MySQL mysli ze ma do czynienia ze znakami (stringami) i niepotzrebnie musi konwertowac typy.

Bzdura. Zapisz taki jest jak najbardziej szybszy, bo kod nie jest parsowany (bo jest w ' '), a zapisując zmienną w cudzysłowiach w kodzie ("coś tam $zmienna") powoduje parsowanie kodu i dłuższe sprawdzanie zmiennych. Nie wprowadzajcie ludzi w błąd.
Cytat
przyklad:
  1. <?php
  2.  
  3. $sql = http://www.php.net/mysql_query("SELECT * FROM news WHERE id=".$_GET['id']);
  4.  
  5. ?>


wywołanie normalne:
Kod
news.php?id=1
news.php?id=25
itd


wywołanie zmodyfikowane przez kogostam
np.
Kod
news.php?id=1;DROP%20TABLE%20news;

Ee tam, zonwu zonk, przecież mysql_query pozwala na wysłanie tylko jednego zapytania, więc to co pokazałeś nic nie da.

Więcej tematu czytać mi się nie chciało, ale mam nadzieję, że nie ma tam dalej więcej bzdur winksmiley.jpg

Napisany przez: Pawel86 5.04.2006, 22:36:28

A takie rozwiazanie:

  1. <?php
  2.  
  3.  function ParseText(&$Text)
  4.    {
  5.       $Text=http://www.php.net/trim($Text);
  6.       if(http://www.php.net/get_magic_quotes_gpc())
  7.       {
  8.          $Text = http://www.php.net/stripslashes($Text);
  9.       }
  10.       $Text = http://www.php.net/htmlspecialchars($Text, ENT_QUOTES);
  11.       $Text = http://www.php.net/str_replace('\\0','\\\\0',$Text);
  12.       $Text = http://www.php.net/str_replace('\\t','\\\\t',$Text);
  13.       $Text = http://www.php.net/str_replace('\\n','\\\\n',$Text);
  14.       $Text = http://www.php.net/str_replace('\\r','\\\\r',$Text);
  15.       return $Text;
  16.    }
  17.  
  18.    function SecureSuperglobalsTables()
  19.    {
  20.       $this->SecureTable($_POST);
  21.       $this->SecureTable($_GET);
  22.       .....
  23.    }
  24.  
  25.    function SecureTable(&$Table)
  26.    {
  27.       if(!http://www.php.net/is_array($Table)) return false;
  28.       foreach($Table as $Id=>$Row)
  29.       {
  30.          if(http://www.php.net/is_array($Row))
  31.          {
  32.             $this->SecureTable($Table[$Id]);
  33.          }
  34.          else $this->ParseText($Table[$Id]);
  35.       }
  36.    }
  37.  
  38. ?>

XSS-y wykluczone, ' i " zamieniane na bezpieczne smile.gif da sie to obejsc?

Napisany przez: Janek111 16.04.2006, 17:47:42

Mam taki problem:
Jesli uzyje mysql_real_escape_string i jesli jest wlaczone magic quotes to otrzymam przykladowo ze stringu jakis'wyraz, string jakis///'wyraz. Moglbym zrobic tak:

  1. <?php
  2.  
  3. if(!http://www.php.net/get_magic_quotes_gpc())
  4.    $string = http://www.php.net/mysql_real_escape_string($string);
  5.  
  6. ?>

tylko, że wtedy, jeśli jest wlaczone magic_quotes to stosowanie tej funkcji jest bezsensu - gdy uzyje addslashes wyjdzie na to samo.
jak mozna rozwiazac ten problem?? Moze poprostu zostac przy addslashes ? smile.gif

Napisany przez: J4r0d 29.05.2006, 22:28:55

Cytat(ktuvok @ 14.05.2005, 19:58 ) *
Dorzucę się do tego wątku i powiem, że moim zdaniem najlepszym zabezpieczeniem jest:

1. ustawienie w php.ini opcji get_magic_quotes_gpc na ON

2. stosowana równolegle z powyższym funkcja czyszcząca otrzymane dane - od razu uprzedzam, że wbrew nazwie nie dotyczy ona tylko danych przesyłanych metodą POST:
  1. <?php
  2.  
  3. function OczyscPost($Zmienna, $Rozmiar)
  4. {
  5. if (http://www.php.net/get_magic_quotes_gpc())
  6. {
  7. $Zmienna = http://www.php.net/stripslashes($Zmienna);
  8. }
  9. $Zmienna = http://www.php.net/trim(http://www.php.net/strip_tags(http://www.php.net/str_replace(""", "", $Zmienna)));
  10. $Zmienna = substr(str_replace("'","", $Zmienna),0,$Rozmiar);
  11. $Zmienna = sprintf("%s",$Zmienna);
  12. return $Zmienna;
  13. }
  14.  
  15. ?>


3. Funkcja zapewniająca dodatkowe filtrowanie dla identyfikatorów, przekazywanych w URL'u:
  1. <?php
  2.  
  3. function DoCyfry($Zmienna)
  4. {
  5. $Zmienna = http://www.php.net/intval($Zmienna);
  6. if(http://www.php.net/is_int($Zmienna))
  7. {
  8. return $Zmienna;
  9. }
  10. else
  11. {
  12. return 0;
  13. }
  14. }
  15.  
  16. ?>


Zastosowanie:
  1. <?php
  2.  
  3. $Nazwisko = OczyscPost($_POST['Nazwisko'], 40);
  4. $ID = DoCyfry(OczyscPost($_GET['ID'], 10));
  5.  
  6. ?>


Jakieś uwagi?

Pozdrawiam,
K



Hmm.. Do czego jest właściwie to UNION? Może ktoś poda przykład? Bo ja się nie zetknąłem z takim zapytaniem

Napisany przez: em1X 29.05.2006, 22:36:35

A http://www.google.pl/search?q=sql+union to nie potrafisz?

  1. SELECT * FROM text UNION
  2. SELECT * FROM news


czyli sklejanie dwoch zapytan do bazy

Napisany przez: J4r0d 29.05.2006, 22:52:27

Próbując podsumować dyskusję, możnaby powiedzieć, że aby zabezpieczyć się przed SQL Injection trzeba filtrować każdą zmienną przychodzącą, czyli:

1. Jeśli spodziewamy się liczby to każdą zmienną traktujemy

  1. <?php
  2. http://www.php.net/intval($zmienna);
  3. ?>


2. Jeśli spodziewamy się ciągu to stosujemy
  1. <?php
  2. http://www.php.net/addslashes($zmienna);
  3. ?>


Czy to wystarczy?


A co w takim przypadku. Mamy spis użytkowników w systemie, który załóżmy że wygląda tak.



Przy każdym użytkowniku jest link z opcją usunięcia konta. Z tym linkiem, przesyłany jest numer ID danego klienta, żeby wiedzieć, którego klienta usunąć z bazy (ID jest kluczem głównym).

Teraz ktoś może zmodyfikować URL, np zamiast usunąć konto 2 (http://jakasstrona/usun.php&id=2) może wpisać dowolny inny numer, np (http://jakasstrona/usun.php&id=1) i skasuje konto admina.

Jak się przed tym zabezpieczyć?

Stosuję w każdym skrypcie funkcję weryfikującą, któa sprawdza czy użytkownik jest zalogowany i czy ma odpowiednie prawa. Ale wiem, że to nie wystarczy.

Napisany przez: Termit_ 3.06.2006, 19:58:56

Wówczas zawsze należy robić dodatkowe confirmy - formularze typu "Czy na pewno chcesz.... [ TAK ] [ NIE ]"

Napisany przez: J4r0d 4.06.2006, 17:53:17

Cytat(Termit_ @ 3.06.2006, 18:58 ) *
Wówczas zawsze należy robić dodatkowe confirmy - formularze typu "Czy na pewno chcesz.... [ TAK ] [ NIE ]"



Stosuję..

Napisany przez: thornag 28.07.2006, 16:32:02

Wedlug mnie mozesz jedynie sprawdzic czy Id nie jest elementem wyznaczonego przez Ciebie a niedozwolonego zbioru.

Zostaja jedynie confirmy, tutaj wszystko wydaje sie kwestia dostepu. Jesli dasz dostep do tego panelu, to po co meczyc sie ze zmiana URLa skoro wystarczy kliknac smile.gif No chyba ze kazdy uzytkownik ma inne prawa i innych uzytkownikow ktorych moze edytowac (taka relacja su/admin/sub-admin smile.gif wtedy wspommniany przezemnie zbior nalezalo by uzaleznic od uzytkowanika.

Napisany przez: eai 2.08.2006, 00:19:08

@J4r0d Bardzo prosto się można zabezpieczyć

Zastosuj sume kontrolną. jakasstrona/usun.php&id=2&checksum=f3sxSdf32vx3sGx

Napisz własny wzór generowania sumy kontrolnej oraz jej sprawdzania.
Np.

  1. <?php
  2.  
  3. function checksum ($id) {
  4.  
  5. return http://www.php.net/substr(http://www.php.net/md5('aXq23' . $id), 1, 3); 
  6.  
  7. }
  8.  
  9. if (checksum ($id) == $_GET['checksum']) {
  10.  // .... Usuwamy itp...
  11.  
  12.  }
  13. ?>

Napisany przez: Turgon 2.08.2006, 08:37:09

Zgadzam się z Eai. Ja stosuje sumy plus sesje oraz grupy uprawnień. Jeśli użytkownik nie ma odpowiedniego levela odrazu acces denied w głównym pliku administracyjnym. Nie pozwalam nawet dojść do uruchomienia reszty winksmiley.jpg .
Co do tego usuwania adminów to banał jest. Dodajemy do filtrowania requestów :

  1. <?php
  2. if($_GET['id'] == '1')
  3. {
  4. return false;
  5. }
  6. ?>


i gotowe smile.gif . Czyż nie trudne ?
Po za tym thornag używaj głównego pliku administracyjnego przez który jest jedyna możliwość użycia funkcji ACP etc. . To dodatkowe zabezpieczenie i trochę utrudnia życie, ale warto. Dodatkowa bariera dla włamywacza...

Napisany przez: J4r0d 2.08.2006, 15:12:09

Cytat(eai @ 1.08.2006, 23:19 ) *
@J4r0d Bardzo prosto się można zabezpieczyć

Zastosuj sume kontrolną. jakasstrona/usun.php&id=2&checksum=f3sxSdf32vx3sGx

Napisz własny wzór generowania sumy kontrolnej oraz jej sprawdzania.
Np.

  1. <?php
  2.  
  3. function checksum ($id) {
  4.  
  5. return http://www.php.net/substr(http://www.php.net/md5('aXq23' . $id), 1, 3); 
  6.  
  7. }
  8.  
  9. if (checksum ($id) == $_GET['checksum']) {
  10.  // .... Usuwamy itp...
  11.  
  12.  }
  13. ?>


Generujesz - ok. A w jaki sposób chcesz przetrzymywać tą sume i gdzie?

Napisany przez: eai 2.08.2006, 22:40:56

@J4r0d Przecież to jest jeszcze prostsze smile.gif

Przykład:

checksum.php

  1. <?php
  2.  
  3. function checksum ($id) {
  4. return http://www.php.net/substr(http://www.php.net/md5('aXq23' . $id), 1, 3); 
  5. }
  6.  
  7. ?>


admin.php
  1. <?php
  2.  
  3. //...
  4.  
  5. include 'checksum.php';
  6.  
  7.  
  8. function foo () { //Jakas tam funkcja generujaca linki do panelu admina bla bla bla...
  9. $row = ...; //Tablica np. wynik z mysql
  10. http://www.php.net/echo 'strona.com?usun=' . $row['id'] . '&checksum=' . checksum($row['id'];
  11.  }
  12.  
  13.  
  14. function delete () {
  15. if(checksum ($_GET['id']) == $_GET['checksum']) {
  16.  
  17. // Usuwasz
  18.  
  19. }
  20. }
  21.  ?>


Prościej się wytłumaczyć nie da smile.gif

Napisany przez: J4r0d 3.08.2006, 09:01:53

Cytat(eai @ 2.08.2006, 21:40 ) *
@J4r0d Przecież to jest jeszcze prostsze smile.gif

Przykład:

checksum.php
  1. <?php
  2.  
  3. function checksum ($id) {
  4. return http://www.php.net/substr(http://www.php.net/md5('aXq23' . $id), 1, 3); 
  5. }
  6.  
  7. ?>


admin.php
  1. <?php
  2.  
  3. //...
  4.  
  5. include 'checksum.php';
  6. function foo () { //Jakas tam funkcja generujaca linki do panelu admina bla bla bla...
  7. $row = ...; //Tablica np. wynik z mysql
  8. http://www.php.net/echo 'strona.com?usun=' . $row['id'] . '&checksum=' . checksum($row['id'];
  9.  }
  10.  
  11.  
  12. function delete () {
  13. if(checksum ($_GET['id']) == $_GET['checksum']) {
  14.  
  15. // Usuwasz
  16.  
  17. }
  18. }
  19.  ?>


Prościej się wytłumaczyć nie da smile.gif

Dzięki. Nie zauważyłem, że generujesz go na podstawie Id. Wszystko jasne. Dzięki.

Napisany przez: planet_x 3.08.2006, 15:09:20

Co do zabezpieczenia przed SQL Injection znalazłem coś takiego

  1. <?php
  2.  
  3. $arrArguments = http://www.php.net/array();
  4. $intArgumentIndex = 0;
  5.  
  6. function parseArgument($arrMatches) {
  7. http://www.php.net/global $arrArguments, $intArgumentIndex;
  8.  
  9. $strMatch = $arrMatches[0];
  10. $strArgument = @$arrArguments[$intArgumentIndex++];
  11. switch ($strMatch) {
  12. case '%d': return (int)$strArgument;
  13. case '%s': return '"'.
  14. http://www.php.net/mysql_real_escape_string($strArgument).'"';
  15. case '%b': return (int)((bool)$strArgument);
  16. }
  17. }
  18.  
  19. function SQL($strSql) {
  20. http://www.php.net/global $arrArguments, $intArgumentIndex;
  21.  
  22. $arrArgs = http://www.php.net/func_get_args();
  23. http://www.php.net/array_shift($arrArgs);
  24. $arrArguments = $arrArgs;
  25. $intArgumentIndex = 0;
  26. return http://www.php.net/preg_replace_callback('/(%[dsb])/', 'parseArgument',
  27. $strSql);
  28. }
  29.  
  30. ?>


Zastosowanie:
  1. $sql = SQL('INSERT INTO users (id, uid, name, username, password, newsletter)
  2. VALUES (NULL, %d, %s, %s, %s, %B)', $_POST['uid'], $_POST['name'],
  3. $_POST['username'], md5($_POST['password']), $_POST['newsletter']);
  4.  
  5. INSERT INTO users (id, uid, name, username, password, newsletter)
  6. VALUES (NULL, 1, "Łukasz \"anAKiN\" Lach", "anakin",
  7. "97296eca657a093aa379778c237e292d", 1)


Cały temat pod http://hacking.pl/5845
oraz bardzo dobry przykład po angielsku ale kod każdy rozumie
http://www.unixwiz.net/techtips/sql-injection.html
a tu przykład błedów wysyłanych przez formularz
http://webcity.pl/webcity/porady.php/t/113

Dobrym też pomysłem są logi jeżeli było jakieś błędne zapytanie, dzięki temu można wyczaić co dany klient kombinuje, i powiedzmy przyblokować w imie dobra jego IP na jakiś czas ewentualnie login, wtedy niezrobimy krzywdy innym userom na tym samym ip.

Co do tego usówania to ja jeszcze weryfikuje IP, nazwe sesji, sumę kontrolną, i uprawniemia usera, pozatym nie jest dany wpis wywalany z bazy tylko deaktywowany powiedzmy jakieś pole w DB odpowiada za status, pużniej odpalam co jakiś czas skrypt który usówa wpisy starsze niż 30 dni z bazy danych w celu odciążenia serwera. Myślę że to w miarę bezpieczna metoda jeżeli chodzi o usówania damych z bazy. i jeszczcze na dodatek jak jest kilka osób które zarządzają serwisem.

Napisany przez: php programmer 21.08.2006, 11:10:02

Mam zapytanie, które jest brzydkie

  1. <?php
  2. $query = "DELETE FROM newsy WHERE id=".$_GET['id'];
  3. ?>


Czy jak zmienie w taki sposób:

  1. <?php
  2. $query = "DELETE FROM newsy WHERE id='".$_GET['id']."'";
  3. ?>


To będzie już ładne questionmark.gif?

Napisany przez: nospor 21.08.2006, 11:25:10

a jak ktos ci w miejsce id zamiast powiedzmy 2, wpisze: 2' or 1=1 to usunie ci wszystko z tabeli.... byla mowa na poczatku tego topicu. jesli id to liczba, to rzutuj ja na liczbe: (int)$_GET['id']. jak nie liczba to slashuj

Napisany przez: php programmer 21.08.2006, 13:05:04

OK. Ale jak mam już zapytanie typu SELECT, np

  1. <?php
  2. $query = "SELECT * FROM newsy WHERE id=".$_GET['id'];
  3. ?>

To rozumiem, że chyba nic złego się nie może stać ?

Napisany przez: nospor 21.08.2006, 13:08:30

W przypadku mysql za bardzo tak ci nic nie skasuja, gdyz mysql_query pozwala na wykonanie tylko jednego zapytania. ale w przypadku innych baz to moglbys sie zzdziwic.
Pozatym w mysql to ci moga wyciagnac inne dane niz w twoim warunku, wystarczy ze za id dadza: 2 or 1=1
i juz poznaja wszystkie rekordy a nie tylko o danym id.

Przyjmij wkoncu do wiadomosc. Dane nalezy filtrowac, niezaleznie od tego czy ktos moze zaszkodzic czy nie. Naucz sie wyrabiac w sobie dobre nawyki.
Cos ma byc intem: zrzutuj na int. Cos ma byc tekstem: przeslashuj to

Napisany przez: sopel 21.08.2006, 13:25:04

Cytat(php programmer @ 21.08.2006, 14:05 ) *
OK. Ale jak mam już zapytanie typu SELECT, np
  1. <?php
  2. $query = "SELECT * FROM newsy WHERE id=".$_GET['id'];
  3. ?>

To rozumiem, że chyba nic złego się nie może stać ?


żartujesz czy to jakaś prowokacja? w $_GET['id'] wpisuje OR 1=1 i po sprawie. wlasciwie mozna zrobic tu wszystko teraz. taki przyklad pojawia sie w kazdym kursie, artykule, ksiazce jako calkowity brazk zabezpieczenia.

Napisany przez: skowron-line 21.08.2006, 13:45:32

Cytat(nospor @ 21.08.2006, 12:08 ) *
mysql_query pozwala na wykonanie tylko jednego

a jesli bedzie cos takiego
http://index.php?site=del&id=2
i dopiszesz dalej
';%20$mysql_query%20=%20"%20DELETE%20%20FROM%20USERS";
chodzi o usuwanie to czy cos takiego ma szanse zadzialac

w przypadku jak id nie jest filtrowane

Napisany przez: nospor 22.08.2006, 08:23:57

Cytat
a jesli bedzie cos takiego
http://index.php?site=del&id=2
i dopiszesz dalej
';%20$mysql_query%20=%20"%20DELETE%20%20FROM%20USERS";
chodzi o usuwanie to czy cos takiego ma szanse zadzialac

w przypadku jak id nie jest filtrowane

Czy Twoim zamierzeniem bylo zakonczenie jednej instrukcji php i wywolanie drugiej, w tym przypadku wywolanie ponownie mysql_query? Powodzenia życze. winksmiley.jpg

Napisany przez: php programmer 23.08.2006, 12:39:00

Kurcze zrobiłem coś takiego:

  1. <?php
  2. $query = ($_GET['id']=='') ? 'INSERT INTO formularze SET' : 'UPDATE formularze SET ';
  3. $query .= " name = '".http://www.php.net/mysql_escape_string($_POST['name'])."', date='".$_POST['date']."' ";
  4. if ($_GET['id']!='')
  5. $query .= ' WHERE id ='.(int)$_GET['id'];
  6.  
  7. $result = http://www.php.net/mysql_query($query) or http://www.php.net/die(http://www.php.net/mysql_error());
  8. ?>


Probelm jest chyba z mysql_escape_string
bo teraz po dodaniu tesktu z cudzysłowem i zapisaniu w bazie,
jak robie wyświetlanie wpisanych wartości to mam dodane slashe,
Co się w takim przypadku robi? Jest jakaś funkcja na to?

Napisany przez: nospor 23.08.2006, 12:41:56

no musisz przed wyswietleniem uzyc stripslashes. jest to pewien feler... smile.gif

Mozesz tez zapisywac do bazy przy pomocy htmlspecialchars z dyrektywa ENT_QUOTES. Zapiszesz wowczas encje i nie bedziesz mial \

Napisany przez: sopel 23.08.2006, 13:20:47

używaj prepared statements to w wiekszosci przypadkow nie bedziesz musial sie sie przejmowaniem slashowaniem i odslashowaniem. niestety dostepne dopiero od mysqli i pdo

Napisany przez: free 29.08.2006, 20:33:05

Cytat(MoD @ 27.02.2005, 16:45:48 ) *
Ja do liczb stosuje najczęściej http://pl.php.net/ereg (zwłaszcza w UPDATE, w grze MMORPG). Wtedy mam pewność że osoba która wpisze np -1230 nie wyrządzi mi żadnych szkód. A zabezpieczanie skryptów można trenować na wspomnianym przeze mnie wyżej ExoFusion. Jak ktoś go tak zabezpieczy, że nie będzie żadnych (no, może nie żadnych, a prawie żadnych) błędów to będzie się miał czym pochwalić (ja znałem 2 gry na 10 które były w miarę zabezpieczone, ale i tak padły - właśnie przez SQL Injection)

Apropo gier: http://sge.laventhar.pl/ Włamałem sie do niej pół roku temu poprzez błąd serwera, w kodzie php odnalazłem pliki *ini a tam hasło :-) i gra była moja.

Napisany przez: Vexator 30.08.2006, 06:36:08

przyznam szczerze, ze calego topica nie przeczytalem i moze sie juz pojawilo

jesli chcemy zrobic

  1. SELECT pole FROM tabela WHERE id=$_GET['id']

to najlepiej jest nie przesylac zmiennej bezposrednio GETem, czy POSTem, lecz zrobic tak:

  1. <?php
  2.  
  3. switch ($_GET['id'])
  4. {
  5. case 'a': $szukana=0;
  6. break;
  7. case 'b': $szukana=1;
  8. break;
  9. default : $szukana=666;
  10. }
  11.  
  12. $sql = "SELECT pole FROM tabela WHERE id =".$szukana.";";
  13. ?>


w ten sposob nikt nie jest w stanie pod nasza zmienna podpiac "zlych" warunkow do sqla, bo jesli wpisze cokolwiek innego niz a lub b, to $szukana bedzie defaultowa


p.s. co zrobic, zeby forum nie wstawialo mi \ przed "?

Napisany przez: nospor 30.08.2006, 08:13:33

@Vexator z calym szacunkiem, ale przeczytaj jednak ten topic caly, albo przynajmniej strone na ktorej napisales tego posta...
Przeciez ty dales warunek na ID, w bazie mam powiedzmy 1000 rekordow i co, mam walić na kazdego case? Jak ty to sobie wyobrazasz? poroniony pomysl
skoro to ID to wystarczy zrzutowac na int: (int) $_GET['id']
i nikt ci nic nie wrzuci

Napisany przez: free 31.08.2006, 11:33:31

Naklepsza ochroną jest stosowanie sesji z prawami dostepu. W swoich skryptach przed wyslaniem zapytanie do SQL spr czy user ma prawa dostepu, jezeli nie skrypt nie puszcza pasozyda.

Napisany przez: nospor 31.08.2006, 12:02:58

@free ale jak to sie ma do topicu w ktorym uraczyles nas tym postem?
W jaki sposob sprawdzasz czy koles ma prawa? Na podstawie pewnie czy zalogowany, a zeby sie zalogowac to musi wpisac login i haslo i juz w tym momencie moze zrobic ci atak. No chyba ze sprawdzasz czy ma prawa do zalogowania sie winksmiley.jpg

edit: a nawet jak ma prawa to moze chcacy lub niechcacy zrobic cos "źle"

Napisany przez: Blastereq 7.09.2006, 12:27:57

Hmm, mam pytanie, stosuje mod_rewrite w ten sposób :

  1. RewriteEngine on
  2. RewriteRule ^$ /index.php
  3. RewriteRule ^([0-9a-z]+)$ /$1/
  4. RewriteRule ^([0-9a-z]+)/$ /index.php?p_zmienna=$1
  5.  
  6. RewriteRule ^([0-9a-z]+)/([0-9a-z]+)$ /$1/$2/
  7. RewriteRule ^([0-9a-z]+)/([0-9a-z]+)/$ /index.php?p_zmienna=$1&d_zmienna=$2

Adres strony pojawia się w ten sposób : http://strona.net/wartosc1/wartosc2/
Jeśli w żadnym linku nie odwołam się do postaci http://strona.net/index.php?p_zmienna=wartosc_1&d_zmienna=wartosc2 . To czy ewentualny atakujący będzię miał możliwość w jakikolwiek sposób zobaczyć nazwę tej zmiennej ? Bo jeśli nie będzie miał możliwości to przy wpisaniu http://strona.net/wartosc1 OR 1=1/ wyskoczy błąd serwera gdyż pusty znak nie jest uwzględniony w [0-9a-z] i SQL Injection się nie powiedzie. Czy się myle ?

Napisany przez: Rzast 11.09.2006, 15:36:07

Ja bronię się trochę inaczej:
robię zapytanie typu

  1. <?php
  2. $sql='SELECT id,login FROM baza WHERE haslo="'.http://www.php.net/md5($_POST['haslo']).'"';
  3. $wynik=http://www.php.net/mysql_fetch_row($sql);
  4. if ((http://www.php.net/mysql_num_rows($sql)==1) && ($wynik[1]==$_POST['login'])){
  5. //Zalogowany
  6. $_Session['id']=$wynik[0];
  7. //Dalsze czynności....
  8. }else{
  9. //Jeszcze raz, bo nie udało się. Można ewentualnie wypisać, czy to zły login, czy 
    też hasło....
  10. }
  11. ?>


Funkcja haszująca MD5 gwarantuje, że treść wysłana w zapytaniu do bazy NIE będzie żadnym poleceniem. Jeżeli hasło istnieje (albo ktoś trafił na ciąg po haszowaniu dajacy jakiśtam rezultat, który jest w bazie), to sprawdzamy login z zapodanym wcześniej. Takie podejście od tyłu winksmiley.jpg Najczęściej wykorzystywane jest pole [login] do takich zabaw jak SQL Injection. A w tym przypadku nie ma na to szans.

Proszę o ocenę pod względem bezpieczeństwa...

PS> Hasła w bazie są oczywiście shaszowane aarambo.gif
PS2> w zmiennej $sql nie ma żadnych Backslashy (czyli [\])

Napisany przez: MatheW 11.09.2006, 16:49:54

Super - sprawdzasz tylko po haśle - więc zakladasz ze kazdy user MUSI miec inne haslo - zle - wybierz po loginie (ktory winien byc unikalny) i potem czy hash hasła = shaszowane wczesniej haslo z bazy.

Napisany przez: Rzast 12.09.2006, 07:58:38

@MatheW: Właśnie chodziło mi o to, żeby nie dopuścić do bazy danych zawartości $_POST['login']. Bezpieczne jest zhaszowane hasło

Racja, nie wpisałem ostatniej modyfikacji....

  1. <?php
  2. $sql='SELECT id,login FROM baza WHERE haslo="'.http://www.php.net/md5($_POST['haslo']).'"';
  3. $wynik=http://www.php.net/mysql_query($sql);
  4. if (http://www.php.net/mysql_num_rows($wynik)>=1){
  5. $ok=true;
  6. while (($dana=http://www.php.net/mysql_fetch_row($wynik))&&($ok==true)){
  7. if ($dana[1]==$_POST['login'])){
  8. //Zalogowany
  9. $ok=false;
  10. $_Session['id']=$wynik[0];
  11. //Dalsze czynności....
  12. }
  13. }
  14. }else{
  15. //złe hasło
  16. }
  17. ?>

Hasła mogą być takie same, ale różne loginy (sprawdzane przy rejestracji) jednoznacznie wskazują na dane konto. Rkingsmiley.png

Napisany przez: MatheW 26.09.2006, 16:37:19

Cytat
@MatheW: Właśnie chodziło mi o to, żeby nie dopuścić do bazy danych zawartości $_POST['login']. Bezpieczne jest zhaszowane hasłoRacja, nie wpisałem ostatniej modyfikacji....
To co zrobiłeś jest beznadziejne - pobierasz z bazy uzytkowników którzy mają takie same hasła! A takie same hasła moze miec paru userow. Wiec wynik moze zwrocic ich kilku - skad wiesz ktory to. W Twoim przpadku addslashes zupełnie wystarczy. Oczywiście przy rejestracji najlepiej zabron pewnych znakow w loginie, zeby nie sprawial trudnosci - najlepiej zostawic znaki alfanumeryczne, podkreslenia i spacje

Napisany przez: Rzast 28.09.2006, 10:24:12

MatheW: Przyjżałeś się? Ale tak naprawdę uważnie?
Piszesz:

Cytat
To co zrobiłeś jest beznadziejne - pobierasz z bazy uzytkowników którzy mają takie same hasła! A takie same hasła moze miec paru userow. Wiec wynik moze zwrocic ich kilku - skad wiesz ktory to.

a w kodzie jest:
  1. <?php
  2. if (http://www.php.net/mysql_num_rows($wynik)>=1){//jeżeli jest jakiś user (userzy) o takim haśle...
  3. $ok=true; //ustaw zmienną pomocniczą 
  4. while (($dana=http://www.php.net/mysql_fetch_row($wynik))&&($ok==true)){// dekoduj wynik z bazy dopóki pomocnicza prawdziwa
  5. if ($dana[1]==$_POST['login'])){ //jeżeli jest taki login to...
  6. //Zalogowany
  7. $ok=false; //skasuj pomocniczą
  8. $_Session['id']=$wynik[0]; //ustaw sesję
  9.  ...itd
  10. ?>

Czy wytłumaczyć dokładniej?
pozdrawiam

Napisany przez: eai 29.09.2006, 09:26:34

To jest bez sensu... a jeśli w bazie masz założymu 1 000 000 userów gdzie 10 000 na takie same hasło... Wtedy zalogowanie jednocześnie 1 000 userów, obciąży serwer. Po co tak robić?

Lepiej zrobić tak:
Login: [A-Za-Z0-9_-]
Hasło: tu już dowolnie i tak hasło trzymamy w bazie jako md5, wiec dodanie jakichkolwiek znaków ' " które mogłby by spowodować zmiane zapytania nic tu nie dadzą.

Po co sobie utrudniać życie i kombinować?

Napisany przez: paziek 29.03.2007, 20:20:36

Witam,

Czytam wątek już drugi raz (pierwszy raz ok. 3 miesiące temu, kiedy php to było dla mnie jeszcze nowość) i dalej nie jestem pewien co do sposobu zabezpieczenia.


Do tej pory używałem ctype_digit() do liczb, oraz htmlspecialchars() do reszty.
Ogólnie to wolałbym używać zamiast htmlspecialchars() funkcję addslashes(), ale kilka postów zamieszczonym na tym forum skutecznie zniechęciło mnie do niej. A mianowicie teksty typu: "A ja podwójnie robię addslashes", jakieś wyrażenia regularne, cuda nie widy..

Czy istnieje możliwość na 'obejście' addslashes()? Tzn przekazać do zmiennej nie wyeskejpowany cudzysłów (podwójny czy pojedyńczy) ?


ps. addslashes() dlatego, że zauważyłem iż MySQL wykonuje swego rodzaju stripslashes() na przychodzących danych, więc oszczędza to miejsce i nie trzeba dekodować później danych z wartości html'owych.


I o co chodzi z tym poruszeniem na temat UNION?
Przeczytałem artykuł http://www.really-fine.com/SQL_union.html i mniej więcej wiem na czym to polega..
Jeśli wyeskejpuje zmiennę lub sprawdze czy są liczbowe, to powinienem być bezpieczny przed tym, racja?



Nie potrzebuję alternatyw do wspomnianych funkcji (czytać manuala potrafię tongue.gif ) , jedynie potwierdzenie od kogoś doświadczonego, czy addslashes() to 100% zabezpieczenie przed cudzysłowiami (nie SQL Injection).
Oczywiście, post Nospora polecający używanie addslashes() przy zmiennych tekstowych daje mi 99% pewności, iż to tylko moja paranoja, ale ten 1% to o 1% za dużo niepewności smile.gif


Swoją drogą, czy składnia typu

  1. <?php
  2. "SELECT * FROM table WHERE cos = '".$_POST."'";
  3. ?>

[bez tych slashy..]
ma jakieś walory pod względem bezpieczeństwa? Używam ".$zmienna." tylko dlatego, że edytor mi wtedy ładnie koloruje taką składnie, ale kto wie, może to coś daje 'gratis'? Wydajność? Bezpieczeństwo?



Dzięki z góry za pomoc w tej sprawie,
Paziek.

Napisany przez: Jarod 29.03.2007, 21:18:38

Cytat(paziek @ 29.03.2007, 19:20:36 ) *
Czy istnieje możliwość na 'obejście' addslashes()? Tzn przekazać do zmiennej nie wyeskejpowany cudzysłów (podwójny czy pojedyńczy) ?

http://pl.php.net/manual/pl/function.mysql-escape-string.php

Napisany przez: paziek 29.03.2007, 21:52:15

Jarod: Dzięki ale nie dzięki ;o

Po pierwsze, cytujesz fragment postu i odpowiadasz na ten fragment (nawet jak by go wyjąć z kontekstu) czymś zupełnie innym :/ Zadatki na polityka tutaj widzę sadsmiley02.gif

Po drugie, tak jak napisałem, nie potrzebuje alternatywy do wspomnianych funkcji, ani gotowego rozwiązania na SQL Injection, koduje swoje aplikacje 'w miarę potrzeb' i potrafię posługiwać się manualem oraz goglami.
Przeczytałem już tyle artykułów oraz postów na forum, że wiem wystarczająco dużo na ten temat.



Chciałem się tylko dowiedzieć, czy istnieje jakiś bug, dziura, sposób, cokolwiek w funkcji addslashes(), który umożliwiłby wprowadzenie do zmiennej nie wyeskejpowanego cudzysłowia, bo nieco zwątpiłem w tą funkcję, zapewne nadinterpretacją kilku postów. To (prawie) wszystko.


Jakiś .. chakier się wypowie? snitch.gif

Napisany przez: akubiczek 6.04.2007, 13:14:58

Tak, istnieje taki bug. Nazywa się on:

$slashedVar=str_replace('\"','"',addslashes($sourceVar));

Tylko to programista musiałby go popełnić.. smile.gif Moim zdaniem, masz faktycznie paranoję tongue.gif


I na koniec: Jarod dobrze ci napisał - do escepowania zmiennych, które umieszczasz w zapytaniu SQL służy mysql_real_escape_string().

I na drugi koniec: ani addslashes() ani htmlspecialchars() nie służą do tego, do czego próbujesz je użyć (patrz punkt wyżej). htmlspecialchars() stosujesz w momencie wyświetlania treści na stronie, aby zabezpieczyć się przed złośliwym działaniem właśnie na poziomie przeglądarki (HTMLa) a nie bazy.

Napisany przez: L00zak 27.04.2007, 23:41:16

php5, pdo i podpinanie, a skończą się wam problemy z addslashes(), mysql_real_escape_string() i magic_quotes tongue.gif

Napisany przez: radex_p 6.05.2007, 17:53:23

Czy ktoś, kto się na tym zna może mi odpowiedzieć:

Jest tu wiele sprzecznych wypowiedzi

I czy "mysql_escape_string" w całkowicie wyklucza możliwość przeprowadzenia ataku SQL Injection, czy konieczne są jakieś modyfikacje zapytań (jak w pierwszym poście)? I proponuję administracji posprzątać temat, bo po przeczytaniu nic mi się kupy nie trzyma:P

Napisany przez: Jarod 6.05.2007, 17:57:26

Stosuję mysql_escape_string + filtrowanie danych i moim zdaniem jest to w zupełności bezpieczne.

A przy okazji jak filtrować na poziomie postgresql'a?

EDIT: @radex_p - bo nie znalazłem odpowiednika dla postgresql'a

Napisany przez: radex_p 6.05.2007, 19:15:35

skoro mysql_escape_string (nie licząc standardowych procedur filtrujących) jest good, to czemu nie użyć podobnej funkcji przeznaczonej dla postgre'a, lub PHP'owskiej wbudowanej?

Napisany przez: sopel 7.05.2007, 00:05:09

są sytuacje kiedy da się ją obejśc, nie jest tajemnicą że najlepiej stosować tzw. prepared statements. więcej: http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.html

Napisany przez: orglee 12.05.2007, 17:08:15

Witam.
Przeczytałem ten temat dwa razy. Dwa razy dostałem oczopląsu i palpitacji serca.
Temat niby jeden, ale skaczecie od wątku do wątku. Oszaleć można.
Postaram się w skrócie podsumować poprzednie wypowiedzi, zanim przejdę do swojego pytania,
jako że poprzednie podsumowania ułatwiły mi czytanie tego wątku.

1. Należy sprawdzać czy liczba jest liczbą, to znaczy że jeśli przesyłamy urlem id rekordu z tabeli musimy sprawdzić czy jest on liczbą.
2. Dodawanie ukośników przez addslashes() lub mysql_real_escape_string() w zmiennych typu string.
(Z tekstu tutaj wyczytałem że mysql_real_escape_string() robi to lepiej. Czy tak jest i dlaczego ?)
3. Ostatnim problemem z SQL-Injection jakiego zdołałem się tutaj doczytać jest słowo kluczowe SQL 'UNION'
dzięki któremu można pobrać więcej danych.

W mojej opinii nie należy trząść portkami przed UNION jeśli zamiast gwiazdki po SELECT wypisuje się nazwy pól które chce się pobrać z tabeli. Jeśli się mylę poprawcie mnie.

Moje pytanie(oprócz tego w punkcie drugim):
Chciałbym się dowiedzieć jak mam usunąć ze zmiennej wszystkie spacje nie tylko te z przodu i z tyłu - trim()
Mam z tym problem bo spacje można zapisać jeszcze w inny sposób niż ' ' a ja niestety na tych metodach zapisu się nie znam.

Poniżej przedstawiłem swoją metodę dodającą do łańcucha znaków wsteczne ukośniki.
Prosiłbym o jakieś komentarze czy jest ona bezpieczna i czy zamiast addslashes powinienem zastosować mysql_real_escape_string()

  1. <?php
  2. public function sanitize($input, $force=false)
  3. {
  4. if(!http://www.php.net/get_magic_quotes_gpc() || $force == true)
  5. {
  6. if(http://www.php.net/is_array($input))
  7. {
  8. foreach($input as $key => $val)
  9. {
  10. $input[$key] = http://www.php.net/addslashes($val);
  11. }
  12. return $input;
  13. } else {
  14. return http://www.php.net/addslashes($input);
  15. }
  16. } else {
  17. return $input;
  18. }
  19. }
  20. ?>

Dziękuję za przeczytanie i odpowiedź na te moje wypociny winksmiley.jpg

Napisany przez: Kicok 12.05.2007, 17:24:00

Cytat
Prosiłbym o jakieś komentarze czy jest ona bezpieczna

To zależy gdzie się jej użyje:
  1. <?php
  2.  
  3. // 1, zabezpieczone przed SQL injection
  4. $_GET['name'] = $this->sanitize( $_GET['name'] );
  5. http://www.php.net/mysql_query( "SELECT * FROM some_table WHERE name = '{$_GET['name']}'" );
  6.  
  7.  
  8. // 2, niezabezpieczone przed SQL injection
  9. $_GET['sort'] = $this->sanitize( $_GET['sort'] );
  10. http://www.php.net/mysql_query( "SELECT * FROM some_table ORDER BY {$_GET['sort']}" );
  11.  
  12. ?>



A co do usuwania spacji to nie rozumiem problemu. Chodzi ci o to, że chcesz usunąć: ' ', '&nbsp;', '%20', itp? Tylko po co, skoro 2 i 3 przykład sam z siebie w spację się nie zamieni...
No ale zawsze możesz użyć http://pl.php.net/str_replace

Napisany przez: orglee 12.05.2007, 17:36:48

Czyli nie ma się co zastanawiać tylko walnąć str_replace na ' '.
Ok dzięki.

Co do mysql_real_escape_string() to poniżej jest cytat z postu http://forum.php.pl/index.php?s=&showtopic=23258&view=findpost&p=172835 calls MySQL's library function mysql_escape_string, which prepends backslashes to the following characters: NULL, \x00, \n, \r, \, ', " and \x1a.

addslashes() : Returns a string with backslashes before characters that need to be quoted in database queries etc. These characters are single quote ('), double quote ("), backslash (\) and NUL (the NULL byte).

Napisany przez: SirZooro 14.06.2007, 18:18:29

Cytat(orglee @ 12.05.2007, 17:08:15 ) *
Witam.
Przeczytałem ten temat dwa razy. Dwa razy dostałem oczopląsu i palpitacji serca.
Temat niby jeden, ale skaczecie od wątku do wątku. Oszaleć można.
Postaram się w skrócie podsumować poprzednie wypowiedzi, zanim przejdę do swojego pytania,
jako że poprzednie podsumowania ułatwiły mi czytanie tego wątku.

Też mam (niestety) podobne odczucia...

Cytat(orglee @ 12.05.2007, 17:08:15 ) *
1. Należy sprawdzać czy liczba jest liczbą, to znaczy że jeśli przesyłamy urlem id rekordu z tabeli musimy sprawdzić czy jest on liczbą.

Tak. Warto użyć do tego wyrażenia regularnego takiego jak to:
Kod
^[1-9][0-9]{0,8}$

Powyższe wyrażenie sprawdza jeszcze ilość cyfr - raczej mało kto będzie miał ponad miliard rekordów smile.gif

Cytat(orglee @ 12.05.2007, 17:08:15 ) *
2. Dodawanie ukośników przez addslashes() lub mysql_real_escape_string() w zmiennych typu string.
(Z tekstu tutaj wyczytałem że mysql_real_escape_string() robi to lepiej. Czy tak jest i dlaczego ?)

mysql_real_escape_string() uwzględnia zestaw znaków używany podczas łączenia się z bazą danych, więc będzie też poprawnie działać jeżeli używasz np. Unicode.

Co do ukośników - z tego co się orientuję, to kilka lat temu MySQL był wyjątkiem i ich wymagał, a inne bazy danych z którymi miałem do czynienia (PostgreSQL, MS SQL, Oracle) akceptowały podwójny apostrof (dwa apostrofy obok siebie). Obecnie także MySQL je akceptuję. Ja tutaj zalecam używanie mysql_escape_string() (dla MySQL) i pg_escape_string() (dla PostgreSQL), ew. podobnych funkcji (jest to opisane w dokumentacji PHP).

Przed wywołaniem tych funkcji warto także sprawdzić czy string wpisany do formularza nie jest za długi, i go obciąć. Warto także wywołać trim() - raczej nie ma sensu przechowywać dodatkowych spacji, które i tak nie będą wyświetlone.
Cytat(orglee @ 12.05.2007, 17:08:15 ) *
3. Ostatnim problemem z SQL-Injection jakiego zdołałem się tutaj doczytać jest słowo kluczowe SQL 'UNION'
dzięki któremu można pobrać więcej danych.

W mojej opinii nie należy trząść portkami przed UNION jeśli zamiast gwiazdki po SELECT wypisuje się nazwy pól które chce się pobrać z tabeli. Jeśli się mylę poprawcie mnie.

Przy UNION jest tylko ważne aby zgadzała się ilość kolumn i ich typy były zgodne, dlatego "SELECT *" przed niczym nie chroni. Dlatego np. takie zapytanie zadziała:
Kod
SELECT * FROM produkty WHERE id=0 UNION SELECT login, haslo, 0, 0, 0 FROM uzytkownicy


Cytat(orglee @ 12.05.2007, 17:08:15 ) *
Moje pytanie(oprócz tego w punkcie drugim):
Chciałbym się dowiedzieć jak mam usunąć ze zmiennej wszystkie spacje nie tylko te z przodu i z tyłu - trim()
Mam z tym problem bo spacje można zapisać jeszcze w inny sposób niż ' ' a ja niestety na tych metodach zapisu się nie znam.

Użyj czegoś takiego:
Kod
echo preg_replace('/\s+/', ' ', ' a   b   c  ');

To polecenie zamienia kilka spacji (i innych "białych" znaków) na jedną spację. Nie usuwa ono jednak całkowicie spacji z początku i końca - trzeba albo to wyrażenie poprawić, albo dodatkowo użyć trim(). Jeżeli chcesz natomiast wyciąć wszystkie spacje, usuń spację z drugiego parametru.

Ktoś wcześniej wspomniał też o mod_rewrite i .htaccess - można tego użyć jako dodatkowego mechanizmu zabezpieczeń, trzeba tylko pilnować aby nigdzie na stronach nie pojawił się rzeczywisty adres stron w serwisie. Poza tym warto także pamiętać że zawsze można próbować zgadnąć nazwy stron i nazwy parametrów.

Poza tym jest jeszcze kwestia znaku komentarza "--" w SQL, i tzw. ataki wielofazowe, ale o tym nie chce mi się drugi raz pisać - zerknijcie sobie tutaj: http://www.poradnik-webmastera.com/artykuly/bazy_danych/sql_injection.php smile.gif

Napisany przez: bełdzio 15.06.2007, 16:54:59

tylko po co te regexpy?

Napisany przez: orglee 15.06.2007, 18:33:41

Cytat(bełdzio @ 15.06.2007, 17:54:59 ) *
tylko po co te regexpy?
Właśnie po co skoro istnieje filter_ input()" title="Zobacz w manualu PHP" target="_manual

Napisany przez: Nightmare 16.06.2007, 11:45:53

Po to żeby ci z php4 też mieli bezpieczne formularze winksmiley.jpg

Napisany przez: bełdzio 16.06.2007, 16:21:03

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

?

Napisany przez: Sedziwoj 16.06.2007, 16:29:43

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 ( !http://www.php.net/empty($_GET['id']) && http://www.php.net/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. ?>

Napisany przez: Black-Berry 26.06.2007, 09:51:43

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 (!http://www.php.net/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 = http://www.php.net/mysql_query ( $query ) or http://www.php.net/die ( _MYSQL_ERROR_.":".http://www.php.net/mysql_error());
  19. $row = http://www.php.net/mysql_fetch_array($result, MYSQL_ASSOC);
  20. $this->user_name = $row["nazwa_uzytkownika"];
  21. }
  22.  
  23. function drop()
  24. {
  25. http://www.php.net/echo $this->user_name;
  26. }
  27. }
  28. ?>
Czy ktoś będzie się mógł mi włamać przy takim kodzie?

Napisany przez: Sedziwoj 26.06.2007, 14:26:32

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 (!http://www.php.net/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

Napisany przez: Black-Berry 3.07.2007, 09:37:48

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.http://forum.php.pl/index.php?showtopic=71985&hl=

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.

Napisany przez: bełdzio 3.07.2007, 12:59:08

  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

Napisany przez: Black-Berry 4.07.2007, 09:29:08

dry.gif że też ja na to nie wpadłem.... 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 ( !http://www.php.net/empty( $a_value ) && http://www.php.net/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 http://www.php.net/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;

Napisany przez: bełdzio 4.07.2007, 10:59:09

w mysql_valid_string return by się przydał

Napisany przez: LEW21 24.07.2007, 14: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

Napisany przez: Sedziwoj 25.07.2007, 08:09:25

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. http://www.php.net/var_dump($intT);
  5. if( http://www.php.net/ctype_digit($strIn) ){
  6.  http://www.php.net/echo "Tylko cyfry";
  7. }else{
  8.  http://www.php.net/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.

Napisany przez: NoiseMc 7.08.2007, 05:27:11

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.

Napisany przez: Sedziwoj 7.08.2007, 18:53:15

@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.

Napisany przez: NoiseMc 9.08.2007, 16:24:55

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 smile.gif

Napisany przez: Sedziwoj 9.08.2007, 18:16:26

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

Napisany przez: NoiseMc 9.08.2007, 19:10:19

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 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.

Napisany przez: Endzio 11.09.2007, 06:07:16

Witam.
Używam kodu

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

Oraz standardowe pytanie biggrin.gif
Czy moje rozwiązanie jest bezpieczne, co byście zmienili?

Napisany przez: Black-Berry 11.09.2007, 11:36:35

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

Edit: błędy.

Napisany przez: Sedziwoj 11.09.2007, 13:16:12

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( !http://www.php.net/empty($cos) && http://www.php.net/ctype_digit($cos ) ){
  4.  http://www.php.net/echo "tak";
  5.  $int = (int)$cos;
  6. }else{
  7.  http://www.php.net/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.

Napisany przez: piter2k1 14.09.2007, 12:42:35

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'\";
?>

Napisany przez: Kicok 14.09.2007, 13:02:23

Cytat
Ja zrobił bym po prostu:


A co zwraca funkcja http://pl.php.net/settype? Chyba pomyliło Ci się z http://pl.php.net/intval ;]

Napisany przez: templar 30.09.2007, 21:42:27

Cytat(Najki @ 25.11.2004, 00:13:57 ) *
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 = "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. Numer ID warto ustawiać w sposób $_GET['id'], lub $_POST['id'], można też ustawić go w nast. sposób:
  1. <?php
  2. $id = (int)$_GET['id'];
  3. ?>


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.


Ależ problem ;->.

  1. <?php
  2. function SecureQuery($q, $type)
  3. {
  4. switch($type)
  5. {
  6. case 'string':
  7. if(!http://www.php.net/preg_match('[a-z0-9]', $q)) $ret = false;
  8. else $ret = true;
  9. break;
  10.  
  11. case 'int':
  12. if(!http://www.php.net/is_numeric($q)) $ret = false;
  13. else $ret = true;
  14. break;
  15. }
  16. return $ret;
  17. }
  18. ?>


I potem w kodzie, przed zapytaniami:

Dla URL'i z tekstem i cyframi:

  1. <?php
  2. $nazwa_uzytkownika = $_GET['username'];
  3.  
  4. if(SecureQuery($nazwa_uzytkownika, 'string'))
  5. http://www.php.net/mysql_query('SELECT * FROM `db_name` WHERE `user_name` = "'.$nazwa_uzytkownika.'"');
  6. else http://www.php.net/die('error');
  7. ?>


A dla URLi z cyframi zastosujemy

  1. <?php
  2. $ilosc = $_GET['ilosc'];
  3.  
  4. if(SecureQuery($ilosc, 'int'))
  5. http://www.php.net/mysql_query('SELECT * FROM `db_name` WHERE `ilosc` = "'.$ilosc.'"');
  6. else http://www.php.net/die('error');
  7. ?>


Zawsze trzeba kodowac w mysl zasady KISS - (keep it stupid simple).

Pozdrawiam.

Napisany przez: bełdzio 30.09.2007, 22:34:53

@templar a po co te regExpy? nie lepiej skorzystać z ctype?

Napisany przez: Regyam 4.11.2007, 14:46:49

a co z sql injection jezeli mam linki w mod_rewrite i nie da sie wpisac slowa bo mam zdefiniowana wartosc ([0-9]*). Chyba nie da sie tego w jakikolwiek sposob ominac bo wywala error 404, co o tym myslicie?

Napisany przez: bełdzio 4.11.2007, 15:40:32

zawsze istnieje możliwość odwołania się bezpośrednio do plików, ale to też można wyeliminować smile.gif zerknij tu -> http://www.beldzio.com/modrewrite-jako-pierwsza-linia-obrony-przed-wstrzyknieciami.freez

Napisany przez: rzymek01 14.11.2007, 20:55:27

Cytat(bełdzio @ 30.09.2007, 22:34:53 ) *
nie lepiej skorzystać z ctype?

Moim zdaniem lepiej skorzystać jest z is_numeric.
Kiedyś testowałem te funkcje i ctype okazało się wolniejsze w działaniu smile.gif

Napisany przez: bełdzio 15.11.2007, 00:25:56

wg. manuala ctype jest szybsze, a raczej ich testy były dokładniejsze :-)

Napisany przez: Garrappachc 15.11.2007, 22:23:22

Co do samego początku tematu:

czy nie można przefiltrować apostrofów:

Kod
$login = str_replace("`", "", $login);
$login = str_replace("'", "", $login);

(ewentualnie wywalić błędu)?
A tak poza tym to przecież MySQL odpowiednio koduje hasła:
  1. UPDATE `users` SET `haslo`=(PASSWORD('$pass')) WHERE `id`='$id'


więć teoretycznie w czym problem?...

Napisany przez: Kicok 15.11.2007, 23:08:17

Cytat
A tak poza tym to przecież MySQL odpowiednio koduje hasła:
  1. UPDATE `users` SET `haslo`=(PASSWORD('$pass')) WHERE `id`='$id'



więć teoretycznie w czym problem?...


Problem jest w tym, że wysyłając formularzem odpowiedni ciąg znaków mogę to zapytanie przerobić na:
  1. UPDATE `users` SET `haslo`=(PASSWORD('jakies_haslo')), `is_admin`=1 WHERE `id` = 123 -- ')) WHERE `id` = ''


A co do apostrofów, to ich użycie nie oznacza zawsze próby włamania. Zamiast usuwania ich albo wyrzucania błędu wystarczy umieścić przed nimi znaki ucieczki.

Napisany przez: marcio 23.12.2007, 23:40:39

A wiec po Przeczytaniu chyba juz 10 raz tego tematu sam juz nie wiem co uzywac dla zmienne $_GET['id'] mam dawac
*(int)
*intval()
*Is_numeric()
*is_integer
??Sam juz nie wiem co jest najlepsze do rzutowania typu cyfrowego

Napisany przez: Kicok 2.01.2008, 11:10:54

http://pl.php.net/is_integer nigdy nie zadziała dla $_GET, $_POST czy $_COOKIE. Dane w tych tablicach są zawsze typu string lub array


Stosuj rzutowanie: http://pl.php.net/intval lub (int) i sprawdzaj czy zapytanie zwróciło jakieś dane. Jeśli nie, to wyświetlasz informację "nie ma strony o podanym ID", "nie ma takiego newsa", "komentarz nie istnieje lub został usunięty" czy jaką tam chcesz.

Napisany przez: pytajnik2 2.01.2008, 18:06:56

Witajcie,
a co myślicie o tym?
http://axelpl.wordpress.com/2008/01/01/uniwersalne-zabezpieczenie-przed-sql-injection-i-xss/#more-3

Napisany przez: bełdzio 2.01.2008, 20:29:42

patrzac na szybko to nic ciekawego smile.gif z tego co widze to nawet nie broni przez standardowym 1 =1 smile.gif

Napisany przez: pytajnik2 2.01.2008, 20:35:44

no ale jak się ma w wszystkie pisywane przecież zmienne w apostrofach np tak
select * from ... where cos = '$_GET['cos']'
to obroni co nie?
no i nie da sie uzyc select, union oraz exec. a to dopisanie 1 = 1 to chyba zadziala jesli zmienna nie jest w apostrofkach?

Napisany przez: bełdzio 3.01.2008, 00:03:29

wszystko zalezy od konkretnego kodu, najlepsze zabezpieczenie to pisanie porzadnego kodu, a nie bawienie sie w polsrodki

Napisany przez: kilas88 9.02.2008, 03:27:22

Cytat(Najki @ 6.12.2004, 09:29:56 ) *
Owszem dodaje, ale chyba tylko, gdy na serwerze jest włączone <span style="font-weight: bold;">magic_quotes_gpc</span> ?
A jeśli nie to jakim prawem kolega mi się włamał? snitch.gif


Znalazłem taką funkcję odnośnie tego problemu.
  1. <?php
  2. function stripMagicQuotes($var){
  3. if(http://www.php.net/get_magic_quotes_gpc()){
  4. return http://www.php.net/stripslashes($var);
  5. }else{
  6. return $var;
  7. }
  8. }
  9. ?>

Przydatne porady smile.gif

Napisany przez: specialplan 10.03.2008, 12:27:05

Cytat(kilas88 @ 9.02.2008, 04:27:22 ) *
Znalazłem taką funkcję odnośnie tego problemu.
  1. <?php
  2. function stripMagicQuotes($var){
  3. if(http://www.php.net/get_magic_quotes_gpc()){
  4. return http://www.php.net/stripslashes($var);
  5. }else{
  6. return $var;
  7. }
  8. }
  9. ?>

Przydatne porady smile.gif


To ze zrodel PHP-Fusion?

Napisany przez: lucca 10.03.2008, 18:51:04

Witka!

Mam pytanie odnośnie SQL Injection.

Wszystkie dane przepuszczam przez filtry, nie dopuszczam, żednych danych do bazy bez obróbki.

Case study:
Mam formularz rejestracji, próbowałem w nim wpisać

  1. "; DELETE * FROM users;


Zwrócił:
There was an error: Invalid User Name Specified and try again.

Czy to znaczy, że skrypt jest jako tako bezpieczny? Macie może jakieś metody, żeby sprawdzić dany skrypt?

Napisany przez: kilas88 10.03.2008, 22:35:51

Cytat(specialplan @ 10.03.2008, 12:27:05 ) *
To ze zrodel PHP-Fusion?

Źródło: php.net/mysql_escape_string. W komentarzach ktoś zapodał, więc skopiowałem - być może komuś się przyda. Pozdrawiam.

Napisany przez: radex_p 11.03.2008, 19:02:00

Mam takie pytanie: "Od zawsze" bronię się przeciwko atakom SQL Injection, w ten sposób:

- mysql_real_escape_string
- apostrof na wyrażenie( bo np. gdyby po czyimś wstrzyknięciu było "WHERE news_title = costam AND (...) --" to samo mysql_escape_string by nic nie dało.)

Ostatnio czytałem bardzo wiele artykułów na temat bezpieczeństwa skryptów etc. i co raz bardziej mam wrażenie, że to co robię to za mało.

Wiem, że pytanie jest głupkowate i "mogłem uważniej czytać", ale kiedyś czyjś artykuł wciska mi kit, że trza zrobić cośtam (a to sprawy bezpieczeństwa), a ja tego nie robię to strasznie mnie to stresuje, bo zaczynam wierzyć, że to prawda tongue.gif

Napisany przez: bim2 11.03.2008, 19:09:01

Czego jeszcze Ci brakuje tongue.gif Wystarczy ze w zmiennych który wstrzykujesz w zapytanie "SELECT * FROM lol WHERE if='$id'" dajesz ' lub jeśli to ma być int dajesz (int)$_GET['ehh']; Tyle starcza... :] No i usuwanie wszelkich scripts embed ;P

Napisany przez: radex_p 11.03.2008, 19:11:05

Jakich znowuż scripts embed?

Napisany przez: empuszek 25.03.2008, 11:49:16

Cytat(bim2 @ 11.03.2008, 19:09:01 ) *
Czego jeszcze Ci brakuje tongue.gif Wystarczy ze w zmiennych który wstrzykujesz w zapytanie "SELECT * FROM lol WHERE if='$id'" dajesz ' lub jeśli to ma być int dajesz (int)$_GET['ehh']; Tyle starcza... :] No i usuwanie wszelkich scripts embed ;P



Nareszcie ktoś to jasno napisał.

PS Co to jest Sript Embed?

Napisany przez: bełdzio 25.03.2008, 12:58:54

zapewne chodzi o xss smile.gif

Napisany przez: Xniver 29.03.2008, 20:49:17

Cytat
PS Co to jest Sript Embed?

Chodzi o tagi HTML <script> i <embed>. Wystarczy użycie funkcji strip_tags albo htmlspecialchars

Napisany przez: gandziorz 6.04.2008, 22:10:06

Witam,
Przeczytałem temat przyklejony. I nikt nie sprecyzował jak można się uchronić przed union.
Napisałem taką funkcję:

  1. <?php
  2. function filtr ($zmienna) {
  3. $zmienna = http://www.php.net/mysql_real_escape_string($zmienna); //zmienia na zmienna z znakami unikowymi
  4. $zmienna = http://www.php.net/htmlspecialchars($zmienna, ENT_QUOTES); //zmienia znaki html
  5. return $zmienna;
  6. }
  7. ?>

Tylko tak naprawdę nic nie wnosi ciekawego bo owszem zabezpieczy ale jedynie przed prostymi operacjami. Ale co jeśli ktoś użyje union?
Nie poskutkuje bo przecież przy UNION nie trzeba dawać splash'y.

Wiadomo również jak jest przy liczbach można dać INT i dopisać że jeżeli jest odstęp to nie ma tego brać pod uwagę.
np.
  1. <?php
  2. strona.php?id=3 or 1=1
  3. Pobierze wtedy tylko 3.
  4. ?>


Dalej nie wiem co z union?

Napisany przez: Sedziwoj 6.04.2008, 22:31:32

Myślałem że w przyklejonych ma być jakiś porządek, a tu burdel się robi...
Ograniczenie się do mysql, do tego było pisane co z union.

PS
spróbuj ?id=3%20or%20id%3d4 i analogicznie union jak nie sprawdzisz czy id to liczba, a string'a nie dasz w apostrofach.

Napisany przez: marcio 6.04.2008, 22:34:11

Dajesz np na zmienne z get'a prosty str_replace np tak

  1. <?php
  2. $id = $_GET['id'];
  3. $nowy_id = http://www.php.net/str_replace("union", "", $id);
  4. ?>

Lub dajesz preg_match + system bledow czy cos w tym stylu lub spradzasz czy zmienna id jest liczba
  1. <?php
  2. if(http://www.php.net/is_integer($_GET['zmienna'])) {
  3. //dzialania jak wszystko ok
  4. }
  5.  
  6. else http://www.php.net/echo('Blad proba wlamania');
  7. ?>

Co do strongow zastosuj pierwsza metode

Edit sedziwoj szybszy smile.gif

Napisany przez: Sedziwoj 6.04.2008, 22:56:04

@marcio

Do id jako liczby całkowitej dodatniej różnej od zera lepiej użyć kombinacji empty() || ctype_digit() -> niepoprawne id.
Co do string'ów to Twoja metoda jest do niczego, co jakbyś pamiętał już było wspominane w tym temacie, w ciągach zabezpiecza się przed znakami specjalnymi np. używając *_escape_string(), do tego w zapytaniu taki ciąg znaków musi być w znakach oznaczających ciąg znaków, dla MySQL, PostgeSQL itd. jest to najczęściej

  1. 'i to jest ciąg znaków dla bazy'

I jak to użyjesz nie wbiją się za pomocą "SQL Injection", ogólnie dla każdego typu danych sprawdza się czy jest to ten co chcemy, a potem robimy odpowiednie rzeczy z nim (właściwie to chyba tylko ciąg znaków wymaga, ale pewnie coś by się jeszcze znalazło)

Napisany przez: MalyKazio 20.04.2008, 15:24:35

Mam krótkie pytanie. Czy w przypadku używania MySQL lepszym jest używanie mysql_real_escape_string zamiast addslashes? Z tego co się zorientowałem jest to funkcja dedykowana dla tej bazy danych. Czy zatem warto otrzymane zmienne, przy włączonym magic_quotes przefiltrować z powrotem stripslashes i potem przez zapytaniem zastosować mysql_real_escape_string? Czy też jest to zupełnie bez sensu i lepiej zostawić tak jak jest a ewentualne mysql_real.* zostawić na wypadek wyłączonych magic_quotes?

Napisany przez: Crozin 20.04.2008, 16:05:44

Jeśli masz magic_quotes przepuść wszystkie dane (_POST, _GET i _COOKIE) przez stripslashes() a przed dodaniem do bazy użyj mysql_real_escape_string() (ponieważ ona escape'uje: \x00, \n, \r, \, ', " and \x1a )

Napisany przez: radex_p 9.05.2008, 18:15:23

Apostrofy na wyrażenie + mysql_real_escape_string wszystko rozwiązuje. Nie potrzebne są dodatkowe zabezpiecznie przeciwko np. UNION

Napisany przez: Jarod 10.05.2008, 19:22:55

Cytat(radex_p @ 9.05.2008, 17:15:23 ) *
Apostrofy na wyrażenie + mysql_real_escape_string wszystko rozwiązuje. Nie potrzebne są dodatkowe zabezpiecznie przeciwko np. UNION


Z czystej ciekawości, czy inne bazy rządzą się tymi samymi prawami?

Napisany przez: radex_p 10.05.2008, 19:30:07

to zależy od SQL a nie od typu bazy danych. Przynajmniej tak mi się wydaje.

Napisany przez: kilas88 30.05.2008, 11:02:53

Odnośnie bezpieczeństwa mam takie pytanie.. Gdzieś tam wyczytałem, że baza danych MySQLi jest szybsza, lepsza i bezpieczniejsza od bazy MySQL. Na czym te różnice w bezpieczeństwie polegają?

I ja dodam funkcję, której używam przy zabezpieczaniu się:

  1. <?php
  2. function escape_data ($data) {
  3.  http://www.php.net/global $dbc; // zmienna z przypisanym połączeniem do bazy mysql
  4.  if (http://www.php.net/ini_get('magic_quotes_qpc')) {
  5. $data = http://www.php.net/stripslashes($data);
  6.  }
  7.  return http://www.php.net/mysql_real_escape_string(http://www.php.net/trim($data), $dbc);
  8. }
  9. ?>


Oczywiście jeszcze sprawdzam czy pobierana jest liczba, czy string oraz w miarę możliwości - zakres liczb, długość stringów i wszelkie inne opcje.

Napisany przez: pyro 23.09.2008, 08:27:57

Cytat(marcio @ 6.04.2008, 23:34:11 ) *
Dajesz np na zmienne z get'a prosty str_replace np tak
  1. <?php
  2. $id = $_GET['id'];
  3. $nowy_id = http://www.php.net/str_replace("union", "", $id);
  4. ?>


www.bla.com/index.php?id=-1 UNI/**/ON SELECT 1;

Napisany przez: marcio 5.11.2008, 15:50:49

@Up oczywiscie znaki takie jak -,*,/ tez mozna usunac smile.gif

A co myslicie o takim nadzorowaniu http://www.uw-team.org/forum/viewtopic.php?f=5&t=6986

Napisany przez: pyro 12.11.2008, 13:30:27

Cytat(marcio @ 5.11.2008, 15:50:49 ) *
@Up oczywiscie znaki takie jak -,*,/ tez mozna usunac smile.gif

A co myslicie o takim nadzorowaniu http://www.uw-team.org/forum/viewtopic.php?f=5&t=6986


tak, sprobujesz je usunac wyrazeniami regularnymi to ja ci zaczne te znaki kodować, poza tym moge chciec umiescic takie znaki jak ukosniki i gwiazdki i co wtedy? dupne zabezpieczenie...

A nadzorowanie ktore podales napewno nie zabezpieczy 100%, moze tylko sluzyc jako dodatkowa nakladka bezpieczenstwa

Napisany przez: kayy 5.12.2008, 12:44:21

Pytanie;

jeżeli użyje takiego czegoś, to wszystkie zmienne z $_GET i $_POST będą zabezpieczone?

  1. <?php
  2. function safe() {
  3.  
  4. foreach($_POST as $key => $item) $_POST[$key] = http://www.php.net/addslashes($item);
  5.  
  6. foreach($_POST as $key => $item) $_POST[$key] = http://www.php.net/mysql_real_escape_string($item);
  7.  
  8. foreach($_POST as $key => $item) $_POST[$key] = http://www.php.net/htmlspecialchars($item, ENT_QUOTES);
  9.  
  10. foreach($_POST as $key => $item) $_POST[$key] = http://www.php.net/strip_tags($item);
  11.  
  12. foreach($_GET as $key => $item) $_GET[$key] = http://www.php.net/addslashes($item);
  13.  
  14. foreach($_GET as $key => $item) $_GET[$key] = http://www.php.net/mysql_real_escape_string($item);
  15.  
  16. foreach($_GET as $key => $item) $_GET[$key] = http://www.php.net/htmlspecialchars($item, ENT_QUOTES);
  17.  
  18. foreach($_GET as $key => $item) $_GET[$key] = http://www.php.net/strip_tags($item);
  19.  
  20.  
  21.  
  22.  
  23. }
  24. ?>

Napisany przez: Black-Berry 5.12.2008, 13:01:33

Takie coś będzie chyba szybsze i lepsze bo nie sprawdzasz słowa union a za pomocą union ktoś mi się włamał:

  1. <?php
  2. while ($key = http://www.php.net/key($_GET)) {
  3.        if (http://www.php.net/strlen($_GET[$key])>20
  4.        or http://www.php.net/eregi('union', $_GET[$key])
  5.        or http://www.php.net/eregi(';', $_GET[$key])
  6.        or http://www.php.net/eregi('=', $_GET[$key])) $_GET[$key] = 0;
  7.        http://www.php.net/next($_GET);
  8.    }
  9. ?>

Napisany przez: ucho 5.12.2008, 15:08:28

Cytat(radex_p @ 9.05.2008, 18:15:23 ) *
Apostrofy na wyrażenie + mysql_real_escape_string wszystko rozwiązuje. Nie potrzebne są dodatkowe zabezpiecznie przeciwko np. UNION

I to powinien być koniec dyskusji na temat zabezpieczania przed Sql Injection.
Na xss itp. wystarczy samo traktowanie wszystkich danych wejściowych za pomocą htmlspecialchars() - będzie po danych w bazie/na stronie widać czy ktoś próbował coś kombinować (co może być wadą lub zaletą smile.gif ale będzie to niegroźne.

kayy: poza tym żę twój kod nieco dziwnie wygląda to:
-najpierw strip_tags()
-potem htmlspecialchars()
-a tylko na danych które będziesz używał w zapytaniach mysql_real_escape_string()
addslashes jest niepotrzebne, *_real_escape_string wystarcza

A jeszcze w kwestii sql injection to powinno się używać przede wszystkim jakiegoś DBO, preapared statements, lub jakiejkolwiek biblioteki która daje coś w stylu PEARowego DB::quoteSmart ( escape i odpowiednia apostrofy dla stringa automatycznie niezależnie od bazy z której się korzysta)

Napisany przez: skowron-line 5.12.2008, 15:46:53

Cytat(kayy @ 5.12.2008, 12:44:21 ) *
Pytanie;

jeżeli użyje takiego czegoś, to wszystkie zmienne z $_GET i $_POST będą zabezpieczone?

  1. <?php
  2. function safe() {
  3.  
  4. foreach($_POST as $key => $item) $_POST[$key] = http://www.php.net/addslashes($item);
  5.  
  6. foreach($_POST as $key => $item) $_POST[$key] = http://www.php.net/mysql_real_escape_string($item);
  7.  
  8. foreach($_POST as $key => $item) $_POST[$key] = http://www.php.net/htmlspecialchars($item, ENT_QUOTES);
  9.  
  10. foreach($_POST as $key => $item) $_POST[$key] = http://www.php.net/strip_tags($item);
  11.  
  12. foreach($_GET as $key => $item) $_GET[$key] = http://www.php.net/addslashes($item);
  13.  
  14. foreach($_GET as $key => $item) $_GET[$key] = http://www.php.net/mysql_real_escape_string($item);
  15.  
  16. foreach($_GET as $key => $item) $_GET[$key] = http://www.php.net/htmlspecialchars($item, ENT_QUOTES);
  17.  
  18. foreach($_GET as $key => $item) $_GET[$key] = http://www.php.net/strip_tags($item);
  19. }
  20. ?>



zastosuj http://pl2.php.net/manual/pl/function.array-walk.php
i napisz sobie funckcje escapujaca zmienne

Napisany przez: mlattari 29.12.2008, 14:34:28

hmmm po co to wszystko? Dlaczego nie wystarczy zabawa z refererami...?



if (!$_SERVER['HTTP_REFERER']) die(''); // Nie wpisujemy niczego do paska adresów... :-))

No i oczywiście dodając funkcję sprawdzającą wszystkie dozwolone referery ..... no i ewentualnie (dla paranoików) żeby nie zawierały niczego poza dozwolonymi zmiennymi.....

To chyba jest pewna metoda? Czy nie?

albo.... he he zainstalować i poprawnie skonfigurować mod security :-)) prościej i pewniej! Bardzo skuteczna ochrona przed SQL Injection !

Napisany przez: bełdzio 29.12.2008, 20:01:48

1. niektore firewalle wycinaja refa
2. kryska z gazowni doda na swoim blogu linka do Ciebie, ów link nie bedzie wsrod Twoich dozwolonych referow i ciach wszyscy nowi userzy nie maja dostepu

Napisany przez: mlattari 30.12.2008, 01:18:00

Masz racje! ALE JESTEM GŁUPI! Ostatnio piszę same aplikacje gdzie ważny jest dostęp tylko ze specyficznych hostów i wszystko mi się pomieszało bo pracuję po 16 godzin dziennie :-))

Ale z tego wszystkiego chyba najbardziej niebezpieczne są łańcuchy zawierające wyrazy "UNION SELECT"... więc wystarczy odciąć takie wyrazy jak UNION, USER, PASSWORD, dokładnie tak jak to robi mod security 2 dla Apache (można przecież nieco podejrzeć jego reguły w ustawieniach i według nich napisać kod php).... a najlepiej to chyba odciać z referera wszystkie zastrzeżone wyrazy SQL....bo raczej nie bądą tam nam potrzebe :-)

Napisany przez: pyro 30.12.2008, 01:35:58

jasne, napiszesz odpowiedz na jakiegos posta (przez post) na jakims forum strzezonym przed wyrazami SQL.

"Oh! you can use UNION statement o merge the result! I'll show ya on my www, but wait... I forgot my PASSWORD to account... fuck"

po usunieciu tych wyrazow wyjdzie burdel w poście smile.gif

Napisany przez: mlattari 30.12.2008, 02:38:12

No już pisałem że jestem GŁUPI :-)

Bierzmy pod lupę cały kontekst np. "You can use UNION SELECT..." to nie to samo co "SELECT price FROM Items UNION SELECT PASSWORD FROM Users" :-) czy username%2b%27%20%27%2bpassword%20from%20users tymbardziej, że wiemy, że Items to nasza tabela i jest częścią zapytania generowanego przez nasz skrypt :-) Może jakoś porównywać zapytania z dopuszczalnymi wzorcami choć może ich czasami być sporo :-) Na pierwszym miejscu za pomocą ereg_replace wywaliłbym wszystkie podejrzane znaki z $_POST i $_GET a potem pozostaje kwestia sprawdzenia czy zapytanie pasuje do dopuszczalnych wzorców.... tak jak to robi mod security 2 ale to już kwestia napisania odpowiedniego algorytmu :-)

Napisany przez: bełdzio 30.12.2008, 09:36:28

nawet nie korzystajac z union selecta mozna przeprowadzic skuteczny SQLi :-)

Napisany przez: ucho 30.12.2008, 10:00:41

To ja bym prosił o jakiś przykład - bo przy mysql, gdzie nie można np. przepchnąć drugiego polecenia po ";" union to jedyny sposób jaki znam na wyciągnięcie czegoś z bazy - przynajmniej kiedy ktoś dał addslashes() myśląc, że to wystarczy =)

Napisany przez: pest 30.12.2008, 10:10:03

Sprawa chociażby z logowaniem, gdzie można zapytanie przedwcześnie zakończyć i to wystarczy.

Napisany przez: pyro 30.12.2008, 10:17:33

Cytat(mlattari @ 30.12.2008, 02:38:12 ) *
No już pisałem że jestem GŁUPI :-)

I zostańmy przy tym smile.gif


Jak to będzie np. forum o programowaniu będzie mnostwo wymienionych przez Ciebie składni zapytania, a ktoś gdzieś indziej może mieć taką samą nazwę np. tabeli i teraz co? Bedziesz pisał 200 linijek wzorców jakie mogą wystąpić przy wlamaniu i do tego nie będą one zawsze skuteczne? To jest !$sens smile.gif

Napisany przez: mlattari 30.12.2008, 14:14:22

No to jak już pisałem, na pierwszym miejscu należałoby oczyścić łańcuchy z niebezpiecznych znaków, za pomocą np. ereg_replace, get_magic_quotes_gpc, mysql_escape_string. To napewno wyeliminuje mozliwość dodania czegokolwiek do zapytania przez włamywacza... a tak na marginesie to polecam mod_sec2 pod apacha :-)

Napisany przez: bełdzio 30.12.2008, 20:29:59

Cytat(ucho @ 30.12.2008, 10:00:41 ) *
To ja bym prosił o jakiś przykład - bo przy mysql, gdzie nie można np. przepchnąć drugiego polecenia po ";" union to jedyny sposób jaki znam na wyciągnięcie czegoś z bazy - przynajmniej kiedy ktoś dał addslashes() myśląc, że to wystarczy =)

jest duzo roznych sposobow, zaczynajac od komenarzy konczac na 1=1, wsio zalezy od sposoby napisania app btw addslashes nie sluzy do zabezpieczania przed SQLi

Napisany przez: erix 30.12.2008, 21:40:33

Cytat
ereg_replace

W PHP6 Twój skrypt nie zadziała.

Cytat
mysql_escape_string

Ta funkcja może Ci rozwalić znaki przy korzystaniu z wielobajtowych kodowań:
Cytat
This function is identical to mysql_real_escape_string() except that mysql_real_escape_string() takes a connection handler and escapes the string according to the current character set. mysql_escape_string() does not take a connection argument and does not respect the current charset setting.


Cytat
To napewno wyeliminuje mozliwość dodania czegokolwiek do zapytania przez włamywacza...

nigdy, zawsze, na pewno, a potem okazuje się, że ktoś coś przeoczył i akcja "filmu" dzieje się jak na obrazku "windows 98 with firewall". tongue.gif

Napisany przez: Ermes 2.01.2009, 21:05:38

hmmm... a słyszeliśta o czymś takim jak procedury składowane ?
podaje sie do nich parametry, ktore potem siedza w zmiennych, a te z kolei nie są analizowane pod kątem wykonania przez serwer sql.
serwer ma w gdzieś co tam siedzi aby sie zgadzało z typem danych i nie ma takiej opcji zeby zmienna sie wykonała chyba ze zrobisz coś w stylu

  1. exec @zmienna

co jest kiepskim pomysłem chyba ze sie robi jeszcze gdzieś w prodecdurze dynamiczny sql i wtedy przy konkatenacji znaków trzeba uwazac ale wystarczy wsadzić zmienna w
  1. quotename(@zmienna)

i gotowe

mozna tez ustawić wartosci domyslne i uzywac tranzakcji itd. a obsługe błędów z sql chyba kazdy potrafi zrobic tongue.gif

problem sql injection znika... prawie ale dalej to trzeba sie nieźle napocić zeby to obejść, ale jak to juz nie wiem smile.gif

generalnie to nie wiem czy mysql posiada te wszystkie rzeczy, ale raczej tak bo procedury sa, ale w kazdym razie MS SQL 2005 i wyzej to ma
takie rzeczy stosuje się w biznesowych rozwiazaniach produkcyjnych smile.gif

PS. podałem kod z mssql ale jak mniemam bardzo podobnie jak nie tak samo jest w mysql

Napisany przez: $olo 12.02.2009, 11:38:27

Cytat(Ermes @ 2.01.2009, 22:05:38 ) *
generalnie to nie wiem czy mysql posiada te wszystkie rzeczy, ale raczej tak bo procedury sa, ale w kazdym razie MS SQL 2005 i wyzej to ma
takie rzeczy stosuje się w biznesowych rozwiazaniach produkcyjnych smile.gif


Owszem - są w MySQL procedury, ale problem można rozwiązać o wiele prościej - przez zmienne związane:

mysqli:
http://pl.php.net/manual/en/mysqli.prepare.php

PDO:
http://pl.php.net/manual/en/pdo.prepare.php

Napisany przez: mlattari 22.02.2009, 17:49:53

hmmm.... ten wątek ciągnie się już od bardzo dawna....
zawsze sądziłem że wystarczy zdjąć możliwość wpisywania czegokolwiek do paska url poprzez pracę nad refererem oraz zastosować mysql_real_escape_string na zmiennych przekazywanych przez $_POST oraz $_GET... ewentualnie odciąć nieporządane znaki które mogłyby w jakiś sposób przedostać się...

Czy ktoś kto stwierdzi, że jest to niewystarczające, mógłby podać konkretny przykład MySql Injection w którym moja skromna metoda nie zapewni ochrony? Bardzo proszę o konkretne przykłady bo zaczynam się martwić, że rzeczywiście to nie wystarczy. Proszę nie odsyłajcie mnie to lektury czegokolwiek tylko przytoczcie konkrety....

Napisany przez: pyro 22.02.2009, 18:02:14

Cytat(mlattari @ 22.02.2009, 17:49:53 ) *
hmmm.... ten wątek ciągnie się już od bardzo dawna....
zawsze sądziłem że wystarczy zdjąć możliwość wpisywania czegokolwiek do paska url poprzez pracę nad refererem oraz zastosować mysql_real_escape_string na zmiennych przekazywanych przez $_POST oraz $_GET... ewentualnie odciąć nieporządane znaki które mogłyby w jakiś sposób przedostać się...

Czy ktoś kto stwierdzi, że jest to niewystarczające, mógłby podać konkretny przykład MySql Injection w którym moja skromna metoda nie zapewni ochrony? Bardzo proszę o konkretne przykłady bo zaczynam się martwić, że rzeczywiście to nie wystarczy. Proszę nie odsyłajcie mnie to lektury czegokolwiek tylko przytoczcie konkrety....


mysql_real_escape_string() w zupełności wystarczy, problem SQLi polega na tym, ze niektórzy zapominają go wogóle dać, a niektórzy na przykład zapominają go dać w przykładowej sytuacji: ktoś sobie zbiera statystyki i zapisuje do bazy $_SERVER['HTTP_USER_AGENT']; $_SERVER wyglada inaczej niz $_GET czy $_POST dlatego ktos niedoswiadczony moglby pominac prze przypadek zabezpieczenei go smile.gif

Napisany przez: mlattari 26.02.2009, 20:56:14

hmm...

czy sądzicie że poniższy fragment kodu jest bezpieczny?

  1. <?php
  2. // Wyplata prowizji
  3. if (http://www.php.net/isset($_GET[wyplataprov])&&$_GET[wyplataprov]!='') {
  4. $wyplataprov=http://www.php.net/mysql_real_escape_string($_GET[wyplataprov]);
  5. http://www.php.net/mysql_query( "update pozycje set data_wyplaty_prowizji='".http://www.php.net/date('Y-m-d')."' where id={$wyplataprov} limit 1;") or diee_close(); }
  6. ?>


*diee_close to taka moja funkcja, która niszczy wszelkie dane sesyjne no i zamyka połączenie z MySql wyświetlając ładny komunikat o błędach :-)

bo już sam nie wiem.... ale wydaje mi się, że tutaj raczej żadne UNION select czy nic za znakami ;' nie powinno przedostać się do MySqla.... i nie czuję potrzeby stosowania stripslashes, trim i innych podobnych funkcji.

no ale żeby nikogo nie korciło wpisywanie bzdur do paska url to często stosuję to:

  1. <?php
  2. if (!$_SERVER['HTTP_REFERER']) diee_close();
  3. ?>


Przy aplikacjach, które muszą być jeszcze bezpieczniejsze jeszcze bardziej ograniczam referery ale to już inna kwestia... chodzi mi o takie rzeczy, które chodzą tylko na prywatnych LANAch.....

Napisany przez: pyro 27.02.2009, 21:45:05

Pierwsze zabezpieczenie dobre, jeśli jednak jest to dana liczbowa to wystarczy stosowac rzutowanie typow, co do tej drugiej metody jest ona bez sensu....

Napisany przez: Orkan 27.02.2009, 23:32:12

Cytat(mlattari @ 26.02.2009, 22:56:14 ) *
  1. <?php
  2. if (!$_SERVER['HTTP_REFERER']) diee_close();
  3. ?>


HTTP_REFERER - to "wytwor" przegladarki, gdzie przy pomocy odpowiednich "dodatkow" mozna tam wpisac cokolwiek. czesto w logach mam jako Referrer zwykly spam i reklamy,.. ludzka wyobraznia naprawde nie zna granic aaevil.gif

Napisany przez: mlattari 28.02.2009, 02:34:55

:-) No to jasne, że można :-) ale chodzi mi o zabezpieczenie przed wpisywaniem przez 'szarego' użytkownika eksperymantalnych wartości w pasku url :-)

np. jeżeli jesteśmy na stronce https://sklep.jakistamsklep.pl/lista_1.php?wyswietl=1&toitamto=2

to już nie będzie można sobie wpisać wartosci wyswietl i toitamto ręcznie po zastosowaniu tego o czym mowa :-)





A czy ktoś się orientuje czy w zapobieganiu MySql Injection ma jakieś znaczenie to, czy treść zapytania MySql jest zakończona w php średnikiem ?

czyli

  1. <?php
  2. $wynik=http://www.php.net/mysql_query( "select name from users;" );
  3. ?>


zamiast

  1. <?php
  2. $wynik=http://www.php.net/mysql_query( "select name from users" );
  3. ?>


?

Napisany przez: Orkan 28.02.2009, 10:00:57

a od kiedy zapytanie w mysql_query() konczy sie srednikiem?

Napisany przez: mlattari 28.02.2009, 13:38:41

zapytania MySql kończy się średnikiem :-) a w mysql_query teoretycznie też można więc ciekawi mnie czy ten średnik w mysql_query mógłby np. czemuś zapobiec (np. dołączeniu UNION SELECT) czy raczej nie :-) Zwyczjnie nie wiem to pytam :-)

Napisany przez: bełdzio 28.02.2009, 19:10:18

";" oznacza ze dane zapytanie zostalo zakonczone, w przypadku "zwyklych" selektow, insertow etc nie ma znaczenia czy dasz ; czy nie

co do uzycia ";" jako obranie przed union select to sprawa jest jasna smile.gif wszystko co wstrzykujesz leci przed ; tak wiec nic on nie da smile.gif

Napisany przez: mlattari 1.03.2009, 16:01:03

no racja... ja jakoś lubię te średniki tam wstawiać ale to chyba zboczenie od klienta mysql.... :-|

A czy ktoś może wie czy jest możliwy atak MySql Injection na zmienne przekazywane przez $_POST[] poprzez listy wyboru typu <SELECT>, w których są ustawione sztywne wartości. Czy da się jakoś manewrować tymi zmiennymi, tak żeby udało się tam coś wstrzyknąć? Chodzi mi o to czy też trzeba zabezpieczać się w przypadku zastosowania list wyboru typy <SELECT> ze sztywnymi wartościami.
Np. <option selected>1: Wybór1</option>. W takim przypadku odcinam sobie to co przed znakiem : czyli 1. Czy ktoś byłby w stanie coś tam podpiąć żeby i to trafiło do MySql?

Napisany przez: bełdzio 1.03.2009, 16:04:22

trzeba, kod HTML może być dowolnie zmodyfikowany, odpal sobie FireBug`a ( wtyczka do FireFoxa) i popatrz sobie jak latwo mozna zmanipulowac kod HTML

Napisany przez: mlattari 1.03.2009, 16:21:54

hmm dzięki! to dobrze wiedzieć!

Napisany przez: megawebmaster 14.03.2009, 20:32:01

Te wartości, które masz stałe, np. tak jak w przypadku tej jedynki najłatwiej obsłużyć przez switch'a - nie ma możliwości innych wartości, bo PHP to wybije na default'ową wartość winksmiley.jpg Oczywiście wada jest taka, że jest to bezpośrednio w kodzie, co zmniejsza elastyczność, ale coś za coś mówią winksmiley.jpg

Napisany przez: thomson89 21.03.2009, 19:41:42

Nie wiem jak wam, ale jak przepuściłem przez mój system login wyszło:

Kod
\', haslo=\'nowe_haslo\' id = 1


I myślę że to dobry sposób, jezei doda się wszystkie komendy sql smile.gif
  1. <?php
  2. $niebezpiecznyciag = "', haslo='nowe_haslo' WHERE id = 1 ALTER DATBASE";
  3.  
  4. //KROK 1
  5. $trochebezpiecznyciag = http://www.php.net/addslashes($niebezpiecznyciag);
  6. http://www.php.net/echo $trochebezpiecznyciag.'<br>';
  7.  
  8. //KROK 2
  9. $zle = http://www.php.net/array('WHERE', 'LIKE', 'INSERT', 'DELETE', 'FROM', 'ALTER');
  10. if(http://www.php.net/strstr($trochebezpiecznyciag, 'WHERE') || http://www.php.net/strstr($ciag, 'LIKE') || http://www.php.net/strstr($ciag, 'INSERT') || http://www.php.net/strstr($ciag, 'DELETE') || http://www.php.net/strstr($ciag, 'FROM') || http://www.php.net/strstr($ciag, 'ALTER')){
  11.    $bezpiecznyciag = http://www.php.net/str_replace($zle, '', $trochebezpiecznyciag);
  12.    //jezeli wykryta proba wlamania caly ciag jest podejrzany
  13.    $bardzobezpiecznyciag = sha1($bezpiecznyciag);
  14.    http://www.php.net/echo $bezpiecznyciag.'<br>';
  15.    http://www.php.net/echo $bardzobezpiecznyciag;
  16.  
  17. }
  18. ?>


Jeżeli zostanie wykryta jakakolwiek proba wlamania sie to konserwujemy caly ciag. Mozna tez uzyc czego innego i potem to odmieszać i sprawdzic co uzyszkodnicy chieli nam zrobic.

I mam pytanie czy przy if, nie można jakos inaczej porownac? if strstr(ciag, tablica) questionmark.gif

Napisany przez: Mephistofeles 21.03.2009, 19:48:05

A po co tak wydziwiać? Jeśli stringa trzymasz w cudzysłowach/apostrofach to MySQL nawet nie spojrzy na żadne słowo kluczowe.

Napisany przez: erix 21.03.2009, 20:13:38

Cytat
I mam pytanie czy przy if, nie można jakos inaczej porownac? if strstr(ciag, tablica)

http://pl.php.net/in_array

Napisany przez: thomson89 21.03.2009, 20:21:49

Cytat(Mephistofeles)
A po co tak wydziwiać? Jeśli stringa trzymasz w cudzysłowach/apostrofach to MySQL nawet nie spojrzy na żadne słowo kluczowe.


@Mephistofeles, jak ktos tam kilka stron wcześniej powiedział: Trzeba przygotować się na najgorsze.

z in array nie dziala

  1. <?php
  2. if(http://www.php.net/in_array($trochebezpiecznyciag, $zlo))
  3. ?>


to nie znajduje ciagu where i warunek nie spełniony...

Napisany przez: erix 21.03.2009, 20:27:05

To najlepiej siedzieć przy kompie i każde żądanie użytkownika przeglądać osobiście.

Przeczytaj cały ten wątek, od początku, dopiero potem zadawaj pytania. tongue.gif

Napisany przez: bełdzio 21.03.2009, 20:41:56

@thomson89 kiedys na swoim rozowym blogasku pisalem, ze w wiekszosci przypadkow pisanie wlasnego systemu filtracji nie ma sensu, bo zawsze cos sie spieprzy ;-) co prawda nie czytalem dokladnie Twojego kodu, ale smiem twierdzic ze "SELECT * FROM tab;" potraktuje jako probe SQLi, a co z "SELECT * FR/**/OM tab;" ?

przy okazji mozesz rzucic okiem na http://www.beldzio.com/zabezpieczenie-mlekiem-i-miodem-plynace

Napisany przez: escobar1983 22.03.2009, 18:06:44

Jakie sa mozliwości włamania na mojej stronie?
Nie mam zadnego formularza rejestracji, uzytkownik moze jedynie przegladac swoj profil bez edycji danych. Jest to strona z przedmiotu logistyka gdzie umieszczone sa testy sprawdzajaca wiedze z tej problematyki. W polach do logowania uzytkownik moze podawac tylko liczy i litery zadnych kropek itp. Uzywam md5 do hashowania hasel. W kazdej stronie sa wstawione warunki na temat czy osoba ma prawo zagladania do danej strony. Jedyne miejsce gdzie uzytkownik moze cos wspisac to formularz kontaktowy do wysylania maili. Gdy jestemy zalogowani ustawiana jest zmienna $_SESSION['login'] a gdy admin to $_SESSION['admin']

Napisany przez: bełdzio 22.03.2009, 21:02:07

nie widzac kodu zbyt wiele nie da sie powiedziec smile.gif jesli filtrujesz wszystko co nalezy i jak nalezy powinno byc ok

Napisany przez: rzymek01 22.03.2009, 21:25:14

pamietaj, że istnieje zatruwanie sesji, więc nie opieraj się tylko i wyłącznei na istnieniu danej zmiennej sesyjnej, możesz sprawdzić ip itp.

Napisany przez: thomson89 14.04.2009, 17:45:02

A czy najlepszym zabezpieczeniem nie byłoby sprawdzenie czy ciąg zawiera znak " ; " questionmark.gif

Napisany przez: erix 14.04.2009, 18:07:50

Tak? To ja wpiszę login:

Kod
' WHERE 1=1


tongue.gif

Przeczytaj, co do tej pory się naprodukowaliśmy, bo zaczyna wątek kołować.

Napisany przez: Rutilius 30.05.2009, 11:59:28

Mam pytanie, przepraszam, jeśli w złym wątku, ale wydaje mi się, że na temat.
Ostatnio na moją stronę próbowano dokonać ataku tego typu (sądzę, że się nie powiodło). Nie rozumiem, co ten ktoś/coś próbował zrobić. Gdyby ktoś mógł mi to wytłumaczyć, to może byłoby to z pożytkiem dla innych (ilustracja do tematu)?
Wyglądało to tak (dane mam ze sprytnego skryptu rejestrującego wejścia na stronę - dotyczy więc GET)
Najpierw ktoś w adresie próbował w jedną ze zmiennych wstawić adres (nie będę mu robił reklamy, więc wyiksowałem)
moja_strona.pl?art=newsy&k=http://www.xxxxxxxxx.com/layout/oxiqade/jokihi/
Potem próbował tak
moja_strona.pl?art=newsy&k=3/**/union/**/select/
**/0x6A7573745F615F746573745F315F305F305F736C6173685F315F3C3F706870206563686F286D64
528226A7573745F615F746573742229293B6563686F2840756E6C696E6B28222F6A6174657374362
7068702
Potem jeszcze kilkanaście takich prób, z tym, że przed tym dziwnym ciągiem dodawał coraz więcej null,
**/union/**/select/**/null,
...
/**/union/**/select/**/null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
ull,null,null,null,null,null,null,null,null,null,
Potem zmienił taktykę, i dodawał nawias
?art=newsy&k=3) union select 0x6A7573745F615F746573745F315F305F315F6461736 bleble
potem trochę pochodził po stronie,
spróbował jeszcze z linkiem
?p=http://www.xxxxxxxxxxx.kz/templates_c/omoj/suju/
i sobie poszedł. Całośc trwała 3 minuty.
Czy to było niebezpieczne?
Mam nadzieję, że się zbytnio nie ośmieszam tym pytaniem.

Napisany przez: erix 30.05.2009, 13:10:33

Cytat
Czy to było niebezpieczne?

Jeśli nie filtrujesz danych wejściowych, to jest niebezpieczne.

Jeśli filtrujesz, nie przejmuj się; chyba każdą stronę skanują boty poszukujące dziur. ;]

Napisany przez: mrSlowFlow 30.05.2009, 17:06:09

Co sądzicie o tym: http://hacking.pl/5845
Czy coś takiego wystarczy?

Napisany przez: erix 30.05.2009, 20:46:50

A chociaż przeczytałeś ten wątek od początku...?

Napisany przez: Fantome 14.06.2009, 15:08:58

ostatnich kilka dni przesiedziałem na szukaniu dobrego i skutecznego sposobu zabezpieczenia się przed SQL injection, jednak nic na prawdę konkretnego nie znalazłem;/
pewnie ameryki nie odkryłem, do optymalnych sposobów to nie należy, ale po połączeniu pomysłów z kilku stron oraz fragmentów kodów z tego forum powstało coś takiego:

  1. <?php
  2. function filtr_sprawdzenie($text)
  3. {
  4.    $filtr_sprawdzenie= filtr($text);
  5.    return http://www.php.net/substr_count($filtr_sprawdzenie, '1');
  6. }
  7. function filtr($text)
  8. {
  9.    $text=http://www.php.net/strtolower($text);
  10.    
  11.    
  12.    $ciag_sprawdzenie = http://www.php.net/substr_count($text, 'unique').
  13.    http://www.php.net/substr_count($text, '*/').
  14.    http://www.php.net/substr_count($text, '/*').
  15.    http://www.php.net/substr_count($text, '//').
  16.    http://www.php.net/substr_count($text, '#').
  17.    http://www.php.net/substr_count($text, '<!--').
  18.    http://www.php.net/substr_count($text, 'char').
  19.    http://www.php.net/substr_count($text, 'BETWEEN');
  20.  
  21.    return $ciag_sprawdzenie;
  22.    
  23. }
  24.  
  25.  
  26.  
  27. function strip_tags_content($text, $tags = '', $invert = FALSE) {
  28. http://www.php.net/preg_match_all('/<(.+?)[s]*/?[s]*>/si', http://www.php.net/trim($tags), $tags);
  29.  $tags = http://www.php.net/array_unique($tags[1]);
  30.  if(http://www.php.net/is_array($tags) AND http://www.php.net/count($tags)> 0) {
  31.    if($invert == FALSE) {
  32.      return http://www.php.net/preg_replace('@<(?!(?:'. http://www.php.net/implode('|', $tags) .')b)(w+)b.*?>.*?</1>@si', '', $text);
  33.    }
  34.    else {
  35.      return http://www.php.net/preg_replace('@<('. http://www.php.net/implode('|', $tags) .')b.*?>.*?</1>@si', '', $text);
  36.    }
  37.  }
  38.  elseif($invert == FALSE) {
  39.    return http://www.php.net/preg_replace('@<(w+)b.*?>.*?</1>@si', '', $text);
  40.  }
  41.  return $text;
  42. }
  43.  
  44. function dlugosc_ciagu($text, $max)
  45. {
  46.    if(http://www.php.net/strlen($text)<$max)
  47.    {
  48.        return $text;
  49.    }
  50.    else
  51.    return'error';
  52. }
  53.  
  54. $text=$_POST['jakis_tekst'];
  55. $user_id=1;
  56. $max=50;
  57. if(dlugosc_ciagu($text, $max)!='error')
  58. {
  59.    $ile_podejrzanych_znakow = filtr_sprawdzenie($text);//sprawdza czy nie zostało użyte słowo unique itp. jeśli bedzie 1 albo wiecej to ktos chce sie wlamac, jesli 0 to nie:)
  60.    if($ile_podejrzanych_znakow>0)
  61.    {
  62.        http://www.php.net/echo 'Próba włamania, Twoje IP zostało zbanowane, a admin poinformowany drogą mailową';//dalej kod wysyłający maila/smsa do admina, banujący dane IP w systemie
  63.    }
  64.    else
  65.    {
  66.        $text = strip_tags_content(http://www.php.net/htmlspecialchars(http://www.php.net/strip_tags(http://www.php.net/html_entity_decode(http://www.php.net/substr($text,0,550)))));
  67.        $zapytanie = "INSERT INTO notatki (`id`, `user_id`, `tresc`) VALUES ('', '$user_id', '$text')";
  68.        $dodaj_komentarz = http://www.php.net/mysql_query($zapytanie);
  69.    }
  70. }
  71. else
  72. http://www.php.net/print 'Wpis jest za długi';
  73. ?>



osobiście widzę w tym jeden plus, bo po pierwszej próbie włamania dany użytkownik/bot jest banowany, komunikat o tym jest wysyłany do mnie, a w razie gdyby zaszła pomyłka mogę zdjąć bana z danego użytkownika. Cała strona którą teraz piszę jest dostępna dopiero po zalogowaniu więc goście nie będą mogli nic nabroić(teoretycznie).

geniuszem nie jestem jeśli chodzi o php, dopiero zaczynam w tym zabawę, ale pytanie:
czy ten kod jest dość bezpieczny? ciężko będzie to obejść?
Pozdrawiam Fantome:)

Napisany przez: erix 15.06.2009, 10:02:52

Cytat
ostatnich kilka dni przesiedziałem na szukaniu dobrego i skutecznego sposobu zabezpieczenia się przed SQL injection, jednak nic na prawdę konkretnego nie znalazłem;/

A chociaż przeczytałeś cały ten wątek...? tiredsmiley.gif

Napisany przez: Fantome 15.06.2009, 11:01:05

żeby tylko ten... ze 2 dni temu to czytałem i postanowiłem szukać dalej... jest sporo pomysłów i rozwiązań w tym temacie, ale nikt nie potwierdził, że któreś z podanych zabezpiecza stronę w 100%... sad.gif

Napisany przez: erix 15.06.2009, 11:11:28

A wiesz o tym, że na nic nie ma 100% zabezpieczenia?

Napisany przez: Fantome 15.06.2009, 11:20:18

zdaję sobie z tego sprawę smile.gif jednak staram się wyeliminować jak najwięcej dziur w tym co piszę smile.gif
pozdrawiam Fantome smile.gif

Napisany przez: erix 15.06.2009, 11:28:11

Jeśli wprowadzisz to, o czym mowa w tym wątku, nie powinno być problemu.

Zresztą, od tego są beta-testy, aby wyeliminować błędy. [;

Napisany przez: nieraczek 20.06.2009, 09:05:08

Fantome nie banuj po IP - w ten sposób podczas szukania czegoś w google odkryłem już dwa fora internetowe, na których jestem zbanowany po IP a w życiu się tam nie rejestrowałem :/

Napisany przez: erix 20.06.2009, 11:17:48

To raczej nie wina forum, a tego, że IP trafiło prawdopodobnie do kogoś, kto ma PC-zombie.

A z tego, co pamiętam, to TP wykupiła kiedyś pulę IP dla neozdrady, która była wcześniej intensywnie wykorzystywana do włamów. [;

Napisany przez: Spawnm 27.06.2009, 20:22:27

Tak się zastanawiam...
jeśli strona ma geta np id=1, jeśli dopiszemy mu 1' sql /* to nie zareaguje,
ale jeśli mu dam id=aaa to wypluje warning ... czy taka strona jest podatna na sql injection ?
Pytam bo widzę taką stronkę i zastanawiam się czy zawracać gitarę adminowi , dodatkowo ciekawość smile.gif

Napisany przez: #luq 27.06.2009, 21:39:56

Cytat(Spawnm @ 27.06.2009, 21:22:27 ) *
ale jeśli mu dam id=aaa to wypluje warning ... czy taka strona jest podatna na sql injection ?

Tak. Jeśli dla stringa wypluwa warninga to wielce prawdopodobne jest, że zapytanie jest zbudowane tak:
  1. SELECT a FROM b WHERE id = $zmienna

Integery nie muszą być w cudzysłowiach, natomiast stringi tak. A np. zapytanie
  1. SELECT a FROM b WHERE id = 1' sql /*

nie wywołuję błędu bo po stronie php są wykrywane pewne niebezpieczne ciągi np. sekwencja "/*" i zmienna jest ignorowana etc.

Jednoznacznie nie da się określić czy taka strona jest podatna na jakiś atak z grupy SQLI. Ja sprawdziłbym ataki typu DoS z grupy SQLI. Sprawdzałbym inne wejścia bo raczej podane przez Ciebie jest popularne.

Taka wskazówka, każdy atak SQLI zaczyna się od wydedukowania zapytania.

Napisany przez: lukasamd 28.06.2009, 13:59:21

Mam pewne pytanie, odnośnie wypowiedzi erixa dotyczącej mysql_escape_string:

Cytat
Ta funkcja może Ci rozwalić znaki przy korzystaniu z wielobajtowych kodowań


Kiedy może się coś takiego stać? Powiedzmy że przez $_POST idzie ciąg, po którym szukam czegoś w bazie w polu typu varchar.
Ciąg z założenia powinien być obrobiony tzn. bez znaków diaktrycznych itp. więc nie muszę się martwić o problemy z nimi.

Chodzi o to, że mysql_real_escape_string działa znacznie wolniej niż wersja bez sprawdzania charsetu.

Napisany przez: erix 28.06.2009, 21:26:21

Np. przy korzystaniu z UTF-8.

Wszystko jest przecież napisane:

Cytat
does not take a connection argument and does not respect the current charset setting.


A tak poza tym, dla http://pl.php.net/mysql_escape_string:
Cytat
This function is deprecated.

Napisany przez: $olo 14.07.2009, 16:05:12

Cytat(erix @ 15.06.2009, 11:11:28 ) *
A wiesz o tym, że na nic nie ma 100% zabezpieczenia?

Hej,

Już raz wspominałem o zastosowaniu zmiennych związanych, ale jakoś widzę wątek dalej rozwija się
w stronę doktoryzacji nad zupełnie prostym problemem. W telegraficznym skrócie:
Zmienne związane mają 2 główne zastosowania:
1) optymalizacja działania aplikacji poprzez jednokrotną interpretację zapytania, a w każdym
następnym jego uruchomieniu tylko podmienianie samych danych. MySQL optymalizuje sobie
niestety takie zapytanie tylko w obrębie sesji. Inne bazy takie jak ORACLE przechowują plan wykonania
zapytania.
2) Oddzielenie treści zapytania od parametrów załatwia przy okazji właśnie problem MySQL Injection.
W zasadzie w 100% ponieważ dane nie wpływają na treść zapytania, która już wcześniej została sparsowana.

Przykład SQLa:

  1. SELECT * FROM tabela WHERE pole = :parametr


takie zapytanie parsuje sobie baza, a dopiero potem przekazujemy (bindujemy) wartość
zmiennej "parametr".

Jeszcze raz link do manuala PHP:
http://pl.php.net/manual/en/pdo.prepare.php
oraz jak kto woli:
http://pl.php.net/manual/en/mysqli.prepare.php

Oczywiście warunkiem jest PHP5 oraz MySQL 4.1, ale to chyba już w tej chwili standard.

Napisany przez: xajart 25.11.2009, 13:07:53

Z tego co zauważyłem to ile osób tyle rozwiązań przed tego typu atakami. A jeżeli ktoś opracuje jakiś uniwersalny kod - to posypie się sporo wypowiedzi negatywnych. Wiec z tego nasuwa się jeden wniosek, jakie zabezpieczenie by nie było i tak nie jest dobre.

Z tego co czytałem ten wątek i jemu podobne w sieci. To nasuneły mi sę takie spostrzeżenia:
Przed atakami XSS najlepiej się bronić stosując htmlspecialchars lub htmlentities - dla danych wyświetlanych (np z BD).


Natomiast przed SQL Injecton, to albo zapoznać się z jakimś interfejsem np PDO i konstruować zapytania w stylu prepare, execute. 
Ale jeżeli ktoś chce zostać przy standardowym konstruowaniu zapytań do BD (np nie chce mu się przebudowywać istniejącego serwisu pod PDO), to czy nie wystarczy dane (zewnętrzne) czy to z POST czy GET poddawać najpierw np htmlentities potem zastosować sprawdzanie wyrażeniami regularnymi (lub stosować funkcje ctype, is_numeric itp.), a na końcu w zapytaniu do BD zastosować mysql_real_escape_string

Jest wiele opini na temat czy to htmlentities, addslashes, strip_tags. Ale które nalepsze? 

strip_tags - wycina(eliminuje) znaczniki HTML,
- nie warty zachodu, jeżeli dane które mają być przetworzone, zapisane w BD a potem wyświetlane w serwisie (stracą formatowanie). 
- jednak są sytuacje w których może się przydać.


addslashes - Dodaje znak ucieczki przed znakami niebezpiecznymi jak: apostrof, cudzysłów, backslash i NUL

htmlentities - konwertuje wszystkie znaki HTML na encje, gdzie htmlspecialchars tylko znaki specjalne. 

Wiec jeżęli ciag zostanie przeformatowany przez htmlentities - to spokonie można sprawdzić np wyrażeniami regularnymi czy zawiera to co powinnien i odpowiednią długość znaków, a następnie przekazać do bazy danych. Ale czy warto wtedy stosować mysql_real_escape_string? - moim zdaniem warto na wypadek gdy wyrażenia regularne nie będą zbyt ścliśle określone i przepuszczą coś w stylu  UNION, SELECT ... Wówczas jeżeli dobrze rozumie powyższa komenda to wyeliminuje.

Ale nie jestem specem w tej dziedzinie i miło mi będzie jeżeli ktoś to sprostuje.



Napisany przez: ucho 25.11.2009, 13:42:16

Wszystkie pytania o SQL Injection powinny się kończyć jednym zdaniem: "Używaj prepared statements, lub jeśli uważasz, że nigdy nie zapomnisz tego zrobić, dodawaj znaki ucieczki odpowiednie dla twojej bazy". Koniec, kropka. Podobnie XSS - "usuwasz cały html albo escape podczas wyświetlania".
Tymczasem w tym wątku co chwila pojawiają się jakieś dziwne pomysły, które co najwyżej wprowadzają zamieszanie i w sumie nie wiem czemu ten wątek ma służyć. Może lepiej przyciąć to do jednego postu z informacją co i jak i tylko go zostawić przypiętym?

Napisany przez: Mephistofeles 30.12.2009, 21:58:11

Zgadzam się. Jak czytam niektóre z tych wymysłów to aż głowa boli. Potem się przyszła ekipa źle nauczy.

Napisany przez: bełdzio 30.12.2009, 22:32:03

Cytat(ucho @ 25.11.2009, 11:42:16 ) *
Wszystkie pytania o SQL Injection powinny się kończyć jednym zdaniem: "Używaj prepared statements"


ja bym dodał świadomie smile.gif bo korzystając z PS też można dać ciała smile.gif

Napisany przez: aio 4.02.2010, 23:38:51

1 obraz > 1000 słów

  1. function _P($sql) { return http://www.php.net/mysql_real_escape_string(http://www.php.net/get_magic_quotes_gpc()?http://www.php.net/stripslashes($sql):$sql); }

Przykładowe użycie:
  1. $query = "SELECT * FROM `login` WHERE `login`='"._P($_POST['login'])."'";

jak ktoś to shakuje to wysyłam mu Moet!

Napisany przez: pyro 13.02.2010, 12:28:23

  1. function _P($sql) { return http://www.php.net/mysql_real_escape_string(http://www.php.net/get_magic_quotes_gpc()?http://www.php.net/stripslashes($sql):$sql); }
  2. http://www.php.net/mysql_query('SELECT id,name FROM videos WHERE `video_id` = '._P($_GET['video_id']));


Kod
http://strona.pl?video_id=-1 UNION SELECT username,password FROM users LIMIT 1


Wyślij mi Moet, cokolwiek to jest.

Napisany przez: wiiir 24.02.2010, 14:37:34

Cytat(pyro @ 13.02.2010, 12:28:23 ) *
  1. function _P($sql) { return http://www.php.net/mysql_real_escape_string(http://www.php.net/get_magic_quotes_gpc()?http://www.php.net/stripslashes($sql):$sql); }
  2. http://www.php.net/mysql_query('SELECT id,name FROM videos WHERE `video_id` = '._P($_GET['video_id']));


Kod
http://strona.pl?video_id=-1 UNION SELECT username,password FROM users LIMIT 1


Wyślij mi Moet, cokolwiek to jest.



podwarunkiem ze tablea users istnieje o polach username, password
smile.gif

a co bys zrobils jak by sie okazalo ze hasla trzymane sa w innej bazie o glupiej nazwie z glupia kolmna?questionmark.gif?
wiec w obrebie polaczenia tego zapytania wyzej byc nic nie uzyskal..

a przy logowaniu leci POST a nie GET plus ta funkcja co pisal kolega do filtrowania danych

Napisany przez: nospor 24.02.2010, 14:39:55

Cytat
podwarunkiem ze tablea users istnieje o polach username, password
Jakie istnieją tabele i jakie mają kolumny też bez problemu dzieki tej dziurze można wykryc... wystarczy ze ktos umozliwia dziure i juz jestesmy w domu.

Napisany przez: kilas88 24.02.2010, 14:48:58

Cytat(wiiir @ 24.02.2010, 14:37:34 ) *
podwarunkiem ze tablea users istnieje o polach username, password
smile.gif

a co bys zrobils jak by sie okazalo ze hasla trzymane sa w innej bazie o glupiej nazwie z glupia kolmna? questionmark.gif ?
wiec w obrebie polaczenia tego zapytania wyzej byc nic nie uzyskal..


Skoro dziurawy skrypt otrzymuje dane to i haker dostałby te dane. Nie musi znać dokładnej struktury tabeli - może działać metodą prób i błędów. To zadanie można też zautomatyzować i myślę, że osoby bawiące się w tych tematach takowe już posiadają smile.gif

Napisany przez: wiiir 24.02.2010, 14:57:42

Dodajac replace na UNION + kilka innych , ustalenie jakie tabele i kolumny jest raczej bardzo trudne
do tego mozna zrobic tak jak mowilem zeby trzymac hasla i uzytkownikow i pare innych poufnych danych w innej bazie to daje tyle ze w obrebie poruszanaia sie po serwisie operujemy tylko na danych wyswietlanych a nie poufnych... chyba ze mozna to obejsc ja nie wiem jak.. wydaje mi sie byc to dobrym pomyslem

Oczywiscie ze dla hakera nie ma rzeczy nie mozliwych, tylko ze wtedy nie ma tak latwo
Nie jestem expertem.. sam chce sie w miare dobrze przed tym zabiezpieczyc

Napisany przez: pyro 24.02.2010, 15:29:50

Cytat(wiiir @ 24.02.2010, 14:37:34 ) *
podwarunkiem ze tablea users istnieje o polach username, password

a przy logowaniu leci POST a nie GET plus ta funkcja co pisal kolega do filtrowania danych


Drogi @wiiir, podane tabele to były najzwyklejsze przykłady, mogłem równie dobrze też napisać tabele asfjaiofjadfo oraz asjfhkjasdkjas. Też byś wtedy napisał `wątpię, żeby jakiś serwis miał pola i tabele o takich nazwach`?

A czy według Ciebie SQL Injection może mieć miejsce tylko w skrypcie logowania? Jak taki błąd ma miejsce na przykład w newsach na tej samej stronie to mogę tak samo z tego miejsca wyciągnąć nazwy użytkowników i ich hasła smile.gif

Cytat(wiiir)
wiec w obrebie polaczenia tego zapytania wyzej byc nic nie uzyskal..


Nie warto się zastanawiać, co mógłby zrobić potencjalny włamywacz w związku z istniejącym błędem. Ważne, żeby zadbać o to, żeby go nie było.

Napisany przez: wiiir 24.02.2010, 15:51:48

jakis bys napisal ze masz nazwy takich tabl i kolumn to bym sie nie zdzwil bo ja czesto stosuje cos takiego.. moze nie taki random jak podales.. albo cos podobnego, wiem ze odpowiesz ze jest to do ustalenia.. .ale osoba ktora pisze sobie taki skrypty zazwyczaj stosuje standardowe nazwy tabel ktore znajdzie w tutakach, a hakerowi to jest nareke, inne nazwy rozne prefixy itd daja tyle ze juz trzeba cos zrobic wiecej ..

Wiadomo ze w pierwszej kolejnosci nalezy zabiezpieczyc skrypt pod w zgledem otrzymywanych danych.. ale wiadomo ze o czyms mozna zapomniec.. a sam id uzytkownika tez duzo nie daje takie dane mozna z cockie zebrac, a zeby odnalesc haslo musisz zainicjowac nowe polaczenie do drugiej bazy, zeby to zrobic trzeba byc juz naprawde niezlym gosciem

To o logowaniu to tak na marginesie bo tam jest popelniany 1 blad

Temat ten mozna by cignac w nieskonczonosc a i tak znalazby sie haker ktory by znalazl dziurke smile.gif

Napisany przez: pyro 24.02.2010, 16:15:38

Cytat(wiiir @ 24.02.2010, 15:51:48 ) *
jakis bys napisal ze masz nazwy takich tabl i kolumn to bym sie nie zdzwil bo ja czesto stosuje cos takiego.. moze nie taki random jak podales.. albo cos podobnego, wiem ze odpowiesz ze jest to do ustalenia.. .ale osoba ktora pisze sobie taki skrypty zazwyczaj stosuje standardowe nazwy tabel ktore znajdzie w tutakach, a hakerowi to jest nareke, inne nazwy rozne prefixy itd daja tyle ze juz trzeba cos zrobic wiecej ..


trudniejsze czy nie, to generalnie kwestia czasu, po prostu nie można sobie pozwolić na to, żeby taka miała miejsce

Cytat(wiiir @ 24.02.2010, 15:51:48 ) *
Wiadomo ze w pierwszej kolejnosci nalezy zabiezpieczyc skrypt pod w zgledem otrzymywanych danych.. ale wiadomo ze o czyms mozna zapomniec.. a sam id uzytkownika tez duzo nie daje takie dane mozna z cockie zebrac, a zeby odnalesc haslo musisz zainicjowac nowe polaczenie do drugiej bazy, zeby to zrobic trzeba byc juz naprawde niezlym gosciem


Pisze się w cookies. No, chyba że sugerujesz, że ludzie przetrzymują nazwy użytkowników w kutaskach tongue.gif. Niestety takie rozwiązanie mogłoby być uciążliwe dla damskiej części użytkowników.

Bardzo rzadko id użytkownika przetrzymuje się w cookies. A żeby nawet go wyciągnąc stamtąd, trzeba by było znaleźć inną lukę (XSS).

Cytat(wiiir @ 24.02.2010, 15:51:48 ) *
To o logowaniu to tak na marginesie bo tam jest popelniany 1 blad


No to równie dobrze mogłeś napisać coś o hardware, bo to również wiąże się z komputerami, na których się pisze kod.

Cytat(wiiir @ 24.02.2010, 15:51:48 ) *
Temat ten mozna by cignac w nieskonczonosc a i tak znalazby sie haker ktory by znalazl dziurke smile.gif


To zdanie jest również (według mnie) fałszywe. Można pisać tak, żeby nie popełniać błędów.

Napisany przez: wiiir 24.02.2010, 16:47:36

Cytat(pyro @ 24.02.2010, 16:15:38 ) *
trudniejsze czy nie, to generalnie kwestia czasu, po prostu nie można sobie pozwolić na to, żeby taka miała miejsce

czasami wlasnie ten czas dziala na twoja korzysc oznacza to im dluzej ktos prubuje wlamac tym masz lepsze zabezpieczenia

Cytat(pyro @ 24.02.2010, 16:15:38 ) *
Pisze się w cookies. No, chyba że sugerujesz, że ludzie przetrzymują nazwy użytkowników w kutaskach tongue.gif. Niestety takie rozwiązanie mogłoby być uciążliwe dla damskiej części użytkowników.

Bardzo rzadko id użytkownika przetrzymuje się w cookies. A żeby nawet go wyciągnąc stamtąd, trzeba by było znaleźć inną lukę (XSS).

Moze sie i pisze ale widzialem ludzi ktorzy trzymaja hasla i w sesji jak i w cookie


Cytat(pyro @ 24.02.2010, 16:15:38 ) *
To zdanie jest również (według mnie) fałszywe. Można pisać tak, żeby nie popełniać błędów.

Nie jestes w stanie tak napisac kodu zeby nie popelnic bledu. Inaczej nie bylo by wlamow do najwikszych instytucji Polsce i na swiecie.

Napisany przez: Crozin 24.02.2010, 17:21:59

Cytat
Nie jestes w stanie tak napisac kodu zeby nie popelnic bledu.
Jest, jest. Na świecie powstaje cała masa bezpiecznego (w pełni) kodu. Problemy pojawiają się przy pisaniu skomplikowanych programów/skryptów jak i przy wykorzystywaniu oprogramowania firm trzecich - co jest właściwie... nieuniknione.

Ale napisanie programu/skryptu do którego nie da się włamać bezpośrednio jest możliwe.

Napisany przez: pyro 24.02.2010, 23:11:24

Cytat(wiiir @ 24.02.2010, 16:47:36 ) *
czasami wlasnie ten czas dziala na twoja korzysc oznacza to im dluzej ktos prubuje wlamac tym masz lepsze zabezpieczenia


Niestety ten czas niewiele działa na korzyść, bo prędzej czy później minie winksmiley.jpg Lepsze zabezpieczenia? Na litość boską, to wcale nie znaczy o lepszych zabezpieczeniach.

Cytat(wiiir @ 24.02.2010, 16:47:36 ) *
Nie jestes w stanie tak napisac kodu zeby nie popelnic bledu. Inaczej nie bylo by wlamow do najwikszych instytucji Polsce i na swiecie.


Zaryzykuje to stwierdzenie, ale jestem. A już przynajmniej od strony SQL Injection, o którym jest temat.

Napisany przez: wiiir 25.02.2010, 08:34:14

Cytat(pyro @ 24.02.2010, 23:11:24 ) *
Niestety ten czas niewiele działa na korzyść, bo prędzej czy później minie winksmiley.jpg

Do tego mnie nie przekonasz, porownanie np: bo przeciez to ze nie miales wypadku nie oznacza ze kiedys i tak bedziesz "musial" miec, no i wcale nie musisz a mozesz
tak samo z wlamem moze byc taka sytuacja ze jest dziura, ale koles probuje probuje i nic az wkoncu daje sobie spokuj..

Ucieklismy od temau ups tongue.gif

Tak ogolnie patrzac na twoje stwierdzenie zrob nam dekalog dobrego zabezpieczenia SQL Injection ktore stosujesz smile.gif

Napisany przez: kilas88 25.02.2010, 08:46:38

Cytat(wiiir @ 25.02.2010, 08:34:14 ) *
Tak ogolnie patrzac na twoje stwierdzenie zrob nam dekalog dobrego zabezpieczenia SQL Injection ktore stosujesz smile.gif


http://php.net/manual/en/pdo.prepare.php


To powinno załatwić sprawę.


Napisany przez: ucho 25.02.2010, 10:25:02

Cytat(wiiir @ 24.02.2010, 14:57:42 ) *
Dodajac replace na UNION + kilka innych , ustalenie jakie tabele i kolumny jest raczej bardzo trudne

sciana.gif
Podałbym przykład jak ominąć takie pseudozabezpieczenie w postacie replace ale podejrzewam, że zacząłbyś po prostu dokładać kolejne warunki brnąc w ślepą uliczkę. Nazwy tabel i pól można pobierać zwykłymi zapytaniami, przecież większość ORMów właśnie to robi nie mówiąc o np. phpMyAdminie.

Napisany przez: pyro 25.02.2010, 20:48:47

Cytat(wiiir @ 24.02.2010, 14:57:42 ) *
Dodajac replace na UNION + kilka innych


Oczywiście... w JPortalu już czegoś takiego próbowali i miałem dzięki temu dużo "zabawy" smile.gif .

Napisany przez: aio 1.03.2010, 23:04:44

@pyro
szampan się nie należy! zmodyfikowałeś mój kod, tworząc lukę ( zlikwidowałeś cudzysłów ), więc shakowałeś swój kod, mój pozostał nietknięty winksmiley.jpg

Kto następny?


Napisany przez: Crozin 1.03.2010, 23:33:47

@aio: Traktowanie liczb jako tekstu (tj.: id = "123", zamiast normalnego id = 123) jest brzydkim/złym zwyczajem - chociaż w tym przypadku (o ile wszędzie wszystkie dane traktowałbyś jako tekst) ratuje Cię to przed potencjalnym atakiem.

Napisany przez: pyro 2.03.2010, 00:12:13

Cytat(aio @ 1.03.2010, 23:04:44 ) *
@pyro
szampan się nie należy! zmodyfikowałeś mój kod, tworząc lukę ( zlikwidowałeś cudzysłów ), więc shakowałeś swój kod, mój pozostał nietknięty winksmiley.jpg

Kto następny?


Ale co Ty w takim razie chciałeś zrobić? Pokazać jak napisałeś dwie linijki kodu, których nie da się tknąć? Zobacz o czym jest wątek. Jest on o zabezpieczaniu przed SQL Injection/Insertion, a nie o zabezpieczaniu jednego, konkretnego, prostego zapytania. Z Twojego posta można było jedynie wywnioskować, że odkryłeś "cudowną funkcję", która zabezpiecza przed SQL Injection. Niestety NIEWIELE ona zabezpiecza i ktoś posługując się nią prawdopodobnie miałby luki w swoim serwisie/stronie. To co napisałeś nie rozwiązuje nawet w połowie zagrożenia SQL Injection. Jestem niemal pewien, że nawet jakbyś teraz rozbudował te "logowanie" o parę linijek kodu do rejestracji, to już by była podatna na atak.

A wino mi się w takim razie należy chociażby za Twojego nic nie wnoszącego do tematu posta tongue.gif

Napisany przez: aio 2.03.2010, 11:58:22

Cytat(pyro @ 2.03.2010, 00:12:13 ) *
Ale co Ty w takim razie chciałeś zrobić? Pokazać jak napisałeś dwie linijki kodu, których nie da się tknąć? Zobacz o czym jest wątek. Jest on o zabezpieczaniu przed SQL Injection/Insertion, a nie o zabezpieczaniu jednego, konkretnego, prostego zapytania. Z Twojego posta można było jedynie wywnioskować, że odkryłeś "cudowną funkcję", która zabezpiecza przed SQL Injection. Niestety NIEWIELE ona zabezpiecza i ktoś posługując się nią prawdopodobnie miałby luki w swoim serwisie/stronie. To co napisałeś nie rozwiązuje nawet w połowie zagrożenia SQL Injection. Jestem niemal pewien, że nawet jakbyś teraz rozbudował te "logowanie" o parę linijek kodu do rejestracji, to już by była podatna na atak.

A wino mi się w takim razie należy chociażby za Twojego nic nie wnoszącego do tematu posta tongue.gif


Chyba się nie rozumiemy. Nie chodziło mi o atak literacki mnie na forum! Na serwerze jako haker, jesteś w stanie tknąć kod? Nie! Hakujesz wejściem poprzez REQUEST! Zrozumiałem że o tym mowa w tym wątku, nieprawdaż? Utwórz taki REQUEST (_GET), żeby shakować mój kod. Nie chcę być niegrzeczny ale czy nie mam przypadkiem racji? Czy uważasz, że Twój post cokolwiek wniósł?

Pozdrawiam

Cytat(Crozin @ 1.03.2010, 23:33:47 ) *
@aio: Traktowanie liczb jako tekstu (tj.: id = "123", zamiast normalnego id = 123) jest brzydkim/złym zwyczajem - chociaż w tym przypadku (o ile wszędzie wszystkie dane traktowałbyś jako tekst) ratuje Cię to przed potencjalnym atakiem.


Do enginu mysqla wysyłasz String. 123 przy parsowaniu jest konwertowane na Number. Tak samo '123' będzie konwertowane do Number, z tą zaletą że poprzez szybszy natywny engine mysql i tylko JEDEN raz, a nie dodatkowe linijki kodu php z większym ryzykiem popełnienia błędu. Jakaż jest przewaga (np wydajności) skryptu z uprzednią konwersją na Number, skoro trzeba przewidzieć i dopisać ochronę w innych przypadkach?

Czy zatem jest coś brzydszego od konwertowania po kilka razy tej samej wartości w kółko na dziesięć sposobów rzekomo utrudniających atak? winksmiley.jpg. Że typ String jest brzydki jako taki? To jest ten argument?
I najważniejsze, bo może nie doczytałem czegoś, ten wątek jest o utrudnianiu czy ułatwianiu rozwiązania zagadnienia? Np. kolega wyżej zamiast dokonać włamu, opracował lukę i dumnie obwieścił, że udowodnił, że się umie włamać - SIC!

PS. Wiem, że wyżej gdzieś ktoś pisał, że jak podamy liczbę jako String, to ma wpływ na performance, ale chyba się zgodzimy wszyscy, że nie dotyczy to tego przypadku?

Pozdrawiam

Napisany przez: pyro 2.03.2010, 12:44:56

Cytat(aio @ 2.03.2010, 11:58:22 ) *
Chyba się nie rozumiemy. Nie chodziło mi o atak literacki mnie na forum! Na serwerze jako haker, jesteś w stanie tknąć kod? Nie! Hakujesz wejściem poprzez REQUEST! Zrozumiałem że o tym mowa w tym wątku, nieprawdaż? Utwórz taki REQUEST (_GET), żeby shakować mój kod. Nie chcę być niegrzeczny ale czy nie mam przypadkiem racji? Czy uważasz, że Twój post cokolwiek wniósł?


haha.gif haha.gif haha.gif

Nie, nie masz racji, nie o tym jest temat smile.gif. Moje posty o tyle wnoszą do tematu, że starają się skorygować Twoje smile.gif.

Cytat(aio @ 2.03.2010, 11:58:22 ) *
I najważniejsze, bo może nie doczytałem czegoś, ten wątek jest o utrudnianiu czy ułatwianiu rozwiązania zagadnienia? Np. kolega wyżej zamiast dokonać włamu, opracował lukę i dumnie obwieścił, że udowodnił, że się umie włamać - SIC!


Właśnie chodzi o to, że nie ułatwiłeś rozwiązania zagadnienia, a jedynie pominąłeś jego większą część. Teraz jak ktoś wejdzie w temat i popatrzy sobie na Twój post(y), to może sobie pomyśleć, że w ten sposób należy zabezpieczać się przed SQL Injection. Przez to potem będzie miał w swojej aplikacji zjawisko zwane "serem szwajcarskim".

Napisany przez: aio 2.03.2010, 14:21:44

Cytat(pyro @ 2.03.2010, 12:44:56 ) *
haha.gif haha.gif haha.gif

Nie, nie masz racji, nie o tym jest temat smile.gif. Moje posty o tyle wnoszą do tematu, że starają się skorygować Twoje smile.gif.



Właśnie chodzi o to, że nie ułatwiłeś rozwiązania zagadnienia, a jedynie pominąłeś jego większą część. Teraz jak ktoś wejdzie w temat i popatrzy sobie na Twój post(y), to może sobie pomyśleć, że w ten sposób należy zabezpieczać się przed SQL Injection. Przez to potem będzie miał w swojej aplikacji zjawisko zwane "serem szwajcarskim".


OK, skoro nie przekonują Cię moje argumenty, pomińmy więc proszę polemikę ad persona. Możesz podać przykład SQL Injection włamującego się do mojego kodu, bez literackich spostrzeżeń a propos mojej osoby?

PS.
To tak jakbym zaprojektował i zbudował drewniany most i orzekł, że możecie wszyscy wejść na niego a się nie zawali. Na to pyro, zamiast wejść i skakać i kopać po moście, buduję swój most obok, na pierwszy rzut oka podobny, wchodzi na niego a ten się wali. Mam nadzieję, że analogia jest czytelna.

Podobnego porównania można użyć jeśli chodzi o używanie String, jako zagadnienienia estetycznego. To tak jakby twierdzić, że ponieważ na elementy rozciągane najlepiej nadaje się stalowa lina, a na elementy ściskane (lepiej od liny) drewno, zatem most w całości wykonany z drewna musi być brzydki, będąc wynikiem złej praktyki budowlanej. Mam nadzieję, że ta analogia zadziała z mocą supernowej pośród przepastnego odmętu wszechświata winksmiley.jpg

@pyro
Konkludując i w odwecie polemizując z pyro, proszę o wejście na mój most i zburzenie go, a nie udowadnianie, że gdzieś, kiedyś widziano most, który się zawalił winksmiley.jpg To simple to prove it?

Pozdrawiam

Napisany przez: Crozin 2.03.2010, 15:27:45

No przecież już dostałeś przykład:

  1. $sql = "SELECT * FROM video WHERE id = $id;";
Gdzie $id to zmienna przefiltrowana Twoim sposobem. Konieczność pamiętania by każdorazowo (nawet tam gdzie jest to po prostu pozbawione sensu) ..."$id"... jest największą wadą Twojego rozwiązania.

Napisany przez: pyro 2.03.2010, 15:40:06

Ehh... no to dwie rzeczy:

1. Wskaż mi choć jedno miejsce, w którym piszę coś propo Twojej persony. Nawiązuję jedynie do Twoich postów, a nie Ciebie.

2. Skoro już zaczęliśmy się bawić w opowiadanie historyjek, to ja opowiem prawdziwą:

Przedstawiłeś się jako konstruktor mostów. Masz swoje narzędzie - młotek firmy `aoi` (którym w tym wypadku jest podana przez Ciebie funkcja). Udało Ci się zbudować stabilny most na betonowym podłożu (którym w tym wypadku jest podane zapytanie). Teraz inni budowniczy (forumowicze) użyją tego młotka, żeby zbudować swoje mosty, ale zbudują je na przykład na piaszczystym, czy też bagnistym podłożu i będą wadliwe, przy skakaniu zawalą się. Twoja rola jako twórcy odpowiedniego młotka do budowy mostów nie powiodła się.

Prościej już nie wiem jak Ci to wytłumaczyć.

Napisany przez: aio 2.03.2010, 16:50:34

Cytat(Crozin @ 2.03.2010, 15:27:45 ) *
No przecież już dostałeś przykład:
  1. $sql = "SELECT * FROM video WHERE id = $id;";
Gdzie $id to zmienna przefiltrowana Twoim sposobem. Konieczność pamiętania by każdorazowo (nawet tam gdzie jest to po prostu pozbawione sensu) ..."$id"... jest największą wadą Twojego rozwiązania.


Nie no super, nie wiedziałem, że SQL Injection polega na umieszczaniu dowolnego kodu php na serwerze! Jeśli tak to po co w ogóle robić zapytanie do mysql! Nie lepiej od razu dać: echo "My login & password is: ...."; questionmark.gifquestionmark.gif Konieczność pamiętania... Wadą? A jak zapomnisz przekonwertować każdorazowo na liczbę to co się stanie? Jakiś problem aby funkcja _P zwracała quoted String? Wybaczy Pan...

Cytat(pyro @ 2.03.2010, 15:40:06 ) *
Ehh... no to dwie rzeczy:

1. Wskaż mi choć jedno miejsce, w którym piszę coś propo Twojej persony. Nawiązuję jedynie do Twoich postów, a nie Ciebie.

2. Skoro już zaczęliśmy się bawić w opowiadanie historyjek, to ja opowiem prawdziwą:

Przedstawiłeś się jako konstruktor mostów. Masz swoje narzędzie - młotek firmy `aoi` (którym w tym wypadku jest podana przez Ciebie funkcja). Udało Ci się zbudować stabilny most na betonowym podłożu (którym w tym wypadku jest podane zapytanie). Teraz inni budowniczy (forumowicze) użyją tego młotka, żeby zbudować swoje mosty, ale zbudują je na przykład na piaszczystym, czy też bagnistym podłożu i będą wadliwe, przy skakaniu zawalą się. Twoja rola jako twórcy odpowiedniego młotka do budowy mostów nie powiodła się.

Prościej już nie wiem jak Ci to wytłumaczyć.


Dzięki, że wytłumaczyłeś swój brak zrozumienia mnie. Otóż technika budowania mostów polega na nauce sposobu projektowania i wykonania, a nie zrobieniu jednego młotka i podejmowaniu próby budowy wszystkiego tym samym młotkiem. W moim przypadku techniką, którą przedstawiłem jest natywna obsługa Stringu w sql co zapobiega konieczności dodatkowej obsługi, co by było gdyby był UNION, a może DELETE, itd. Panu obok może się nie podobać String, ale nie zauważa, że konwertując na liczbę, potem i tak konwertuje na String, co później znowu jest konwertowane na liczbę.... o rzeczywiście, jakie ładne winksmiley.jpg

Napisany przez: pyro 2.03.2010, 17:54:59

Cytat(aio @ 2.03.2010, 16:50:34 ) *
Otóż technika budowania mostów polega na nauce sposobu projektowania i wykonania, a nie zrobieniu jednego młotka i podejmowaniu próby budowy wszystkiego tym samym młotkiem.


To czemu pokazałeś tylko ten jeden młotek? Widzę, że zaczynasz zaprzeczać samemu sobie.

@aoi, @Crozin ma rację

Napisany przez: Crozin 2.03.2010, 18:02:12

Tak trudno to pojąć, że w sytuacji gdzie użyłbyś takiego zapytania jak ja podałem byłbyś błędnie przekonany o skuteczności owej filtracji (która jak mniemam ma służyć do filtrowania wszystkiego)? Co się czepiasz, że ktoś podaje przykład, w którym użyto innej - bardziej sensownej, czytelnej, "poprawnej" konstrukcji w której to filtrowanie o kant d..y rozbić można, a jej występowanie jest powszechne - jeśli nawet nie u Ciebie, to u dużej części programistów?

Ten wątek ma służyć m. in. promowaniu dobrych praktyk, a Twoja jest wręcz naganna i może doprowadzić innych użytkowników do sytuacji opisanej czy to przeze mnie czy przez pyro.

Cytat
Panu obok może się nie podobać String, ale nie zauważa, że konwertując na liczbę, potem i tak konwertuje na String, co później znowu jest konwertowane na liczbę.... o rzeczywiście, jakie ładne
Jak mniemam również uważasz zapisy typu:
  1. $obj->getId() == "123";
  2. $abc = "123413";
  3. $def = abc() + "4" + 2 - def();
  4. toSth("321", "true - bo przecież z rzutuje na boolean'owskie TRUE");
Za czytelniejsze/bardziej sensowne? Już nie wspominając o tym, że przykładowe ID (użyte w przykładach ilustrujących ułomność Twojej metody) wykorzystujemy tylko w zapytaniach?

PS. Z mojej strony to tyle - nie ciągnę więcej tego wątku.

EDIT:
Zapomniałem dodać: Jak prezentujesz jakieś rozwiązania, to albo opisz, że należy je stosować wyłącznie w określonych przypadkach, albo chociaż zwróć uwagę na to, że w pewnych są kompletnie nieskuteczne.

Napisany przez: aio 3.03.2010, 16:48:55

Cytat(Crozin @ 2.03.2010, 18:02:12 ) *
Tak trudno to pojąć, że w sytuacji gdzie użyłbyś takiego zapytania jak ja podałem byłbyś błędnie przekonany o skuteczności owej filtracji (która jak mniemam ma służyć do filtrowania wszystkiego)? Co się czepiasz, że ktoś podaje przykład, w którym użyto innej - bardziej sensownej, czytelnej, "poprawnej" konstrukcji w której to filtrowanie o kant d..y rozbić można, a jej występowanie jest powszechne - jeśli nawet nie u Ciebie, to u dużej części programistów?

Ten wątek ma służyć m. in. promowaniu dobrych praktyk, a Twoja jest wręcz naganna i może doprowadzić innych użytkowników do sytuacji opisanej czy to przeze mnie czy przez pyro.

Jak mniemam również uważasz zapisy typu:
  1. $obj->getId() == "123";
  2. $abc = "123413";
  3. $def = abc() + "4" + 2 - def();
  4. toSth("321", "true - bo przecież z rzutuje na boolean'owskie TRUE");
Za czytelniejsze/bardziej sensowne? Już nie wspominając o tym, że przykładowe ID (użyte w przykładach ilustrujących ułomność Twojej metody) wykorzystujemy tylko w zapytaniach?

PS. Z mojej strony to tyle - nie ciągnę więcej tego wątku.

EDIT:
Zapomniałem dodać: Jak prezentujesz jakieś rozwiązania, to albo opisz, że należy je stosować wyłącznie w określonych przypadkach, albo chociaż zwróć uwagę na to, że w pewnych są kompletnie nieskuteczne.


No raczej trudno pojąć, skoro składnia ze stringiem występuje celowo właśnie po to aby filtrować zarówno number jak i string i wykorzystać natywny support dla osiągnięcia konkretnego celu. Skoro moje zapytanie przechodzi przez parser sql to chyba nie jest aż tak do dupy jak się koledze wydaje winksmiley.jpg

Panowie. Po co wklejacie jakiś kod (błędny zresztą) nie związany z tematem i wmawiacie mi, że na pewno tak uważam i żeby rzekomo dowieźć swojej racji dumnie ogłaszacie EOT! Jedną linijkę kodu, którą napisałem na siłę mi zmieniacie i mówicie, że musi być zmieniona, czytaj źle napisane zapytanie i wtedy nie będzie działać. Pytam po co? Napisaliście, że nie rozwiązuje to nawet połowy problemów zw. z SQL Injection. Super. Ale na litość boską może chociaż jeden przykład!? Jak ja mówię, że w pewnym przypadku naprzemienna konwersja string<->number jest niekoniecznie potrzebna bo ma inne zalety, to mi się wyjeżdża z argumentem, że gdyby tak było to pisało by się "4" + 2 we wszystkich innych zastosowaniach (sic!)! Czy na prawdę tak trudno sobie wyobrazić sytuację odwrotną: Wy napisaliście kod zabezpieczający. A ja zmienię coś w tym kodzie i będę się upierał, że nie działa Wasz kod! No jest tu sens? Czy istnieje jakikolwiek kod, którego nie da się tak "poprawić" aby go zepsuć? Odpowiedzcie szczerze.

"...albo chociaż zwróć uwagę na to, że w pewnych są kompletnie nieskuteczne" - w jakich? Że jak celowo zrobisz lukę (w tym wypadku usunięty cudzysłów) to będzie luka? Kiedy jest nieskuteczne przy prawidłowym użyciu wg podanego przeze mnie przykładu? Proszę uprzejmie, czekam, bez klęcia, epitetów i wywnętrzania się.



Cytat(pyro @ 2.03.2010, 17:54:59 ) *
To czemu pokazałeś tylko ten jeden młotek? Widzę, że zaczynasz zaprzeczać samemu sobie.

@aoi, @Crozin ma rację


Jaki młotek? Podałem sposób a Wy ten sposób na siłę zmieniacie i udowadniacie, że nie działa. No to udowodniliście, że Wasza metoda jest do niczego. Ok. Widzę.

W czym sobie zaprzeczyłem? Pokazałem sposób - narzędzie + przykład użycia. Rozwiązanie ze stringiem działa zarówno dla number jak i string, z kolejną jeszcze niewymienioną zaletą, że gdyby było dozwolone 0 jako input, to trzeba by było jeszcze dodatkowo uwzględnić wypadek, gdy input (który zawsze jest stringiem) był rzutowany do zera, trzeba by dodatkowo sprawdzać czy string... naprawdę muszę to pisać?

Wyobraźcie sobie: to tak jakbyście słusznie mówili, że żeby zrzutować do integer trzeba napisać $int = (int)$str; a na to ja przychodzę i mówię: no tak, ale jak się napisze $int = (string)$str; to nie będzie działać, więc Wasz kod jest do dupy. Nie na tym przypadkiem polega Wasze udowadnianie?

Może dla odmiany, zamiast orzekać co ja uważam, i że tak bardzo się mylę, może się doczekam tego haku? Szampan wciąż czeka.

Pozdrawiam Szanownych Interlokutorów.

Napisany przez: pyro 3.03.2010, 17:43:05

Cytat(aio @ 3.03.2010, 16:48:55 ) *
Jaki młotek? Podałem sposób a Wy ten sposób na siłę zmieniacie i udowadniacie, że nie działa. No to udowodniliście, że Wasza metoda jest do niczego. Ok. Widzę.


Nie zmieniłem nawet jednej literki. Użyłem dokładnie tego sposobu, który Ty podałeś. I ci przykładowo udowodniłem, że Twój sposób jest nieskuteczny.

Cytat(aio @ 3.03.2010, 16:48:55 ) *
W czym sobie zaprzeczyłem? Pokazałem sposób - narzędzie + przykład użycia.


I Ci właśnie pokazałem, używając tego samego narzędzia, na innym przykładzie, że sposób jest zawodny.

Cytat(aio @ 3.03.2010, 16:48:55 ) *
Rozwiązanie ze stringiem działa zarówno dla number jak i string,


Ehhh... kolejny raz piszę, że podałem Ci przykład, w którym Twój sposób na liczbę nie działa.

Cytat(aio @ 3.03.2010, 16:48:55 ) *
z kolejną jeszcze niewymienioną zaletą, że gdyby było dozwolone 0 jako input, to trzeba by było jeszcze dodatkowo uwzględnić wypadek, gdy input (który zawsze jest stringiem) był rzutowany do zera, trzeba by dodatkowo sprawdzać czy string... naprawdę muszę to pisać?


Czy z inputa czy nie, tak czy inaczej zawiedzie... sciana.gif

Cytat(aio @ 3.03.2010, 16:48:55 ) *
w jakich? Że jak celowo zrobisz lukę (w tym wypadku usunięty cudzysłów) to będzie luka?


Twoje zabezpieczenie nawet z cudzysłowami nie w jednym przypadku zawiedzie. A wymuszanie ich używania na użytkowniku jest co najmniej nie na miejscu, chociażby ze względów wydajnościowych. Dodatkowo piszący kod może o nich zapomnieć ich użycia dla danych numerycznych, bo ma taki dobry nawyk i skrypt dalej dziurawy.

Napisany przez: erix 3.03.2010, 19:26:34

~aio, a przeczytałeś ten wątek od początku?

Napisany przez: thek 4.03.2010, 00:33:49

Ja właśnie za to, iż PHP jest tak "nieokreślony" z początku podchodziłem do niego hurraoptymistycznie. Fajnie, w końcu nie martwię się o typy danych i wiele innych aspektów, które wyniosłem z nauki C++. Tyle że ta dowolność w wypadku www i ataków jest największym zagrożeniem. Co z tego, że baza mi w locie zamieni string na liczbę czy na odwrót. Skoro ja oczekuję od usera danych o określonym formacie to taki ma do skryptu trafić i koniec, kropka. Ma to być string, to niech bedzie, nawet jeśli z cyfr złożony. Ale niech mi baza tego nie przerabia na int bo może to dla mnie nie być to co chcę. ma być liczba? To filtruję i wywalam wszystko co nie jest cyframi lub na etapie walidacji choćby jeden znak nie będzie cyfrą to od razu user jest na cenzurowanym. Dla mnie mysql_real_escape_string, filter_var i czasem preg_match to niezbędne minimum. Dziś nawet jak się okazało zabezpieczenia pchnąłem na taki poziom w swoim panelu, że szef zgłupiał winksmiley.jpg Jakim sposobem? tak miałem skonstruowany kod, że jedyne modyfikacje rekordów w bazie mogła wykonać osoba je zakładająca, gdyż wszystko wiązało się z kontrolą działań użytkownika przy współdziałaniu bazy danych oraz zmiennych sesyjnych. W efekcie tylko bezpośrednie modyfikacje rekordów w bazie odnosiły sukces. Nawet osoba z uprawnieniami administratora w serwisie mogła jedynie na to patrzeć z boku, gdyż skrypt nie pozwalał mu modyfikować danych innych userów winksmiley.jpg Tak bowiem był skonstruowany by blokować wszelkie próby ingerencji użytkowników w dane innych użytkowników. A admin to też user :] No ale tak to jest z custom made skryptami. Niektórzy mają dziury i mają to gdzieś, a inni przesadzą przypadkiem w druga stronę i user jest w 100% zabezpieczony. Nawet przed administratorem winksmiley.jpg

Napisany przez: aio 4.03.2010, 13:38:25

Cytat(erix @ 3.03.2010, 19:26:34 ) *
~aio, a przeczytałeś ten wątek od początku?


Witam, ale co masz na myśli, bo nie będę się upierał, że niczego nie pominąłem, bo sam chyba przyznasz, że mimo różnych rozwiązań, co ileś postów (o dziwo po moim również) na nowo pojawia się wątek z a to INTEGEREM, a to UNION... itd (!), co sprawia, że przeglądanie postu gdy kolejny raz widzę, że zawiera w sobie słowo UNION, powoduje, że nawet nie czytam winksmiley.jpg Jeśli to w jakimś stopniu kogoś uraziło, to pragnę przeprosić. Z kolei autor wątku edytując pierwszy post, jak sądzę, starał się dokonać pewnego streszczenia zagadnienia, a pytanie w takim razie do Ciebie, czy zauważyłeś czym różni się moje rozwiązanie od proponowanych tutaj? Szczegół, którego tutaj, jeśli się nie mylę nikt nie poruszył (nawet koledzy, którzy udowadniają mi dodupowość tego skompresowanego semantycznie do jedniej linii algorytmu)? I żeby była jasność - nigdzie nie napisałem, że ta linijka kodu jest genialna i mam nadzieje, że nigdzie się nie wywyższyłem ponad kogokolwiek z Was, ale naprawdę, jeśli ktoś wykażę się wiedzą otrzyma nagrodę a ja się czegoś nauczę, słowo dałem i dotrzymam.


Cytat(thek @ 4.03.2010, 00:33:49 ) *
Ja właśnie za to, iż PHP jest tak "nieokreślony" z początku podchodziłem do niego hurraoptymistycznie. Fajnie, w końcu nie martwię się o typy danych i wiele innych aspektów, które wyniosłem z nauki C++. Tyle że ta dowolność w wypadku www i ataków jest największym zagrożeniem. Co z tego, że baza mi w locie zamieni string na liczbę czy na odwrót. Skoro ja oczekuję od usera danych o określonym formacie to taki ma do skryptu trafić i koniec, kropka. Ma to być string, to niech bedzie, nawet jeśli z cyfr złożony. Ale niech mi baza tego nie przerabia na int bo może to dla mnie nie być to co chcę. ma być liczba? To filtruję i wywalam wszystko co nie jest cyframi lub na etapie walidacji choćby jeden znak nie będzie cyfrą to od razu user jest na cenzurowanym. Dla mnie mysql_real_escape_string, filter_var i czasem preg_match to niezbędne minimum. Dziś nawet jak się okazało zabezpieczenia pchnąłem na taki poziom w swoim panelu, że szef zgłupiał winksmiley.jpg Jakim sposobem? tak miałem skonstruowany kod, że jedyne modyfikacje rekordów w bazie mogła wykonać osoba je zakładająca, gdyż wszystko wiązało się z kontrolą działań użytkownika przy współdziałaniu bazy danych oraz zmiennych sesyjnych. W efekcie tylko bezpośrednie modyfikacje rekordów w bazie odnosiły sukces. Nawet osoba z uprawnieniami administratora w serwisie mogła jedynie na to patrzeć z boku, gdyż skrypt nie pozwalał mu modyfikować danych innych userów winksmiley.jpg Tak bowiem był skonstruowany by blokować wszelkie próby ingerencji użytkowników w dane innych użytkowników. A admin to też user :] No ale tak to jest z custom made skryptami. Niektórzy mają dziury i mają to gdzieś, a inni przesadzą przypadkiem w druga stronę i user jest w 100% zabezpieczony. Nawet przed administratorem winksmiley.jpg

Zgadzam się w całej rozciągłości. Czegoś nie jesteśmy pewni, róbmy filtry i obudowujmy nasz skrypt. W końcu jeśli user ma podać integer a podał '4abc' to też wypadałoby go za to opierniczyć i samo (int) nie wystarczy, prawda? Do żadnych, hiper wypasionych, wielopoziomowych walidacji nic nie mam. Mam nadzieje, że się rozumiemy. Przedstawiłem tylko pewien trick, który jest bardziej wynikiem świadomości tego co się dzieje na poziomie cpp (opisałem to wyżej), niż tego co daje nieokreśloność php. W końcu wątek jest o SQL Injection i już chyba bardziej na temat napisać nie mogłem i mam nadzieję, że się nie rozwlekam jeśli nie muszę. Otrzymałem zarzut, że ... no już nie będę cytował. Pytam więc, z ciekawości: da się ominąć? - pokażcie.



Cytat(pyro @ 3.03.2010, 17:43:05 ) *
Nie zmieniłem nawet jednej literki. Użyłem dokładnie tego sposobu, który Ty podałeś. I ci przykładowo udowodniłem, że Twój sposób jest nieskuteczny.



I Ci właśnie pokazałem, używając tego samego narzędzia, na innym przykładzie, że sposób jest zawodny.



Ehhh... kolejny raz piszę, że podałem Ci przykład, w którym Twój sposób na liczbę nie działa.



Czy z inputa czy nie, tak czy inaczej zawiedzie... sciana.gif



Twoje zabezpieczenie nawet z cudzysłowami nie w jednym przypadku zawiedzie. A wymuszanie ich używania na użytkowniku jest co najmniej nie na miejscu, chociażby ze względów wydajnościowych. Dodatkowo piszący kod może o nich zapomnieć ich użycia dla danych numerycznych, bo ma taki dobry nawyk i skrypt dalej dziurawy.


Podałem przykład użycia. Przykład jest po to aby wyjaśnić jak użyć. Jeśli naprawdę nie rozumiesz mojego przykładu to zamień sobie w moim przykładzie `login` na swoje `video_id`. A następnie włamuj się swoim (dobrym skądinąd) requestem, a później dla porównania przeklej swój. Ręczę Ci, że zajmie Ci to krócej niż kolejne wytłuszczanie poszczególnych słów w swoim poście! winksmiley.jpg Dżizaz to jest takie trudne serio? Przecież zapytanie musi być dobrze napisane! Przecież to jest kwintesencja w ogóle programowania! Argument "a co jak zapomnę...?" jest takim samo dobry jak "a co jak zapomnę zamknąć drzwi od samochodu?". Jeśli nadal nie rozumiesz na podstawie jednej linijki o co w nim chodzi, to ja Ci już nie pomogę, gdyż musiałbym powtarzać objaśnienia z powyższych postów.

PS. Żartobliwie dodam, że zaczynam rozumieć też autora wątku, który prawdopodobnie znając Waszą uszczypliwość, podaje co najmniej dwa sposoby na rzutowanie typów, bo w przeciwnym razie zarzucilibyście mu, że można inaczej i że jego kod jest do... winksmiley.jpg A przychylając się do prośby autora "Proszę osoby obeznane w tym temacie, aby dopisały tu własne propozycje metod zabezpieczenia się przed tym atakiem" lecz z wyłączeniem słowa "obeznane" bo się za taką nie uważam, po prostu to zrobiłem. Mało tego, pytam i sam jestem ciekaw czy ktoś jest w stanie to obejść...

Cytat(pyro @ 3.03.2010, 17:43:05 ) *
Twoje zabezpieczenie nawet z cudzysłowami nie w jednym przypadku zawiedzie

Obiecałem. Podaj przykład, masz szampana.

Napisany przez: pyro 4.03.2010, 18:26:00

Ehhh... ja się po prostu poddaję. Nie ważne ile bym nie tłumaczył, to @aoi i tak się upierasz przy swoim, nie patrząc na to obiektywnie, nie ważne jak bardzo się mylisz. @aoi, warto zwrócić uwagę, że nie tylko ja Ci próbuję to wytłumaczyć, ale także parę innych osób.

Napisany przez: aio 5.03.2010, 13:27:00

Cytat(pyro @ 4.03.2010, 18:26:00 ) *
Ehhh... ja się po prostu poddaję. Nie ważne ile bym nie tłumaczył, to @aoi i tak się upierasz przy swoim, nie patrząc na to obiektywnie, nie ważne jak bardzo się mylisz. @aoi, warto zwrócić uwagę, że nie tylko ja Ci próbuję to wytłumaczyć, ale także parę innych osób.


E tam poddawać się. Ważne, że już ochłonęliśmy, będzie się milej rozmawiać. Wiem, że dyskusja jest taka dlatego, że w pierwszym poście nie napisałem 1000 słów opisu, dlaczego tak a nie inaczej i szczegółowo how to do & how not. Ale na tym polegał post: 1 obraz, zero objaśnień. Oczywiście wiem, że przez to mogłem być źle zrozumiany, a propos tego na co zwrócić uwagę ale przecież po pojawieniu się wątpliwości zostało to wyjaśnione w drugim poście! Tak samo jak nie można pominąć/zapomnieć w Waszych kodach '(int)' tak samo w moim nie można pominąć "'"! I nie jest kwestią do roztrząsania tutaj czy kod jest ładny, pół-brzydki, czy para-pseudo-nie-teges! Chodzi w tym o to, że mimo bardzo obszernie przedstawianego zagadnienia ataku SQL, zadałem pytanie czy jest możliwe rozprawić się z problemem ekstremalnie prostym i banalnym zabiegiem? Czy chroni to w zupełności czy nie? Mam nadzieję, że chociaż zauważyłeś, że w kod zawiera ochronę przeciwko namnażającym się slashom, na co nikt nie zwrócił uwagi w całym wątku, a istotne jest nie tyle przy SELECT ile przy zapisie do bazy, bo może zepsuć dane, bo to jest właśnie szczegół, o którym najłatwiej zapomnieć, ale większość woli pisać super-klasy podmieniające UNION (przepraszam, że się znowu z tego nabijam - już nie będę). I tak, widzę, że wszyscy twierdzą, że się mylę. Ale przypominam, tu przecież nie chodzi o to, że mój przykład nie waliduje inputu pod każdym możliwym do wymyślenia i uniwersalnym kątem oraz nie wyświetla okienka z napisem "Dear Almighty User, please kindly note you have failed on input"; bo takie rzeczy zależą od indywidualnych potrzeb. Ale chodzi o to czy da się dokonać ataku SQL! Obojętnie czy przyjmując liczbę, string, czy odczytując czy zapisując do bazy.
Ja podałem 1 obraz, Wy macie pretensje, że nie napisałem 1000 słów. Wy piszecie 1000 słów, to pokażcie chociaż 1 obraz.

Cieszę się bardzo, że piszecie, że się mylę, że nie zadziała nawet z cudzysłowem. Nawet nie chce, żebyście mi przyznawali rację! Ale dlaczego jedyny argument to "bo nie i już"? Jestem ciekaw. Podajcie przykład.

PS. ERRATA do pierwszego postu: ewentualną nagrodę otrzymuje pierwszy łamacz! Bo znając już Waszą czepialskość, każdy skopiuje post i będzie sądownie dochodził należności winksmiley.jpg

Napisany przez: kuzdo 5.03.2010, 18:03:52

Mam pewien problem... Testuje sobie różne zabezpieczenia własnych skryptów i chciałem teraz przeprowadzić atak na skrypt bez zabezpieczeń i wyłączonym magic_quotes_gpc()... Problem w tym, że nie chce wykonać się w ogóle zapytanie... Oto one:

  1. INSERT INTO title (title) VALUES (12) UNION SELECT title FROM title WHERE id = 1

W tej tabeli już są wpisy... Jednak MySQL wywala błąd: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT title FROM title WHERE id = 1' at line 1"
Może mi ktoś powiedzieć dlaczego jest błąd?

Edit: Dodam, że działa tylko SELECT ... UNION SELECT ... Operacje na różnych tabelach też nie działają...

Napisany przez: bełdzio 5.03.2010, 21:07:30

UNION SELECT możesz wstrzyknąć tylko w zapytania pobierające dane, czyli w innego SELECTa

Napisany przez: kuzdo 6.03.2010, 00:46:08

Dzięki za odpowiedź... Miałem o coś jeszcze się zapytać, ale trochę pogooglowałem i znalazłem odpowiedź... Z początku myślałem, że UNION to tylko taki operator AND, a to jednak pozwala tylko na dodanie dodatkowego SELECT... Myślałem, że za pomocą UNION można wykonać każdą komendę - INSERT, DROP, TRUNCATE, itd. Jeśli jednak się mylę i można je użyć za pomocą UNION, to niech ktoś mnie poprawi...

Napisany przez: pyro 6.03.2010, 09:00:38

UNION, jak sama nazwa mówi (z ang. złączenie) służy do łączenia pobieranych danych.

Napisany przez: GreeN_DG 6.03.2010, 11:43:05

Witam. Chciałbym wrócić do zagadnienia "prepared stat...". Na większości anglojezycznych stron opisują, iż to najlepszy sposób zabezpieczający przed sql inj.. Czyli przy użyciu ps zmienne są całkowicie oddzielone od spreparowanego zapytania? Cokolwiek by się w nich nie pojawiło będzie zawsze interpretowane jako zmienna danego typu a nie jako cześć zapytania?

Napisany przez: erix 6.03.2010, 11:50:55

Tak.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)