Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]PDO czy w 100% bezpieczne
Forum PHP.pl > Forum > Przedszkole
vento
Witam. Mam pytanie odnośnie PDO.
Czy w obecnej chwili jest możliwe jakieś wstrzyknięcie SQL przy np. takim kodzie:
  1. <?php
  2. include('connect.php');
  3. $nick = $_POST['nick'];
  4. $komentarz = $_POST['komentarz'];
  5. $db = new PDO('mysql:host='.$server.';dbname='.$db_name.';charset=utf8mb4', ''.$login.'', ''.$password.'');
  6. try
  7. {
  8. $zapytanie = "INSERT INTO `pdo`.`main` (`nick`, `data`, `komentarz`) VALUES ('$nick', NOW(), '$komentarz');";
  9. $db->query($zapytanie);
  10. }
  11. catch(PDOException $ex)
  12. {
  13. echo "error";
  14. }
  15. ?>


Wcześniej korzystałem z mysqli, ale przeczytałem, że PDO jest nowszą technologią, która posiada dodatkowe zabezpieczenia np. przed wstrzykiwaniem SQL.
Tak jak pisałem na początku moje pytanie brzmi czy jest to w 100% bezpieczne?
kapslokk
tak, jest możliwe wstrzyknięcie sql. Używaj bindowania. http://php.net/manual/en/pdostatement.bindparam.php
vento
Cytat(kapslokk @ 20.05.2016, 21:39:49 ) *
tak, jest możliwe wstrzyknięcie sql. Używaj bindowania. http://php.net/manual/en/pdostatement.bindparam.php


Rozumiem. Czy jest wtedy sens przeskakiwania na PDO czy można zostać przy mysqli?
kapslokk
Jeśli dopiero zaczynasz pisanie aplikacji, to chyba lepiej użyć PDO, w razie potrzeby łatwiej będzie Ci zmienić bazę danych, mysqli jest tylko do mysql'a. Jeżeli musisz przepisywać dużą część aplikacji to już Twoja decyzja tongue.gif
vento
Chodzi mi raczej tylko o bezpieczeństwo.
W mysqli zamieniałem ciąg znaków na base64 a przy wyświetlaniu rekordów na stronie po prostu je odkodowywałem i to było moje zabezpieczenie przed wstrzykiwaniem sql.
Myślałem, że PDO chroni przed jakimkolwiek wstrzyknięciem, ale jeżeli nie to chyba nie ma sensu przechodzić na PDO.
Jeszcze jedno pytanie przeczytałem na jakimś forum, że w PHP 7.0 mysqli oraz mysql mają być usunięte i ma zostać samo PDO czy to prawda?
kapslokk
Cytat
Myślałem, że PDO chroni przed jakimkolwiek wstrzyknięciem, ale jeżeli nie to chyba nie ma sensu przechodzić na PDO.

Chroni, pod warunkiem, że używasz bindowania. Mysqli też ma bindowanie: http://php.net/manual/en/mysqli-stmt.bind-param.php

Co do tego base64 to nie wiem jakby to miało w czymkolwiek pomóc.

A co do PHP7 to mysql_ zostało usunięte, ale mysqli nadal jest.
vento
  1. <?php
  2. include('connect.php');
  3. $nick = $_POST['nick'];
  4. $komentarz = $_POST['komentarz'];
  5. $polaczenie = @new mysqli($servername, $username, $password, $dbname);
  6. if ($polaczenie->connect_errno!=0)
  7. {
  8. echo "ERROR TO CONNECT MYSQL";
  9. }
  10. else
  11. {
  12. $nick = base64_encode($nick);
  13. $komentarz = base64_encode($komentarz);
  14. $zapytanie = "INSERT INTO `pdo`.`main` (`nick`, `data`, `komentarz`) VALUES ('$nick', NOW(), '$komentarz');";
  15. $polaczenie->query($zapytanie);
  16. }
  17.  
  18. ?>


Chodzi mi mniej więcej o coś takiego, że wszystkie dane ktore wpisuje user zostają zamienione na base64 (przykład wyżej).
Czy nadal jest możliwe wstrzyknięcie SQL?
kapslokk
Hahaha, no nie jest możliwe, ale to nie jest optymalne rozwiązanie biggrin.gif Wszystkie pola w bazie musiał byś mieć tekstowe, a to nie o to w tym wszystkim chodzi. Masz filtrować dane, a nie wrzucać co popadnie, tylko zakodowane w base64 biggrin.gif

Poza tym, już lepiej robić wszedzie: http://php.net/manual/en/mysqli.real-escape-string.php niż base64_encode biggrin.gif pisania mniej-więcej tyle samo, a przynajmniej baze przeglądać możesz normalnie biggrin.gif
vento
Rozumiem. Dziękuje za pomoc.

  1. <?php
  2. include('connect.php');
  3. $nick = $_POST['nick'];
  4. $komentarz = $_POST['komentarz'];
  5. $polaczenie = @new mysqli($servername, $username, $password, $dbname);
  6. if ($polaczenie->connect_errno!=0)
  7. {
  8. echo "ERROR TO CONNECT MYSQL";
  9. }
  10. else
  11. {
  12. $nick = mysqli_real_escape_string($polaczenie, $nick);
  13. $komentarz = mysqli_real_escape_string($polaczenie, $komentarz);
  14. $zapytanie = "INSERT INTO `pdo`.`main` (`nick`, `data`, `komentarz`) VALUES ('$nick', NOW(), '$komentarz');";
  15. $polaczenie->query($zapytanie);
  16. }
  17.  
  18. ?>

Rozumiem, że teraz wszystko jest bezpieczne?
kapslokk
Tak.
Comandeer
Nie, nie jest! A czemu, to najlepiej wyjaśnia ta odpowiedź na SO: http://stackoverflow.com/a/8255054/5778385
Jedyny dobry sposób to PS: http://stackoverflow.com/a/60496/5778385
com
kapslokk ale nie pisz bazdur jakiekolwiek *_real_escape_string, nie chroni przed niczym, to się używało w mysql_* bo tylko to tam było, ale dlatego ten sposób już umarł wink.gif To nie daje nic, bo 95% współczesnych ataków przepuści wink.gif
kapslokk
No dobra, moja wina, szczerze mówiąc nawet nie wiedziałem sad.gif przyznaję się.
vento
Może mi ktoś napisać przykład jak dodać bezpiecznie komentarz, aby nie było możliwe wstrzyknięcie sql dla mysqli
Póki co mam coś takiego:
  1. <?php
  2. include('connect.php');
  3. $nick = $_POST['nick'];
  4. $komentarz = $_POST['komentarz'];
  5. $polaczenie = @new mysqli($servername, $username, $password, $dbname);
  6. if ($polaczenie->connect_errno!=0)
  7. {
  8. echo "ERROR TO CONNECT MYSQL";
  9. }
  10. else
  11. {
  12. $nick = mysqli_real_escape_string($polaczenie, $nick);
  13. $komentarz = mysqli_real_escape_string($polaczenie, $komentarz);
  14. $zapytanie = "INSERT INTO `pdo`.`main` (`nick`, `data`, `komentarz`) VALUES ('$nick', NOW(), '$komentarz');";
  15. $polaczenie->query($zapytanie);
  16. }
  17.  
  18. ?>


Z góry dziękuję za pomoc..
Tomplus
Jak użyjesz PDO to zapytanie będzie proste:

  1. $zapytanie = $polaczenie->prepare("INSERT INTO `pdo`.`main` (`nick`, `data`, `komentarz`) VALUES ( :nick , NOW(), :komentarz);");
  2. $zapytanie->bindValue(':nick', $nick);
  3. $zapytanie->bindValue(':komentarz', $komentarz);
  4. $zapytanie->execute();


mysqli_real_escape_string jest wtedy zbędne i usuwasz z kodu.


Jeżeli nie planujesz mieć skomplikowanych zapytań lub tabele będziesz miał referencyjne, to możesz użyć już klas ułatwiające otrzymywanie wyników, aktualizację i dodawanie treści do bazy danych np. klasę:
http://www.phpclasses.org/package/9209-PHP...tml#information

Dla przykładu:
  1. $db->table('main') /* nazwa tabeli */
  2. ->insert([
  3. 'nick' => $nick, /* nazwa kolumny jako klucz */
  4. 'komentarz' => $komentarz
  5. ]);
vento
Rozumiem, dziękuję za pomoc będę korzystał z PDO

  1. <?php
  2. include('connect.php');
  3. $nick = $_POST['nick'];
  4. $komentarz = $_POST['komentarz'];
  5. $polaczenie = @new mysqli($servername, $username, $password, $dbname);
  6. if ($polaczenie->connect_errno!=0)
  7. {
  8. echo "ERROR TO CONNECT MYSQL";
  9. }
  10. else
  11. {
  12. $zapytanie = $polaczenie->prepare("INSERT INTO `pdo`.`main` (`nick`, `data`, `komentarz`) VALUES (?, NOW(), ?);");
  13. $zapytanie->bind_param("ss", $nick, $komentarz);
  14. $zapytanie->execute();
  15. $zapytanie->close();
  16. }
  17.  
  18. ?>



Tak też może być?
com
wywalisz małpę dodasz if z isset i będzie ok wink.gif
vento
  1. <?php
  2. include('connect.php');
  3.  
  4. if( (isset($_POST['nick'])) && (isset($_POST['komentarz'])) )
  5. {
  6. $nick = $_POST['nick'];
  7. $komentarz = $_POST['komentarz'];
  8. $polaczenie = new mysqli($servername, $username, $password, $dbname);
  9. if ($polaczenie->connect_errno!=0)
  10. {
  11. echo "ERROR TO CONNECT MYSQL";
  12. }
  13. else
  14. {
  15. $zapytanie = $polaczenie->prepare("INSERT INTO `pdo`.`main` (`nick`, `data`, `komentarz`) VALUES (?, NOW(), ?);");
  16. $zapytanie->bind_param("ss", $nick, $komentarz);
  17. $zapytanie->execute();
  18. $zapytanie->close();
  19. }
  20. }
  21. else
  22. {
  23. exit();
  24. }
  25.  
  26. ?>


Teraz ok?
viking
Cytat(vento @ 24.05.2016, 17:04:54 ) *
Rozumiem, dziękuję za pomoc będę korzystał z PDO


Po czym korzystasz z mysqli wink.gif
Zamiast tych ifów poczytaj o wyjątkach.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.