SlideShare uma empresa Scribd logo
1 de 64
Kompletny przewodnik po SQL
             injection dla developerów PHP
             (i nie tylko)


                      Krzysztof Kotowicz
                      PHP Developer

                      http://web.eskot.pl
OWASP                 Medycyna Praktyczna
                      krzysztof@kotowicz.net
10.03.2010

                 Copyright © The OWASP Foundation
                 Permission is granted to copy, distribute and/or modify this document
                 under the terms of the OWASP License.




                 The OWASP Foundation
                 http://www.owasp.org
Plan prezentacji

   Co to jest SQL injection?
   Dlaczego SQL injection jest groźne (demo)?
   Jak się bronić?
      • Prepared statements
      • Escape'owanie
      • Procedury składowane
      • Metody uzupełniające
   Podsumowanie



                                            OWASP   2
Omawiane bazy danych (RDBMS)

   MySQL
   Oracle
   MS SQL Server
   W mniejszym stopniu:
     • PostgreSQL
     • SQLite




                               OWASP   3
Omawiane projekty PHP
    PDO – PHP data objects
    • Wspólny interfejs dla różnych RDBMS
    Doctrine 1.2
    • ORM (Object Relational Mapper) używany m.in. we frameworku Symfony
    Propel 1.4
    • ORM konkurencyjny dla Doctrine
    • Używany we frameworku Symfony
    Zend Framework 1.10
    • Popularny framework MVC dla PHP
    MDB2 2.4.1
    • Warstwa abstrakcji bazy danych (DBAL)
    • Dystrybuowany przez PEAR

                                                            OWASP          4
Co to jest SQL injection?




                            OWASP   5
SQL injection – krótka definicja
Jest to rodzaj ataku na aplikacje internetowe.
Polega na tym, że dane od użytkownika
pochodzące z:

  URL: www.example.com?id=1
  Formularzy: email=a@example.com
  Innych elementów: np. cookie, nagłówki HTTP


zostają zmanipulowane tak, że w podatnej aplikacji
zostaje wykonane „wstrzyknięte” przez
atakującego polecenie SQL.
                                            OWASP    6
Przykład – formularz logowania
SELECT * FROM users WHERE login = '{$login}' and
password_hash = MD5('{$password}')

$login = "' or 1=1 -- ";
$password = "dowolne";

// zamierzalismy osiagnac to (kod  dane)
SELECT * FROM users WHERE login = '' or 1=1 -- '
and password_hash = MD5('dowolne')

// serwer interpretuje to tak
SELECT * FROM users WHERE login = '' or 1=1 -- '
and password_hash = MD5('dowolne')


Użytkownik jest zalogowany bez znajomości loginu
 ani hasła
                                           OWASP    7
Dlaczego jest groźne?
      DEMO




                        OWASP   8
Czym grozi podatność na SQL injection?

 Nieuprawniony dostęp do aplikacji
 Dostęp do całej zawartości bazy / baz na
  serwerze
 Denial of service
 Możliwość modyfikacji danych w bazie
 Przeczytanie / zapisanie pliku na serwerze
 Wykonanie kodu na serwerze



                                      OWASP    9
Kilka faktów

    Podatności na injection na pierwszym miejscu
     OWASP Top 10 2010 RC
    Odpowiada za 40–60% przypadków wycieku
     danych [1] [2]
    Obecne techniki ataku są bardzo zaawansowane i
     często automatyzowane
    • Podatność nie tylko w części WHERE
    • Czasem celem jest zepsucie zapytania
    Codziennie znajdowane podatności, nawet w
     nowych aplikacjach


                                             OWASP    10
Jak się bronić?




                  OWASP   11
Jak się bronić przed SQL injection?

 Źródło podatności - łączenie kodu z danymi
 SELECT * FROM users WHERE login = 'login'


Metody obrony
  Oddzielenie kodu od danych
    prepared statements
    stored procedures
  Escape'owanie danych



                                             OWASP   12
Jak się bronić?
Prepared statements




                      OWASP   13
Prepared statements – zasada działania

1.   Przygotowujemy polecenie SQL (string)
     W miejsce danych wstawiamy znaczniki
                          WHERE a = ? ... WHERE a = :col

2.   Przesyłamy polecenie na serwer             PREPARE
3.   Podajemy zestaw danych do polecenia
4.   Wykonujemy polecenie                       EXECUTE
5.   Odbieramy rezultat

     3, 4, 5 można powtarzać...
6.   Czyścimy polecenie

                                                OWASP      14
Prepared statements - przykład

 Przykład działania (PDO)
// przygotowujemy zapytanie
$stmt = $dbh->prepare("INSERT INTO SUMMARIES
  (name, sum) VALUES (:name, :sum)");

// podajemy wartosci zmiennych – RAZEM Z TYPAMI!
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':sum', $sum, PDO::PARAM_INT);

// podajemy wartości zmiennych
$name = 'something';
$value = 1234;

// wykonujemy zapytanie
$stmt->execute();
$stmt = null; //zwalniamy pamiec
                                           OWASP    15
Prepared statements - zalety

   Polecenia SQL są całkowicie oddzielone od
    przetwarzanych danych
   Brak możliwości wstrzyknięcia kodu SQL
   Polecenie SQL jest przez serwer kompilowane tylko raz
    – potencjalne zwiększenie wydajności zapytań

$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':sum', $sum, PDO::PARAM_INT);

// petla po danych...
foreach ($do_bazy as $name => $value) {
  $stmt->execute();
}

                                                OWASP       16
Prepared statements - uwagi

   Nie wszystkie typy poleceń można parametryzować
   Nie w każdym miejscu polecenia można wstawić
    parametr

    -- blad
    SELECT * FROM :tabela
    SELECT :funkcja(:kolumna) FROM :widok

    -- nie tego się spodziewacie
    SELECT * FROM tabela WHERE :kolumna = 1
    SELECT * FROM tabela GROUP BY :kolumna


   Samo ich użycie nie wymusza stosowania parametrów
   Czasem są emulowane (ale to dobrze!)
                                              OWASP     17
Prepared statements w Doctrine

   Używa PDO   (emulacja dla Oracle)   i prepared statements
   Zamiast SQL używa własnego języka – DQL

$q = Doctrine_Query::create()
  ->select('u.id')
  ->from('User u')
  ->where('u.login = ?', ‘mylogin');

echo $q->getSqlQuery();
// SELECT u.id AS u__id FROM user u
// WHERE (u.login = ?)

$users = $q->execute();

                                                       OWASP    18
Prepared statements w Doctrine cd.

 Wciąż można „wpaść”
   $q = Doctrine_Query::create()
       ->update('Account')
       ->set('amount', 'amount + 200')
       ->where("id > {$_GET['id']}");

 Trzeba poprawić na:

   ->where("id > ?", (int) $_GET['id']);


 NIGDY nie umieszczaj danych wejściowych
  bezpośrednio w treści zapytań

                                           OWASP   19
Prepared statements w Propel

 Podobnie jak Doctrine, oparty na PDO
// poprzez Criteria
$c = new Criteria();
$c->add(AuthorPeer::FIRST_NAME, "Karl");
$authors = AuthorPeer::doSelect($c);

// poprzez customowy SQL (czasem jest latwiej)
$pdo = Propel::getConnection(BookPeer::DATABASE_NAME);
$sql = "SELECT * FROM skomplikowany_sql
        JOIN cos_jeszcze_gorszego USING cos_tam
        WHERE kolumna = :col)”;
$stmt = $pdo->prepare($sql);
$stmt->execute(array('col' => 'Bye bye SQLi!');


                                            OWASP    20
Prepared statements w Zend Framework

   PDO (+ mysqli + oci8 + sqlsrv)

// prepare + execute
$stmt = $db->prepare('INSERT INTO server (key,
          value) VALUES (:key,:value)');
$stmt->bindParam('key', $k);
$stmt->bindParam('value', $v);

foreach ($_SERVER as $k => $v)
   $stmt->execute();

// prepare + execute w jednym kroku
$stmt = $db->query('SELECT * FROM bugs WHERE
      reported_by = ? AND bug_status = ?',
       array('goofy', 'FIXED'));

while ($row = $stmt->fetch())
    echo $row['bug_description'];
                                                 OWASP   21
MDB2

 Oparty na konkretnych sterownikach baz
  danych (mysql, oci8, mssql, ...)
 Emuluje PS, jeśli baza ich nie wspiera
   $types = array('integer', 'text', 'text');
   $stmt = $mdb2->prepare('INSERT INTO numbers
   VALUES (:id, :name, :lang)', $types);

   $data = array('id' => 1,
                 'name' => 'one',
                 'lang' => 'en');

   $affectedRows = $stmt->execute($data);
   $stmt->free();

                                            OWASP   22
Prepared statements - podsumowanie

 Oferują bardzo dobre zabezpieczenie
  (jeśli użyte poprawnie)
 Łatwe w użyciu, niewielkie zmiany w kodzie
 Dobre wsparcie we frameworkach
 Mają swoje ograniczenia
 Czasem muszą być uzupełniane innymi
  metodami zabezpieczeń




                                       OWASP   23
Jak się bronić?
Escape'owanie danych




                       OWASP   24
Escape'owanie – zasada działania

    Dane i polecenia wciąż trzymamy w jednej zmiennej, ale
     zabezpieczamy je
    Liczby
    • Rzutowanie na (int) / (float) – nie is_numeric [1]!
    Teksty - zwykle otoczone apostrofami: '

      .. WHERE pole = 'DANE TEKSTOWE' AND ...

    • Jeśli w tekście również są apostrofy, trzeba je odróżnić od
      apostrofu „kończącego”
    • Apostrof wewnątrz danych jest poprzedzany znakiem
      specjalnym, np. ""
    • Reguły escape'owania zależą od kontekstu!

                                                             OWASP   25
Escape'owanie – kontekst

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).
   / Źródło: php.net manual /


$user = addslashes($_GET['u']);
$pass = addslashes($_GET['p']);

$sql = "SELECT * FROM users WHERE username =
        '{$user}' AND password = '{$pass}'";

$ret = exec_sql($sql);


 Czy jesteś bezpieczny?

                                                                       OWASP        26
NIE

      OWASP
Escape'owanie – kontekst cd.

    Różne RDBMS mają różne sposoby escape'owania danych
     (zależy to też od konfiguracji bazy)
    addslashes() tylko „przypadkiem” działa dla MySQL
    RBDMS                 Funkcja             mam 'apostrofy'
     PDO         $pdo->quote($val, $type)        n/d (różnie)
MySQL (mysql)    mysql_real_escape_string    mam 'apostrofy'
MySQL (mysqli)   mysqli_real_escape_string   mam 'apostrofy'
 Oracle (oci8)      n/d - str_replace()      mam ''apostrofy''
    SQLite         sqlite_escape_string      mam ''apostrofy''
MS SQL (mssql)      n/d - str_replace()      mam ''apostrofy''
 PostgreSQL         pg_escape_string()       mam ''apostrofy''

                                                       OWASP     28
Escape'owanie – kontekst cd.
// SELECT * FROM users WHERE username =
// '{$user}' AND password = '{$pass}'
$_GET['u'] = "cokolwiek'";
$_GET['p'] = " or 1=1 -- ";

// MySQL widzi to tak:
SELECT * FROM users WHERE username = 'cokolwiek''
AND password = ' or 1=1 -- '

// SQLite / MS SQL / Oracle / PostgreSQL - tak:
SELECT * FROM users WHERE username = 'cokolwiek''
AND password = ' or 1=1 -- '



   Nie używaj addslashes(), używaj funkcji konkretnej
    bazy
   Czy teraz jesteś bezpieczny?
                                             OWASP       29
PRAWIE

         OWASP
Pułapki escape'owania – zestawy znaków

 Błędy wykryte w 2006 r. w PostgreSQL i MySQL [1]
    [2]
 W niektórych wielobajtowych zestawach znaków
  pomimo escape’owania można doprowadzić do
  SQL injection
  zostaje „połknięty” przez wielobajtowy znak
 Przykład:
      •   BF 27 [ ¬ ' ]  BF 5C 27 [ ¬  ' ]
      •   Pierwsze dwa bajty to w charsecie GBK znak ¿
      •   Serwer „zobaczy” ciąg ¿'

                                               OWASP     31
Pułapki escape'owania – zestawy znaków

   Podatne są różne azjatyckie zestawy znaków
   Na szczęście nie UTF-8!
   W PostgreSQL zastosowano escape'owanie poprzez ''
    (zamiast ')
   W mysql_real_escape_string() zastosowano
    uwzględnianie bieżącego zestawu znaków
     •   Nie zawsze zadziała! [1] [2]
   Kontekst to również zestaw znaków




                                            OWASP       32
Escape'owanie – nazwy obiektów

 Nazwy kolumn, tabel, baz
      •   Nie ma dobrej ogólnej metody na ich
          escape'owanie
      •   W różnych bazach różne listy słów
          zarezerwowanych, różne długości nazw itp.

Jeśli musisz pobierać te nazwy od użytkownika, zastosuj
      whitelisting (blacklisting w ostateczności)




                                                 OWASP    33
Escape'owanie – nazwy obiektów cd.

 Przykład – sortowanie po kolumnie
 Jest podatność w $order, ale nie możesz
  użyć escape'owania
$cat_id = (int) $_GET['cid'];
$order = $_GET['column'];
$stmt = $pdo->prepare("SELECT * FROM products WHERE
                       cid = :cid ORDER BY $order");

$stmt->bindParam(':cid', $cat_id, PDO::PARAM_INT);

if ($stmt->execute()) {
    ...
}

                                            OWASP      34
Escape'owanie – nazwy obiektów cd.

 Whitelisting
  $columns = array( // lista dozwolonych kolumn
  'product_name','cid','price',
  );

  if (!in_array($order, $columns, true))
  $order = 'product_name'; // wartosc domyslna

 Blacklisting
  // tylko znaki a-z i _
  $order = preg_replace('/[^a-z_]/', '', $order);

  // max 40 znakow
  $order = substr($order, 0, 40);

                                                  OWASP   35
Escape'owanie w PDO

 PDO::quote($value, $type, $len)
 Długość i typ bywają ignorowane!
     •   Liczby najlepiej rzutuj na (int), (float)
     •   Teksty – obcinaj ręcznie
$quoted = $pdo->quote($input, PDO::PARAM_STR, 40);




                                                     OWASP   36
Escape'owanie w Doctrine

 Uwaga na Doctrine'owe quote()!
$q = Doctrine_Query::create();
// nie tak!!!
$quoted = $q->getConnection()->quote($input, 'text');

$q->update('User')->set('username', $quoted);
// quote() zamienia ' na '' - exploit (MySQL):
$input = 'anything' where 1=1 -- ';

// trzeba escape'owac poprzez PDO - getDbh():
$quoted = $q->getConnection()
            ->getDbh()
            ->quote($input, PDO::PARAM_STR);
// 'anything ' where 1=1 -- '


                                                OWASP   37
Escape'owanie w Propel

 Poprzez PDO::quote()


$pdo = Propel::getConnection(UserPeer::DATABASE_NAME);

$c = new Criteria();
$c->add(UserPeer::PASSWORD,
        "MD5(".UserPeer::PASSWORD.") "
        ." = " . $pdo->quote($password),
        Criteria::CUSTOM);




                                              OWASP      38
Escape'owanie w Zend Framework

 Funkcje quote(), quoteInto()


$name = $db->quote("O'Reilly");
// 'O'Reilly'

// uproszczone escape'owanie dla jednej zmiennej
$sql = $db->quoteInto("SELECT * FROM products WHERE
 product_name = ?", 'any string');




                                            OWASP     39
Escape'owanie w MDB

 Funkcja quote()

// funkcja quote()- trzeba określić typ
$query = 'INSERT INTO table (id, itemname,
          saved_time) VALUES ('
 . $mdb2->quote($id, 'integer') .', '
 . $mdb2->quote($name, 'text') .', '
 . $mdb2->quote($time, 'timestamp') .')';

$res = $mdb2->exec($query);




                                             OWASP   40
Escape'owanie danych - podsumowanie

   Wydaje się proste – zastępowanie tekstu
   Niestety, tylko się wydaje
     •   Musimy znać kontekst (baza danych, charset)
     •   Istnieją błędne implementacje
   Skłania do stosowania niebezpiecznych konstrukcji
     •   sklejanie poleceń
     •   ignorowanie zmiennych numerycznych
   Stosowanie dopuszczalne tylko, jeśli
     •   Programujemy pod konkretną bazę
     •   Nie ma innej możliwości



                                                       OWASP   41
Jak się bronić?
Procedury składowane




                       OWASP   42
Procedury składowane

   Polecenie SQL (lub seria poleceń) zostaje przeniesione
    na serwer bazy danych i zapisane jako procedura
   Po stronie klienta procedura zostaje wywołana z
    określonymi parametrami (danymi) wejściowymi i
    wyjściowymi
   W parametrach wyjściowych klient otrzymuje wyniki
    procedury

   Dane są formalnie oddzielone od kodu
   To NIE wystarcza


                                                 OWASP       43
Procedury składowane

 Przykład w MS SQL – fragment podatnej
  procedury
CREATE PROCEDURE SP_ProductSearch
@prodname varchar(400)
AS
 DECLARE @sql nvarchar(4000)
 SELECT @sql = 'SELECT ProductID, ProductName,
    Category, Price FROM Product Where ProductName
    LIKE ''' + @prodname + ''''
 EXEC (@sql)
 ...

 To eval() w kolejnym wcieleniu!

                                           OWASP     44
Procedury składowane cd.

 Przykład tej samej podatności w Oracle

CREATE OR REPLACE PROCEDURE
SP_ProductSearch(Prodname IN VARCHAR2) AS
       sqltext VARCHAR2(80);
BEGIN
   sqltext := 'SELECT ProductID, ProductName,
            Category, Price FROM Product
           WHERE ProductName LIKE '''
            || Prodname || '''';
   EXECUTE IMMEDIATE sqltext;
   ...
END;


                                           OWASP   45
Procedury składowane – Dynamic SQL

 Źródło podatności – Dynamic SQL
 • Dane znów „przemieszane” z kodem w jednej
   zmiennej, która zostaje wykonana jako
   polecenie SQL
 Jak się obronić?
 • Oddziel kod od danych
 • Escape'uj




                                     OWASP     46
Procedury składowane w MS SQL

 Oddzielenie danych od kodu
 • użyj sp_executesql razem z listą
   parametrów
CREATE PROCEDURE SP_ProductSearch @prodname
varchar(400) = NULL AS
DECLARE @sql nvarchar(4000)
SELECT @sql = N'SELECT ProductID, ProductName,
               Category, Price FROM Product Where
               ProductName LIKE @p'
EXEC sp_executesql @sql,
     N'@p varchar(400)',
     @prodname


                                            OWASP   47
Procedury składowane w MS SQL cd.

 Escape'owanie zmiennych tekstowych
   Nazwa obiektu         QUOTENAME(@v)

   Tekst <= 128 znaków   QUOTENAME(@v,'''')

   Tekst > 128 znaków    REPLACE(@v,'''','''''')



 Przykład:
   SET @cmd = N'select * from authors where lname=''' +
   REPLACE(@lname, '''', '''''') + N''''

 Escape'uj tylko wtedy, kiedy musisz!
  (używaj sp_executesql z parametrami)
                                                   OWASP   48
Procedury składowane w Oracle

 Oracle - użyj EXECUTE IMMEDIATE ..
  USING
 CREATE OR REPLACE PROCEDURE
 SP_ProductSearch(Prodname IN VARCHAR2) AS
        sqltext VARCHAR2(80);
 BEGIN
   sqltext := 'SELECT ProductID, ProductName,
            Category, Price WHERE
            ProductName=:p';
   EXECUTE IMMEDIATE sqltext USING Prodname;
   ...
 END;

 Escape'owanie - pakiet DBMS_ASSERT

                                           OWASP   49
Procedury składowane w MySQL

 Wsparcie dla Dynamic SQL tylko poprzez
  prepared statements
 Napisanie podatnych procedur jest trudniejsze
  niż procedur zabezpieczonych!
 Wystarczy używać placeholderów zamiast
  doklejać wartości zmiennych




                                        OWASP     50
Procedury składowane w MySQL cd.

 PREPARE / EXECUTE USING /
  DEALLOCATE PREPARE
DELIMITER $$
CREATE PROCEDURE get_users_like (
  IN contains VARCHAR(40))
BEGIN
  SET @like = CONCAT("%", contains, "%");
  SET @sql = "SELECT * FROM users WHERE uname LIKE ?";
  PREPARE get_users_stmt from @sql;
  EXECUTE get_users_stmt USING @like;
  DEALLOCATE PREPARE get_users_stmt;
END$$
DELIMITER ;


                                             OWASP       51
Procedury składowane w MySQL cd.

 Lub jeszcze prościej (bezpośrednio)


DELIMITER $$
CREATE PROCEDURE get_users_like (
  IN contains VARCHAR(40))
BEGIN
  SET @like = CONCAT("%", contains, "%");
  SELECT * FROM users WHERE uname LIKE @like;
END$$
DELIMITER ;



 Escape'owanie – funkcja QUOTE()
                                                OWASP   52
Procedury składowane w PHP

   Różne wsparcie w zależności od RDBMS
   Wsparcie zależy od konkretnego sterownika
   Wspólne API (np. PDO) obsługuje tylko najprostsze
    wywołania
     •   Procedura nic nie zwraca
     •   Procedura zwraca prosty rezultat w parametrze OUT
   Różna obsługa (lub brak) bardziej zaawansowanych
    wywołań
     •   np. pobieranie rekordów z procedur, kursory
   Wsparcie we frameworkach śladowe
   Wciąż występują błędy

                                                       OWASP   53
Procedury składowane w PDO

 Wywołanie procedury

// MySQL
$sql = "CALL get_users_like(:contains)";
// MS SQL – EXEC get_users_like :contains

$stmt = $pdo->prepare($sql);
$ret = $stmt->execute(array('contains' => $input));

foreach($stmt->fetchAll() as $users) {
  var_dump($users);
}

unset($s);



                                            OWASP     54
Procedury składowane w
Doctrine/Propel/Zend Framework
 Doctrine - Brak wsparcia (użyj PDO)
$pdo = Doctrine_Manager::connection()->getDbh();


 Propel – jw.
$pdo = Propel::getConnection(UserPeer::DATABASE_NAME);


 Zend Framework – jw.

$pdo = $db::getConnection();



                                               OWASP     55
Procedury składowane w MDB2

 Trzeba własnoręcznie escape'ować wszystkie
  parametry
 $mdb2->loadModule('Function');
 $multi_query = $mdb2->setOption('multi_query', true);

 if (!PEAR::isError($multi_query)) {

     $result = $mdb2->executeStoredProc('get_users_like',
               array($mdb2->quote($contains, 'text')));
 do {
     while ($row = $result->fetchRow()) {
           var_dump($row);
     }
 } while ($result->nextResult());
 }


                                                OWASP       56
Procedury składowane - pułapki

 Długość zmiennych
CREATE PROCEDURE change_password
@loginname varchar(50),
@old varchar(50),
@new varchar(50)
AS
  DECLARE @command varchar(120)
  SET @command= 'UPDATE users SET password=' +
                 QUOTENAME(@new, '''') +
                 ' WHERE loginname=' +
                 QUOTENAME(@loginname, '''') +
                 ' AND password=' +
                  QUOTENAME(@old, '''')
  EXEC (@command)
GO

                                            OWASP   57
Procedury składowane - podsumowanie
   Czasochłonne przenoszenie logiki SQL z aplikacji na
    serwer
   Nie są łatwo przenośne pomiędzy RDBMS
   Napisane bezpiecznych procedur i tak wymaga użycia
    prepared statements lub escape'owania danych
   Źle zaimplementowane mogą zwiększyć podatność
      • Zarówno wywołanie procedury, jak i jej kod jest
          podatny
      • Procedura może mieć większe uprawnienia niż
          kod ją wywołujący
   Złe wsparcie w PHP i we frameworkach


                                             OWASP        58
Procedury składowane - podsumowanie
Mają dużo zalet poza naszym obszarem zainteresowania
    Można precyzyjnie zarządzać uprawnieniami do procedur
    Przydatne w wypadku stosowania różnych klientów
     (Java/.NET + PHP)
    Mogą zwiększyć wydajność
    I wiele innych...
Wnioski:
Pozwalają osiągnąć dobre zabezpieczenie przed SQL
    injection, ale przy dużych kosztach.
Niezbędne jest zabezpieczanie samego kodu procedur
    przed SQL injection.


                                                   OWASP     59
Jak się bronić?
Metody uzupełniające




                       OWASP   60
Walidacja i filtrowanie danych
 Kontrola poprawności danych zewnętrznych
 Odbywa się przed przetwarzaniem tych danych
 Nie myl z escape'owaniem!
  Filter INPUT - escape OUTPUT
 Osobne reguły walidacji dla każdego
  parametru - sprawdzaj m.in.
     •   Typ zmiennej
     •   Skalar / tablica
     •   Wartości min / max
     •   Długość danych tekstowych! [1]

                                          OWASP   61
Uzupełniające metody obrony

Komplementarne do poprzednich!
 Zasada najmniejszych uprawnień przy łączeniu się do
   bazy danych
 Wyłączenie nieużywanych funkcji, kont, pakietów
   dostarczanych z bazą danych
 Regularne aktualizowanie serwera bazy danych
 Dobra konfiguracja PHP i bazy
      •   magic_quotes_* = false
      •   display_errors = false
   Dobrze zaprojektowana baza danych


                                             OWASP      62
Podsumowanie

   Zwracaj uwagę na SQL injection - pojedynczy błąd
    może wiele kosztować!
   Preferuj rozwiązania kompleksowe - np. frameworki
   Filtruj wszystkie dane wejściowe
   Pamiętaj o typach i długościach zmiennych
   Stosuj whitelisting zamiast blacklistingu - to drugie
    kiedyś zawiedzie!
   Stosuj prepared statements wszędzie, gdzie możesz
   Unikaj escape'owania
   W procedurach składowanych uważaj na Dynamic SQL


                                                OWASP       63
Linki
       Omawiane projekty
    •      sqlmap.sourceforge.net
    •      php.net/manual/en/book.pdo.php
    •      www.doctrine-project.org
    •      propel.phpdb.org/trac
    •      framework.zend.com
    •      pear.php.net/package/MDB2
       O SQL injection
    •      www.owasp.org/index.php/SQL_Injection
    •      unixwiz.net/techtips/sql-injection.html
    •      delicious.com/koto/sql+injection
       Hack me
    •      threats.pl/bezpieczenstwo-aplikacji-internetowych
    •      tinyurl.com/webgoat
    •      mavensecurity.com/dojo.php
       krzysztof@kotowicz.net       http://blog.kotowicz.net
                                                                OWASP   64

Mais conteúdo relacionado

Mais procurados

View, Store Procedure & Function and Trigger in MySQL - Thaipt
View, Store Procedure & Function and Trigger in MySQL - ThaiptView, Store Procedure & Function and Trigger in MySQL - Thaipt
View, Store Procedure & Function and Trigger in MySQL - ThaiptFramgia Vietnam
 
Basics of Object Oriented Programming in Python
Basics of Object Oriented Programming in PythonBasics of Object Oriented Programming in Python
Basics of Object Oriented Programming in PythonSujith Kumar
 
C# lecture 2: Literals , Variables and Data Types in C#
C# lecture 2: Literals , Variables and Data Types in C#C# lecture 2: Literals , Variables and Data Types in C#
C# lecture 2: Literals , Variables and Data Types in C#Dr.Neeraj Kumar Pandey
 
Web application vulnerabilities
Web application vulnerabilitiesWeb application vulnerabilities
Web application vulnerabilitiesebusinessmantra
 
Sql injection attack
Sql injection attackSql injection attack
Sql injection attackRaghav Bisht
 
Using SQL Queries to Insert, Update, Delete, and View Data.ppt
Using SQL Queries to Insert, Update, Delete, and View Data.pptUsing SQL Queries to Insert, Update, Delete, and View Data.ppt
Using SQL Queries to Insert, Update, Delete, and View Data.pptMohammedJifar1
 
Python debugging techniques
Python debugging techniquesPython debugging techniques
Python debugging techniquesTuomas Suutari
 
Programming for Problem Solving
Programming for Problem SolvingProgramming for Problem Solving
Programming for Problem SolvingSreedhar Chowdam
 
Object-oriented Programming-with C#
Object-oriented Programming-with C#Object-oriented Programming-with C#
Object-oriented Programming-with C#Doncho Minkov
 
Core programming in c
Core programming in cCore programming in c
Core programming in cRahul Pandit
 
Secure software development presentation
Secure software development presentationSecure software development presentation
Secure software development presentationMahdi Dolati
 
44 randomized-algorithms
44 randomized-algorithms44 randomized-algorithms
44 randomized-algorithmsAjitSaraf1
 
An Introduction to Programming in Java: Arrays
An Introduction to Programming in Java: ArraysAn Introduction to Programming in Java: Arrays
An Introduction to Programming in Java: ArraysMartin Chapman
 
pseudocode and Flowchart
pseudocode and Flowchartpseudocode and Flowchart
pseudocode and FlowchartALI RAZA
 

Mais procurados (20)

View, Store Procedure & Function and Trigger in MySQL - Thaipt
View, Store Procedure & Function and Trigger in MySQL - ThaiptView, Store Procedure & Function and Trigger in MySQL - Thaipt
View, Store Procedure & Function and Trigger in MySQL - Thaipt
 
Sql injection
Sql injectionSql injection
Sql injection
 
Basics of Object Oriented Programming in Python
Basics of Object Oriented Programming in PythonBasics of Object Oriented Programming in Python
Basics of Object Oriented Programming in Python
 
SQL Injection
SQL Injection SQL Injection
SQL Injection
 
C# lecture 2: Literals , Variables and Data Types in C#
C# lecture 2: Literals , Variables and Data Types in C#C# lecture 2: Literals , Variables and Data Types in C#
C# lecture 2: Literals , Variables and Data Types in C#
 
Sql select
Sql select Sql select
Sql select
 
Web application vulnerabilities
Web application vulnerabilitiesWeb application vulnerabilities
Web application vulnerabilities
 
Sql injection attack
Sql injection attackSql injection attack
Sql injection attack
 
Using SQL Queries to Insert, Update, Delete, and View Data.ppt
Using SQL Queries to Insert, Update, Delete, and View Data.pptUsing SQL Queries to Insert, Update, Delete, and View Data.ppt
Using SQL Queries to Insert, Update, Delete, and View Data.ppt
 
Python debugging techniques
Python debugging techniquesPython debugging techniques
Python debugging techniques
 
Programming for Problem Solving
Programming for Problem SolvingProgramming for Problem Solving
Programming for Problem Solving
 
C# Arrays
C# ArraysC# Arrays
C# Arrays
 
Object-oriented Programming-with C#
Object-oriented Programming-with C#Object-oriented Programming-with C#
Object-oriented Programming-with C#
 
Strings and pointers
Strings and pointersStrings and pointers
Strings and pointers
 
Core programming in c
Core programming in cCore programming in c
Core programming in c
 
Secure software development presentation
Secure software development presentationSecure software development presentation
Secure software development presentation
 
44 randomized-algorithms
44 randomized-algorithms44 randomized-algorithms
44 randomized-algorithms
 
An Introduction to Programming in Java: Arrays
An Introduction to Programming in Java: ArraysAn Introduction to Programming in Java: Arrays
An Introduction to Programming in Java: Arrays
 
pseudocode and Flowchart
pseudocode and Flowchartpseudocode and Flowchart
pseudocode and Flowchart
 
Database connectivity in python
Database connectivity in pythonDatabase connectivity in python
Database connectivity in python
 

Destaque

Ms Sql Server
Ms Sql ServerMs Sql Server
Ms Sql Serverscale
 
Jerzy proficz -_programowanie_w_java
Jerzy proficz -_programowanie_w_javaJerzy proficz -_programowanie_w_java
Jerzy proficz -_programowanie_w_javalargeman
 
Programowanie w języku Scala
Programowanie w języku ScalaProgramowanie w języku Scala
Programowanie w języku ScalaDevCastZone
 
Crowdsourcing testowania aplikacji i serwisów webowych, czyli testowanie 2.0
Crowdsourcing testowania aplikacji i serwisów webowych, czyli testowanie 2.0Crowdsourcing testowania aplikacji i serwisów webowych, czyli testowanie 2.0
Crowdsourcing testowania aplikacji i serwisów webowych, czyli testowanie 2.0Damian Szczurek
 
Wprowadzenie do C# i platformy .NET
Wprowadzenie do C# i platformy .NETWprowadzenie do C# i platformy .NET
Wprowadzenie do C# i platformy .NETDevCastZone
 
Kurs MySQL i SQL, bazy danych - prezentacja ppt, pdf, porady, trening, kurs i...
Kurs MySQL i SQL, bazy danych - prezentacja ppt, pdf, porady, trening, kurs i...Kurs MySQL i SQL, bazy danych - prezentacja ppt, pdf, porady, trening, kurs i...
Kurs MySQL i SQL, bazy danych - prezentacja ppt, pdf, porady, trening, kurs i...twitch.tv/katmpb
 
Refaktoryzacja kodu w języku PHP
Refaktoryzacja kodu w języku PHPRefaktoryzacja kodu w języku PHP
Refaktoryzacja kodu w języku PHPDevCastZone
 
Matryca śledzenia - Traceability Matrix
Matryca śledzenia - Traceability MatrixMatryca śledzenia - Traceability Matrix
Matryca śledzenia - Traceability MatrixRadoslaw Smilgin
 
Grywalizacja (gamification) w testowaniu
Grywalizacja (gamification) w testowaniuGrywalizacja (gamification) w testowaniu
Grywalizacja (gamification) w testowaniuRadoslaw Smilgin
 
JavaStart - kurs Java Podstawy
JavaStart - kurs Java PodstawyJavaStart - kurs Java Podstawy
JavaStart - kurs Java PodstawyJavaStart
 

Destaque (15)

Ms Sql Server
Ms Sql ServerMs Sql Server
Ms Sql Server
 
Excel Zaawansowany - Lekcja 3
Excel Zaawansowany - Lekcja 3Excel Zaawansowany - Lekcja 3
Excel Zaawansowany - Lekcja 3
 
Tester Warszawa
Tester WarszawaTester Warszawa
Tester Warszawa
 
Jerzy proficz -_programowanie_w_java
Jerzy proficz -_programowanie_w_javaJerzy proficz -_programowanie_w_java
Jerzy proficz -_programowanie_w_java
 
Programowanie w języku Scala
Programowanie w języku ScalaProgramowanie w języku Scala
Programowanie w języku Scala
 
Crowdsourcing testowania aplikacji i serwisów webowych, czyli testowanie 2.0
Crowdsourcing testowania aplikacji i serwisów webowych, czyli testowanie 2.0Crowdsourcing testowania aplikacji i serwisów webowych, czyli testowanie 2.0
Crowdsourcing testowania aplikacji i serwisów webowych, czyli testowanie 2.0
 
Wprowadzenie do C# i platformy .NET
Wprowadzenie do C# i platformy .NETWprowadzenie do C# i platformy .NET
Wprowadzenie do C# i platformy .NET
 
Kurs MySQL i SQL, bazy danych - prezentacja ppt, pdf, porady, trening, kurs i...
Kurs MySQL i SQL, bazy danych - prezentacja ppt, pdf, porady, trening, kurs i...Kurs MySQL i SQL, bazy danych - prezentacja ppt, pdf, porady, trening, kurs i...
Kurs MySQL i SQL, bazy danych - prezentacja ppt, pdf, porady, trening, kurs i...
 
Przetestuj swoje CV
Przetestuj swoje CVPrzetestuj swoje CV
Przetestuj swoje CV
 
Refaktoryzacja kodu w języku PHP
Refaktoryzacja kodu w języku PHPRefaktoryzacja kodu w języku PHP
Refaktoryzacja kodu w języku PHP
 
Matryca śledzenia - Traceability Matrix
Matryca śledzenia - Traceability MatrixMatryca śledzenia - Traceability Matrix
Matryca śledzenia - Traceability Matrix
 
Grywalizacja (gamification) w testowaniu
Grywalizacja (gamification) w testowaniuGrywalizacja (gamification) w testowaniu
Grywalizacja (gamification) w testowaniu
 
JavaStart - kurs Java Podstawy
JavaStart - kurs Java PodstawyJavaStart - kurs Java Podstawy
JavaStart - kurs Java Podstawy
 
Tester.pl - Numer 4
Tester.pl - Numer 4Tester.pl - Numer 4
Tester.pl - Numer 4
 
ISTQB REX BLACK book
ISTQB REX BLACK bookISTQB REX BLACK book
ISTQB REX BLACK book
 

Semelhante a Kompletny przewodnik po SQL injection dla developerów PHP (i nie tylko)

“Jak ocalić swoje dane przed SQL injection?” - Krzysztof Kotowicz na KrakSpot...
“Jak ocalić swoje dane przed SQL injection?” - Krzysztof Kotowicz na KrakSpot...“Jak ocalić swoje dane przed SQL injection?” - Krzysztof Kotowicz na KrakSpot...
“Jak ocalić swoje dane przed SQL injection?” - Krzysztof Kotowicz na KrakSpot...krakspot
 
Jak ocalić swoje dane przed SQL injection?
Jak ocalić swoje dane przed SQL injection?Jak ocalić swoje dane przed SQL injection?
Jak ocalić swoje dane przed SQL injection?Krzysztof Kotowicz
 
Zhakuj swojego Wordpressa, WordUP Trojmiasto
Zhakuj swojego Wordpressa, WordUP TrojmiastoZhakuj swojego Wordpressa, WordUP Trojmiasto
Zhakuj swojego Wordpressa, WordUP Trojmiastosecman_pl
 
Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPLaravel Poland MeetUp
 
"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać
"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać
"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbaćBartosz Ratajczyk
 
Secure Coding w praktyce.
Secure Coding w praktyce.Secure Coding w praktyce.
Secure Coding w praktyce.Semihalf
 
Poznaj wp-config.php "Ukryte" możliwości.
Poznaj wp-config.php  "Ukryte" możliwości.Poznaj wp-config.php  "Ukryte" możliwości.
Poznaj wp-config.php "Ukryte" możliwości.Marcin Jóźwiak
 
Środowisko testowe pod REST-a
Środowisko testowe pod REST-aŚrodowisko testowe pod REST-a
Środowisko testowe pod REST-aFuture Processing
 
Sql z perspektywy hakera czy twoje dane są bezpieczne ? - Sqlday 2016 Wrocław
Sql z perspektywy hakera   czy twoje dane są bezpieczne ? - Sqlday 2016 WrocławSql z perspektywy hakera   czy twoje dane są bezpieczne ? - Sqlday 2016 Wrocław
Sql z perspektywy hakera czy twoje dane są bezpieczne ? - Sqlday 2016 WrocławKrzysztof Binkowski
 
Tworzenie, zaciemnianie i analiza złośliwego kodu JavaScript
Tworzenie, zaciemnianie i analiza złośliwego kodu JavaScriptTworzenie, zaciemnianie i analiza złośliwego kodu JavaScript
Tworzenie, zaciemnianie i analiza złośliwego kodu JavaScriptKrzysztof Kotowicz
 
Using Red Gate SQL Doc for database documentation
Using Red Gate SQL Doc for database documentationUsing Red Gate SQL Doc for database documentation
Using Red Gate SQL Doc for database documentationMariusz Koprowski
 
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)Codesushi.co (CODESUSHI LLC)
 
REST API - teoria i praktyka - WordUp Trójmiasto
REST API - teoria i praktyka - WordUp TrójmiastoREST API - teoria i praktyka - WordUp Trójmiasto
REST API - teoria i praktyka - WordUp TrójmiastoTomasz Dziuda
 
Michał Dec - Quality in Clouds
Michał Dec - Quality in CloudsMichał Dec - Quality in Clouds
Michał Dec - Quality in Cloudskraqa
 
Laravel workshops 1
Laravel workshops 1Laravel workshops 1
Laravel workshops 1Kamil Fojuth
 
Tomasz Kopacz MTS 2012 Azure - Co i kiedy użyć (IaaS vs paas vshybrid cloud v...
Tomasz Kopacz MTS 2012 Azure - Co i kiedy użyć (IaaS vs paas vshybrid cloud v...Tomasz Kopacz MTS 2012 Azure - Co i kiedy użyć (IaaS vs paas vshybrid cloud v...
Tomasz Kopacz MTS 2012 Azure - Co i kiedy użyć (IaaS vs paas vshybrid cloud v...Tomasz Kopacz
 
Wzorce projektowe w praktyce
Wzorce projektowe w praktyceWzorce projektowe w praktyce
Wzorce projektowe w praktycePHPstokPHPstok
 

Semelhante a Kompletny przewodnik po SQL injection dla developerów PHP (i nie tylko) (20)

“Jak ocalić swoje dane przed SQL injection?” - Krzysztof Kotowicz na KrakSpot...
“Jak ocalić swoje dane przed SQL injection?” - Krzysztof Kotowicz na KrakSpot...“Jak ocalić swoje dane przed SQL injection?” - Krzysztof Kotowicz na KrakSpot...
“Jak ocalić swoje dane przed SQL injection?” - Krzysztof Kotowicz na KrakSpot...
 
Jak ocalić swoje dane przed SQL injection?
Jak ocalić swoje dane przed SQL injection?Jak ocalić swoje dane przed SQL injection?
Jak ocalić swoje dane przed SQL injection?
 
Zhakuj swojego Wordpressa, WordUP Trojmiasto
Zhakuj swojego Wordpressa, WordUP TrojmiastoZhakuj swojego Wordpressa, WordUP Trojmiasto
Zhakuj swojego Wordpressa, WordUP Trojmiasto
 
Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHP
 
"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać
"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać
"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać
 
Secure Coding w praktyce.
Secure Coding w praktyce.Secure Coding w praktyce.
Secure Coding w praktyce.
 
Poznaj wp-config.php "Ukryte" możliwości.
Poznaj wp-config.php  "Ukryte" możliwości.Poznaj wp-config.php  "Ukryte" możliwości.
Poznaj wp-config.php "Ukryte" możliwości.
 
Środowisko testowe pod REST-a
Środowisko testowe pod REST-aŚrodowisko testowe pod REST-a
Środowisko testowe pod REST-a
 
Sql z perspektywy hakera czy twoje dane są bezpieczne ? - Sqlday 2016 Wrocław
Sql z perspektywy hakera   czy twoje dane są bezpieczne ? - Sqlday 2016 WrocławSql z perspektywy hakera   czy twoje dane są bezpieczne ? - Sqlday 2016 Wrocław
Sql z perspektywy hakera czy twoje dane są bezpieczne ? - Sqlday 2016 Wrocław
 
Tworzenie, zaciemnianie i analiza złośliwego kodu JavaScript
Tworzenie, zaciemnianie i analiza złośliwego kodu JavaScriptTworzenie, zaciemnianie i analiza złośliwego kodu JavaScript
Tworzenie, zaciemnianie i analiza złośliwego kodu JavaScript
 
Using Red Gate SQL Doc for database documentation
Using Red Gate SQL Doc for database documentationUsing Red Gate SQL Doc for database documentation
Using Red Gate SQL Doc for database documentation
 
HTML5: Atak i obrona
HTML5: Atak i obronaHTML5: Atak i obrona
HTML5: Atak i obrona
 
JRuby real use case
JRuby real use caseJRuby real use case
JRuby real use case
 
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
 
REST API - teoria i praktyka - WordUp Trójmiasto
REST API - teoria i praktyka - WordUp TrójmiastoREST API - teoria i praktyka - WordUp Trójmiasto
REST API - teoria i praktyka - WordUp Trójmiasto
 
Michał Dec - Quality in Clouds
Michał Dec - Quality in CloudsMichał Dec - Quality in Clouds
Michał Dec - Quality in Clouds
 
Laravel workshops 1
Laravel workshops 1Laravel workshops 1
Laravel workshops 1
 
Testowanie na 101 sposobów
Testowanie na 101 sposobówTestowanie na 101 sposobów
Testowanie na 101 sposobów
 
Tomasz Kopacz MTS 2012 Azure - Co i kiedy użyć (IaaS vs paas vshybrid cloud v...
Tomasz Kopacz MTS 2012 Azure - Co i kiedy użyć (IaaS vs paas vshybrid cloud v...Tomasz Kopacz MTS 2012 Azure - Co i kiedy użyć (IaaS vs paas vshybrid cloud v...
Tomasz Kopacz MTS 2012 Azure - Co i kiedy użyć (IaaS vs paas vshybrid cloud v...
 
Wzorce projektowe w praktyce
Wzorce projektowe w praktyceWzorce projektowe w praktyce
Wzorce projektowe w praktyce
 

Mais de Krzysztof Kotowicz

Trusted Types - Securing the DOM from the bottom up (JSNation Amsterdam)
Trusted Types - Securing the DOM from the bottom up (JSNation Amsterdam)Trusted Types - Securing the DOM from the bottom up (JSNation Amsterdam)
Trusted Types - Securing the DOM from the bottom up (JSNation Amsterdam)Krzysztof Kotowicz
 
Trusted Types and the end of DOM XSS
Trusted Types and the end of DOM XSSTrusted Types and the end of DOM XSS
Trusted Types and the end of DOM XSSKrzysztof Kotowicz
 
Biting into the forbidden fruit. Lessons from trusting Javascript crypto.
Biting into the forbidden fruit. Lessons from trusting Javascript crypto.Biting into the forbidden fruit. Lessons from trusting Javascript crypto.
Biting into the forbidden fruit. Lessons from trusting Javascript crypto.Krzysztof Kotowicz
 
Hacking HTML5 offensive course (Zeronights edition)
Hacking HTML5 offensive course (Zeronights edition)Hacking HTML5 offensive course (Zeronights edition)
Hacking HTML5 offensive course (Zeronights edition)Krzysztof Kotowicz
 
I'm in ur browser, pwning your stuff - Attacking (with) Google Chrome Extensions
I'm in ur browser, pwning your stuff - Attacking (with) Google Chrome ExtensionsI'm in ur browser, pwning your stuff - Attacking (with) Google Chrome Extensions
I'm in ur browser, pwning your stuff - Attacking (with) Google Chrome ExtensionsKrzysztof Kotowicz
 
I'm in your browser, pwning your stuff
I'm in your browser, pwning your stuffI'm in your browser, pwning your stuff
I'm in your browser, pwning your stuffKrzysztof Kotowicz
 
Advanced Chrome extension exploitation
Advanced Chrome extension exploitationAdvanced Chrome extension exploitation
Advanced Chrome extension exploitationKrzysztof Kotowicz
 
Html5: Something wicked this way comes (Hack in Paris)
Html5: Something wicked this way comes (Hack in Paris)Html5: Something wicked this way comes (Hack in Paris)
Html5: Something wicked this way comes (Hack in Paris)Krzysztof Kotowicz
 
Something wicked this way comes - CONFidence
Something wicked this way comes - CONFidenceSomething wicked this way comes - CONFidence
Something wicked this way comes - CONFidenceKrzysztof Kotowicz
 
Html5: something wicked this way comes - HackPra
Html5: something wicked this way comes - HackPraHtml5: something wicked this way comes - HackPra
Html5: something wicked this way comes - HackPraKrzysztof Kotowicz
 
Html5: something wicked this way comes
Html5: something wicked this way comesHtml5: something wicked this way comes
Html5: something wicked this way comesKrzysztof Kotowicz
 
Creating, obfuscating and analyzing malware JavaScript
Creating, obfuscating and analyzing malware JavaScriptCreating, obfuscating and analyzing malware JavaScript
Creating, obfuscating and analyzing malware JavaScriptKrzysztof Kotowicz
 
SQL Injection: complete walkthrough (not only) for PHP developers
SQL Injection: complete walkthrough (not only) for PHP developersSQL Injection: complete walkthrough (not only) for PHP developers
SQL Injection: complete walkthrough (not only) for PHP developersKrzysztof Kotowicz
 

Mais de Krzysztof Kotowicz (14)

Trusted Types - Securing the DOM from the bottom up (JSNation Amsterdam)
Trusted Types - Securing the DOM from the bottom up (JSNation Amsterdam)Trusted Types - Securing the DOM from the bottom up (JSNation Amsterdam)
Trusted Types - Securing the DOM from the bottom up (JSNation Amsterdam)
 
Trusted Types @ W3C TPAC 2018
Trusted Types @ W3C TPAC 2018Trusted Types @ W3C TPAC 2018
Trusted Types @ W3C TPAC 2018
 
Trusted Types and the end of DOM XSS
Trusted Types and the end of DOM XSSTrusted Types and the end of DOM XSS
Trusted Types and the end of DOM XSS
 
Biting into the forbidden fruit. Lessons from trusting Javascript crypto.
Biting into the forbidden fruit. Lessons from trusting Javascript crypto.Biting into the forbidden fruit. Lessons from trusting Javascript crypto.
Biting into the forbidden fruit. Lessons from trusting Javascript crypto.
 
Hacking HTML5 offensive course (Zeronights edition)
Hacking HTML5 offensive course (Zeronights edition)Hacking HTML5 offensive course (Zeronights edition)
Hacking HTML5 offensive course (Zeronights edition)
 
I'm in ur browser, pwning your stuff - Attacking (with) Google Chrome Extensions
I'm in ur browser, pwning your stuff - Attacking (with) Google Chrome ExtensionsI'm in ur browser, pwning your stuff - Attacking (with) Google Chrome Extensions
I'm in ur browser, pwning your stuff - Attacking (with) Google Chrome Extensions
 
I'm in your browser, pwning your stuff
I'm in your browser, pwning your stuffI'm in your browser, pwning your stuff
I'm in your browser, pwning your stuff
 
Advanced Chrome extension exploitation
Advanced Chrome extension exploitationAdvanced Chrome extension exploitation
Advanced Chrome extension exploitation
 
Html5: Something wicked this way comes (Hack in Paris)
Html5: Something wicked this way comes (Hack in Paris)Html5: Something wicked this way comes (Hack in Paris)
Html5: Something wicked this way comes (Hack in Paris)
 
Something wicked this way comes - CONFidence
Something wicked this way comes - CONFidenceSomething wicked this way comes - CONFidence
Something wicked this way comes - CONFidence
 
Html5: something wicked this way comes - HackPra
Html5: something wicked this way comes - HackPraHtml5: something wicked this way comes - HackPra
Html5: something wicked this way comes - HackPra
 
Html5: something wicked this way comes
Html5: something wicked this way comesHtml5: something wicked this way comes
Html5: something wicked this way comes
 
Creating, obfuscating and analyzing malware JavaScript
Creating, obfuscating and analyzing malware JavaScriptCreating, obfuscating and analyzing malware JavaScript
Creating, obfuscating and analyzing malware JavaScript
 
SQL Injection: complete walkthrough (not only) for PHP developers
SQL Injection: complete walkthrough (not only) for PHP developersSQL Injection: complete walkthrough (not only) for PHP developers
SQL Injection: complete walkthrough (not only) for PHP developers
 

Kompletny przewodnik po SQL injection dla developerów PHP (i nie tylko)

  • 1. Kompletny przewodnik po SQL injection dla developerów PHP (i nie tylko) Krzysztof Kotowicz PHP Developer http://web.eskot.pl OWASP Medycyna Praktyczna krzysztof@kotowicz.net 10.03.2010 Copyright © The OWASP Foundation Permission is granted to copy, distribute and/or modify this document under the terms of the OWASP License. The OWASP Foundation http://www.owasp.org
  • 2. Plan prezentacji  Co to jest SQL injection?  Dlaczego SQL injection jest groźne (demo)?  Jak się bronić? • Prepared statements • Escape'owanie • Procedury składowane • Metody uzupełniające  Podsumowanie OWASP 2
  • 3. Omawiane bazy danych (RDBMS)  MySQL  Oracle  MS SQL Server  W mniejszym stopniu: • PostgreSQL • SQLite OWASP 3
  • 4. Omawiane projekty PHP  PDO – PHP data objects • Wspólny interfejs dla różnych RDBMS  Doctrine 1.2 • ORM (Object Relational Mapper) używany m.in. we frameworku Symfony  Propel 1.4 • ORM konkurencyjny dla Doctrine • Używany we frameworku Symfony  Zend Framework 1.10 • Popularny framework MVC dla PHP  MDB2 2.4.1 • Warstwa abstrakcji bazy danych (DBAL) • Dystrybuowany przez PEAR OWASP 4
  • 5. Co to jest SQL injection? OWASP 5
  • 6. SQL injection – krótka definicja Jest to rodzaj ataku na aplikacje internetowe. Polega na tym, że dane od użytkownika pochodzące z: URL: www.example.com?id=1 Formularzy: email=a@example.com Innych elementów: np. cookie, nagłówki HTTP zostają zmanipulowane tak, że w podatnej aplikacji zostaje wykonane „wstrzyknięte” przez atakującego polecenie SQL. OWASP 6
  • 7. Przykład – formularz logowania SELECT * FROM users WHERE login = '{$login}' and password_hash = MD5('{$password}') $login = "' or 1=1 -- "; $password = "dowolne"; // zamierzalismy osiagnac to (kod dane) SELECT * FROM users WHERE login = '' or 1=1 -- ' and password_hash = MD5('dowolne') // serwer interpretuje to tak SELECT * FROM users WHERE login = '' or 1=1 -- ' and password_hash = MD5('dowolne') Użytkownik jest zalogowany bez znajomości loginu ani hasła OWASP 7
  • 8. Dlaczego jest groźne? DEMO OWASP 8
  • 9. Czym grozi podatność na SQL injection?  Nieuprawniony dostęp do aplikacji  Dostęp do całej zawartości bazy / baz na serwerze  Denial of service  Możliwość modyfikacji danych w bazie  Przeczytanie / zapisanie pliku na serwerze  Wykonanie kodu na serwerze OWASP 9
  • 10. Kilka faktów  Podatności na injection na pierwszym miejscu OWASP Top 10 2010 RC  Odpowiada za 40–60% przypadków wycieku danych [1] [2]  Obecne techniki ataku są bardzo zaawansowane i często automatyzowane • Podatność nie tylko w części WHERE • Czasem celem jest zepsucie zapytania  Codziennie znajdowane podatności, nawet w nowych aplikacjach OWASP 10
  • 11. Jak się bronić? OWASP 11
  • 12. Jak się bronić przed SQL injection?  Źródło podatności - łączenie kodu z danymi SELECT * FROM users WHERE login = 'login' Metody obrony Oddzielenie kodu od danych prepared statements stored procedures Escape'owanie danych OWASP 12
  • 13. Jak się bronić? Prepared statements OWASP 13
  • 14. Prepared statements – zasada działania 1. Przygotowujemy polecenie SQL (string) W miejsce danych wstawiamy znaczniki WHERE a = ? ... WHERE a = :col 2. Przesyłamy polecenie na serwer PREPARE 3. Podajemy zestaw danych do polecenia 4. Wykonujemy polecenie EXECUTE 5. Odbieramy rezultat 3, 4, 5 można powtarzać... 6. Czyścimy polecenie OWASP 14
  • 15. Prepared statements - przykład  Przykład działania (PDO) // przygotowujemy zapytanie $stmt = $dbh->prepare("INSERT INTO SUMMARIES (name, sum) VALUES (:name, :sum)"); // podajemy wartosci zmiennych – RAZEM Z TYPAMI! $stmt->bindParam(':name', $name, PDO::PARAM_STR); $stmt->bindParam(':sum', $sum, PDO::PARAM_INT); // podajemy wartości zmiennych $name = 'something'; $value = 1234; // wykonujemy zapytanie $stmt->execute(); $stmt = null; //zwalniamy pamiec OWASP 15
  • 16. Prepared statements - zalety  Polecenia SQL są całkowicie oddzielone od przetwarzanych danych  Brak możliwości wstrzyknięcia kodu SQL  Polecenie SQL jest przez serwer kompilowane tylko raz – potencjalne zwiększenie wydajności zapytań $stmt->bindParam(':name', $name, PDO::PARAM_STR); $stmt->bindParam(':sum', $sum, PDO::PARAM_INT); // petla po danych... foreach ($do_bazy as $name => $value) { $stmt->execute(); } OWASP 16
  • 17. Prepared statements - uwagi  Nie wszystkie typy poleceń można parametryzować  Nie w każdym miejscu polecenia można wstawić parametr -- blad SELECT * FROM :tabela SELECT :funkcja(:kolumna) FROM :widok -- nie tego się spodziewacie SELECT * FROM tabela WHERE :kolumna = 1 SELECT * FROM tabela GROUP BY :kolumna  Samo ich użycie nie wymusza stosowania parametrów  Czasem są emulowane (ale to dobrze!) OWASP 17
  • 18. Prepared statements w Doctrine  Używa PDO (emulacja dla Oracle) i prepared statements  Zamiast SQL używa własnego języka – DQL $q = Doctrine_Query::create() ->select('u.id') ->from('User u') ->where('u.login = ?', ‘mylogin'); echo $q->getSqlQuery(); // SELECT u.id AS u__id FROM user u // WHERE (u.login = ?) $users = $q->execute(); OWASP 18
  • 19. Prepared statements w Doctrine cd.  Wciąż można „wpaść” $q = Doctrine_Query::create() ->update('Account') ->set('amount', 'amount + 200') ->where("id > {$_GET['id']}");  Trzeba poprawić na: ->where("id > ?", (int) $_GET['id']);  NIGDY nie umieszczaj danych wejściowych bezpośrednio w treści zapytań OWASP 19
  • 20. Prepared statements w Propel  Podobnie jak Doctrine, oparty na PDO // poprzez Criteria $c = new Criteria(); $c->add(AuthorPeer::FIRST_NAME, "Karl"); $authors = AuthorPeer::doSelect($c); // poprzez customowy SQL (czasem jest latwiej) $pdo = Propel::getConnection(BookPeer::DATABASE_NAME); $sql = "SELECT * FROM skomplikowany_sql JOIN cos_jeszcze_gorszego USING cos_tam WHERE kolumna = :col)”; $stmt = $pdo->prepare($sql); $stmt->execute(array('col' => 'Bye bye SQLi!'); OWASP 20
  • 21. Prepared statements w Zend Framework  PDO (+ mysqli + oci8 + sqlsrv) // prepare + execute $stmt = $db->prepare('INSERT INTO server (key, value) VALUES (:key,:value)'); $stmt->bindParam('key', $k); $stmt->bindParam('value', $v); foreach ($_SERVER as $k => $v) $stmt->execute(); // prepare + execute w jednym kroku $stmt = $db->query('SELECT * FROM bugs WHERE reported_by = ? AND bug_status = ?', array('goofy', 'FIXED')); while ($row = $stmt->fetch()) echo $row['bug_description']; OWASP 21
  • 22. MDB2  Oparty na konkretnych sterownikach baz danych (mysql, oci8, mssql, ...)  Emuluje PS, jeśli baza ich nie wspiera $types = array('integer', 'text', 'text'); $stmt = $mdb2->prepare('INSERT INTO numbers VALUES (:id, :name, :lang)', $types); $data = array('id' => 1, 'name' => 'one', 'lang' => 'en'); $affectedRows = $stmt->execute($data); $stmt->free(); OWASP 22
  • 23. Prepared statements - podsumowanie  Oferują bardzo dobre zabezpieczenie (jeśli użyte poprawnie)  Łatwe w użyciu, niewielkie zmiany w kodzie  Dobre wsparcie we frameworkach  Mają swoje ograniczenia  Czasem muszą być uzupełniane innymi metodami zabezpieczeń OWASP 23
  • 25. Escape'owanie – zasada działania  Dane i polecenia wciąż trzymamy w jednej zmiennej, ale zabezpieczamy je  Liczby • Rzutowanie na (int) / (float) – nie is_numeric [1]!  Teksty - zwykle otoczone apostrofami: ' .. WHERE pole = 'DANE TEKSTOWE' AND ... • Jeśli w tekście również są apostrofy, trzeba je odróżnić od apostrofu „kończącego” • Apostrof wewnątrz danych jest poprzedzany znakiem specjalnym, np. "" • Reguły escape'owania zależą od kontekstu! OWASP 25
  • 26. Escape'owanie – kontekst 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). / Źródło: php.net manual / $user = addslashes($_GET['u']); $pass = addslashes($_GET['p']); $sql = "SELECT * FROM users WHERE username = '{$user}' AND password = '{$pass}'"; $ret = exec_sql($sql);  Czy jesteś bezpieczny? OWASP 26
  • 27. NIE OWASP
  • 28. Escape'owanie – kontekst cd.  Różne RDBMS mają różne sposoby escape'owania danych (zależy to też od konfiguracji bazy)  addslashes() tylko „przypadkiem” działa dla MySQL RBDMS Funkcja mam 'apostrofy' PDO $pdo->quote($val, $type) n/d (różnie) MySQL (mysql) mysql_real_escape_string mam 'apostrofy' MySQL (mysqli) mysqli_real_escape_string mam 'apostrofy' Oracle (oci8) n/d - str_replace() mam ''apostrofy'' SQLite sqlite_escape_string mam ''apostrofy'' MS SQL (mssql) n/d - str_replace() mam ''apostrofy'' PostgreSQL pg_escape_string() mam ''apostrofy'' OWASP 28
  • 29. Escape'owanie – kontekst cd. // SELECT * FROM users WHERE username = // '{$user}' AND password = '{$pass}' $_GET['u'] = "cokolwiek'"; $_GET['p'] = " or 1=1 -- "; // MySQL widzi to tak: SELECT * FROM users WHERE username = 'cokolwiek'' AND password = ' or 1=1 -- ' // SQLite / MS SQL / Oracle / PostgreSQL - tak: SELECT * FROM users WHERE username = 'cokolwiek'' AND password = ' or 1=1 -- '  Nie używaj addslashes(), używaj funkcji konkretnej bazy  Czy teraz jesteś bezpieczny? OWASP 29
  • 30. PRAWIE OWASP
  • 31. Pułapki escape'owania – zestawy znaków  Błędy wykryte w 2006 r. w PostgreSQL i MySQL [1] [2]  W niektórych wielobajtowych zestawach znaków pomimo escape’owania można doprowadzić do SQL injection  zostaje „połknięty” przez wielobajtowy znak  Przykład: • BF 27 [ ¬ ' ]  BF 5C 27 [ ¬ ' ] • Pierwsze dwa bajty to w charsecie GBK znak ¿ • Serwer „zobaczy” ciąg ¿' OWASP 31
  • 32. Pułapki escape'owania – zestawy znaków  Podatne są różne azjatyckie zestawy znaków  Na szczęście nie UTF-8!  W PostgreSQL zastosowano escape'owanie poprzez '' (zamiast ')  W mysql_real_escape_string() zastosowano uwzględnianie bieżącego zestawu znaków • Nie zawsze zadziała! [1] [2]  Kontekst to również zestaw znaków OWASP 32
  • 33. Escape'owanie – nazwy obiektów  Nazwy kolumn, tabel, baz • Nie ma dobrej ogólnej metody na ich escape'owanie • W różnych bazach różne listy słów zarezerwowanych, różne długości nazw itp. Jeśli musisz pobierać te nazwy od użytkownika, zastosuj whitelisting (blacklisting w ostateczności) OWASP 33
  • 34. Escape'owanie – nazwy obiektów cd.  Przykład – sortowanie po kolumnie  Jest podatność w $order, ale nie możesz użyć escape'owania $cat_id = (int) $_GET['cid']; $order = $_GET['column']; $stmt = $pdo->prepare("SELECT * FROM products WHERE cid = :cid ORDER BY $order"); $stmt->bindParam(':cid', $cat_id, PDO::PARAM_INT); if ($stmt->execute()) { ... } OWASP 34
  • 35. Escape'owanie – nazwy obiektów cd.  Whitelisting $columns = array( // lista dozwolonych kolumn 'product_name','cid','price', ); if (!in_array($order, $columns, true)) $order = 'product_name'; // wartosc domyslna  Blacklisting // tylko znaki a-z i _ $order = preg_replace('/[^a-z_]/', '', $order); // max 40 znakow $order = substr($order, 0, 40); OWASP 35
  • 36. Escape'owanie w PDO  PDO::quote($value, $type, $len)  Długość i typ bywają ignorowane! • Liczby najlepiej rzutuj na (int), (float) • Teksty – obcinaj ręcznie $quoted = $pdo->quote($input, PDO::PARAM_STR, 40); OWASP 36
  • 37. Escape'owanie w Doctrine  Uwaga na Doctrine'owe quote()! $q = Doctrine_Query::create(); // nie tak!!! $quoted = $q->getConnection()->quote($input, 'text'); $q->update('User')->set('username', $quoted); // quote() zamienia ' na '' - exploit (MySQL): $input = 'anything' where 1=1 -- '; // trzeba escape'owac poprzez PDO - getDbh(): $quoted = $q->getConnection() ->getDbh() ->quote($input, PDO::PARAM_STR); // 'anything ' where 1=1 -- ' OWASP 37
  • 38. Escape'owanie w Propel  Poprzez PDO::quote() $pdo = Propel::getConnection(UserPeer::DATABASE_NAME); $c = new Criteria(); $c->add(UserPeer::PASSWORD, "MD5(".UserPeer::PASSWORD.") " ." = " . $pdo->quote($password), Criteria::CUSTOM); OWASP 38
  • 39. Escape'owanie w Zend Framework  Funkcje quote(), quoteInto() $name = $db->quote("O'Reilly"); // 'O'Reilly' // uproszczone escape'owanie dla jednej zmiennej $sql = $db->quoteInto("SELECT * FROM products WHERE product_name = ?", 'any string'); OWASP 39
  • 40. Escape'owanie w MDB  Funkcja quote() // funkcja quote()- trzeba określić typ $query = 'INSERT INTO table (id, itemname, saved_time) VALUES (' . $mdb2->quote($id, 'integer') .', ' . $mdb2->quote($name, 'text') .', ' . $mdb2->quote($time, 'timestamp') .')'; $res = $mdb2->exec($query); OWASP 40
  • 41. Escape'owanie danych - podsumowanie  Wydaje się proste – zastępowanie tekstu  Niestety, tylko się wydaje • Musimy znać kontekst (baza danych, charset) • Istnieją błędne implementacje  Skłania do stosowania niebezpiecznych konstrukcji • sklejanie poleceń • ignorowanie zmiennych numerycznych  Stosowanie dopuszczalne tylko, jeśli • Programujemy pod konkretną bazę • Nie ma innej możliwości OWASP 41
  • 42. Jak się bronić? Procedury składowane OWASP 42
  • 43. Procedury składowane  Polecenie SQL (lub seria poleceń) zostaje przeniesione na serwer bazy danych i zapisane jako procedura  Po stronie klienta procedura zostaje wywołana z określonymi parametrami (danymi) wejściowymi i wyjściowymi  W parametrach wyjściowych klient otrzymuje wyniki procedury  Dane są formalnie oddzielone od kodu  To NIE wystarcza OWASP 43
  • 44. Procedury składowane  Przykład w MS SQL – fragment podatnej procedury CREATE PROCEDURE SP_ProductSearch @prodname varchar(400) AS DECLARE @sql nvarchar(4000) SELECT @sql = 'SELECT ProductID, ProductName, Category, Price FROM Product Where ProductName LIKE ''' + @prodname + '''' EXEC (@sql) ...  To eval() w kolejnym wcieleniu! OWASP 44
  • 45. Procedury składowane cd.  Przykład tej samej podatności w Oracle CREATE OR REPLACE PROCEDURE SP_ProductSearch(Prodname IN VARCHAR2) AS sqltext VARCHAR2(80); BEGIN sqltext := 'SELECT ProductID, ProductName, Category, Price FROM Product WHERE ProductName LIKE ''' || Prodname || ''''; EXECUTE IMMEDIATE sqltext; ... END; OWASP 45
  • 46. Procedury składowane – Dynamic SQL  Źródło podatności – Dynamic SQL • Dane znów „przemieszane” z kodem w jednej zmiennej, która zostaje wykonana jako polecenie SQL  Jak się obronić? • Oddziel kod od danych • Escape'uj OWASP 46
  • 47. Procedury składowane w MS SQL  Oddzielenie danych od kodu • użyj sp_executesql razem z listą parametrów CREATE PROCEDURE SP_ProductSearch @prodname varchar(400) = NULL AS DECLARE @sql nvarchar(4000) SELECT @sql = N'SELECT ProductID, ProductName, Category, Price FROM Product Where ProductName LIKE @p' EXEC sp_executesql @sql, N'@p varchar(400)', @prodname OWASP 47
  • 48. Procedury składowane w MS SQL cd.  Escape'owanie zmiennych tekstowych Nazwa obiektu QUOTENAME(@v) Tekst <= 128 znaków QUOTENAME(@v,'''') Tekst > 128 znaków REPLACE(@v,'''','''''')  Przykład: SET @cmd = N'select * from authors where lname=''' + REPLACE(@lname, '''', '''''') + N''''  Escape'uj tylko wtedy, kiedy musisz! (używaj sp_executesql z parametrami) OWASP 48
  • 49. Procedury składowane w Oracle  Oracle - użyj EXECUTE IMMEDIATE .. USING CREATE OR REPLACE PROCEDURE SP_ProductSearch(Prodname IN VARCHAR2) AS sqltext VARCHAR2(80); BEGIN sqltext := 'SELECT ProductID, ProductName, Category, Price WHERE ProductName=:p'; EXECUTE IMMEDIATE sqltext USING Prodname; ... END;  Escape'owanie - pakiet DBMS_ASSERT OWASP 49
  • 50. Procedury składowane w MySQL  Wsparcie dla Dynamic SQL tylko poprzez prepared statements  Napisanie podatnych procedur jest trudniejsze niż procedur zabezpieczonych!  Wystarczy używać placeholderów zamiast doklejać wartości zmiennych OWASP 50
  • 51. Procedury składowane w MySQL cd.  PREPARE / EXECUTE USING / DEALLOCATE PREPARE DELIMITER $$ CREATE PROCEDURE get_users_like ( IN contains VARCHAR(40)) BEGIN SET @like = CONCAT("%", contains, "%"); SET @sql = "SELECT * FROM users WHERE uname LIKE ?"; PREPARE get_users_stmt from @sql; EXECUTE get_users_stmt USING @like; DEALLOCATE PREPARE get_users_stmt; END$$ DELIMITER ; OWASP 51
  • 52. Procedury składowane w MySQL cd.  Lub jeszcze prościej (bezpośrednio) DELIMITER $$ CREATE PROCEDURE get_users_like ( IN contains VARCHAR(40)) BEGIN SET @like = CONCAT("%", contains, "%"); SELECT * FROM users WHERE uname LIKE @like; END$$ DELIMITER ;  Escape'owanie – funkcja QUOTE() OWASP 52
  • 53. Procedury składowane w PHP  Różne wsparcie w zależności od RDBMS  Wsparcie zależy od konkretnego sterownika  Wspólne API (np. PDO) obsługuje tylko najprostsze wywołania • Procedura nic nie zwraca • Procedura zwraca prosty rezultat w parametrze OUT  Różna obsługa (lub brak) bardziej zaawansowanych wywołań • np. pobieranie rekordów z procedur, kursory  Wsparcie we frameworkach śladowe  Wciąż występują błędy OWASP 53
  • 54. Procedury składowane w PDO  Wywołanie procedury // MySQL $sql = "CALL get_users_like(:contains)"; // MS SQL – EXEC get_users_like :contains $stmt = $pdo->prepare($sql); $ret = $stmt->execute(array('contains' => $input)); foreach($stmt->fetchAll() as $users) { var_dump($users); } unset($s); OWASP 54
  • 55. Procedury składowane w Doctrine/Propel/Zend Framework  Doctrine - Brak wsparcia (użyj PDO) $pdo = Doctrine_Manager::connection()->getDbh();  Propel – jw. $pdo = Propel::getConnection(UserPeer::DATABASE_NAME);  Zend Framework – jw. $pdo = $db::getConnection(); OWASP 55
  • 56. Procedury składowane w MDB2  Trzeba własnoręcznie escape'ować wszystkie parametry $mdb2->loadModule('Function'); $multi_query = $mdb2->setOption('multi_query', true); if (!PEAR::isError($multi_query)) { $result = $mdb2->executeStoredProc('get_users_like', array($mdb2->quote($contains, 'text'))); do { while ($row = $result->fetchRow()) { var_dump($row); } } while ($result->nextResult()); } OWASP 56
  • 57. Procedury składowane - pułapki  Długość zmiennych CREATE PROCEDURE change_password @loginname varchar(50), @old varchar(50), @new varchar(50) AS DECLARE @command varchar(120) SET @command= 'UPDATE users SET password=' + QUOTENAME(@new, '''') + ' WHERE loginname=' + QUOTENAME(@loginname, '''') + ' AND password=' + QUOTENAME(@old, '''') EXEC (@command) GO OWASP 57
  • 58. Procedury składowane - podsumowanie  Czasochłonne przenoszenie logiki SQL z aplikacji na serwer  Nie są łatwo przenośne pomiędzy RDBMS  Napisane bezpiecznych procedur i tak wymaga użycia prepared statements lub escape'owania danych  Źle zaimplementowane mogą zwiększyć podatność • Zarówno wywołanie procedury, jak i jej kod jest podatny • Procedura może mieć większe uprawnienia niż kod ją wywołujący  Złe wsparcie w PHP i we frameworkach OWASP 58
  • 59. Procedury składowane - podsumowanie Mają dużo zalet poza naszym obszarem zainteresowania  Można precyzyjnie zarządzać uprawnieniami do procedur  Przydatne w wypadku stosowania różnych klientów (Java/.NET + PHP)  Mogą zwiększyć wydajność  I wiele innych... Wnioski: Pozwalają osiągnąć dobre zabezpieczenie przed SQL injection, ale przy dużych kosztach. Niezbędne jest zabezpieczanie samego kodu procedur przed SQL injection. OWASP 59
  • 60. Jak się bronić? Metody uzupełniające OWASP 60
  • 61. Walidacja i filtrowanie danych  Kontrola poprawności danych zewnętrznych  Odbywa się przed przetwarzaniem tych danych  Nie myl z escape'owaniem! Filter INPUT - escape OUTPUT  Osobne reguły walidacji dla każdego parametru - sprawdzaj m.in. • Typ zmiennej • Skalar / tablica • Wartości min / max • Długość danych tekstowych! [1] OWASP 61
  • 62. Uzupełniające metody obrony Komplementarne do poprzednich!  Zasada najmniejszych uprawnień przy łączeniu się do bazy danych  Wyłączenie nieużywanych funkcji, kont, pakietów dostarczanych z bazą danych  Regularne aktualizowanie serwera bazy danych  Dobra konfiguracja PHP i bazy • magic_quotes_* = false • display_errors = false  Dobrze zaprojektowana baza danych OWASP 62
  • 63. Podsumowanie  Zwracaj uwagę na SQL injection - pojedynczy błąd może wiele kosztować!  Preferuj rozwiązania kompleksowe - np. frameworki  Filtruj wszystkie dane wejściowe  Pamiętaj o typach i długościach zmiennych  Stosuj whitelisting zamiast blacklistingu - to drugie kiedyś zawiedzie!  Stosuj prepared statements wszędzie, gdzie możesz  Unikaj escape'owania  W procedurach składowanych uważaj na Dynamic SQL OWASP 63
  • 64. Linki  Omawiane projekty • sqlmap.sourceforge.net • php.net/manual/en/book.pdo.php • www.doctrine-project.org • propel.phpdb.org/trac • framework.zend.com • pear.php.net/package/MDB2  O SQL injection • www.owasp.org/index.php/SQL_Injection • unixwiz.net/techtips/sql-injection.html • delicious.com/koto/sql+injection  Hack me • threats.pl/bezpieczenstwo-aplikacji-internetowych • tinyurl.com/webgoat • mavensecurity.com/dojo.php  krzysztof@kotowicz.net http://blog.kotowicz.net OWASP 64

Notas do Editor

  1. Sprawdzic ansi mode
  2. pO tym dodac slajd, jak wywolac procedure w SQL (call / exec)