Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Zabezpieczenie skryptu PHP
Baku12345
post
Post #1





Grupa: Zarejestrowani
Postów: 46
Pomógł: 1
Dołączył: 23.04.2011

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


Witam
Mam skrypt co do którego mam zastrzeżenia jeśli chodzi o bezpieczeństwo. Nie wrzucę go ze względu na to, że jest zbyt długi. Wrzucę natomiast jego uproszczoną wersję by odnieść się do problemu. A wygląda on tak
  1. <?php
  2.  
  3. $now = time();
  4. $session_data = "";
  5.  
  6. $pdo = new PDO('mysql:host=localhost; port=3306; dbname=test', 'root', '');
  7.  
  8. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  9. $pdo->exec("SET NAMES 'utf8'");
  10.  
  11. if (isset($_POST['login']) && isset($_POST['password']))
  12. {
  13. if (!empty($_POST['login']) && !empty($_POST['password']))
  14. {
  15. $login = addslashes(strip_tags($_POST['login']));
  16. $password = hash_hmac('sha256', $_POST['password'], '2NYbH5qS8J');
  17.  
  18. $stmt = $pdo->prepare("SELECT * FROM users WHERE login = :login && password = :password");
  19. $stmt -> execute(array(':login' => $login, ':password' => $password));
  20.  
  21. if ($row = $stmt->fetch(PDO::FETCH_ASSOC))
  22. {
  23. $_SESSION[$session_data] = array('id' => $row['id'], 'time' => $now, 'user' => $row['name']);
  24. }
  25. else
  26. {
  27. echo "Podałeś błędny login lub hasło";
  28. }
  29. }
  30. else
  31. {
  32. echo "Nie wprowadziłeś wszystkich danych";
  33. }
  34. }
  35.  
  36. $max_idle_time = 900;
  37. if (isset($_SESSION[$session_data]) && !empty($_SESSION[$session_data]))
  38. {
  39. if ($now - $_SESSION[$session_data]['time'] < $max_idle_time)
  40. {
  41. $_SESSION[$session_data]['time'] = $now;
  42. echo "Jesteś zalogowany";
  43. // tu następuje pobranie z bazy danych danych przeznaczonych dla użytkownika o danym id a następnie ich wyświetlenie
  44. }
  45. else
  46. {
  47. echo "Przekroczono czas bezczynności";
  48. }
  49. }
  50. else
  51. {
  52. echo '<h1>Panel Użytkownika</h1>
  53. <form method="post" action="">
  54. <div>
  55. <input type="text" name="login" placeholder="Twój login" value="">
  56. </div>
  57. <div>
  58. <input type="password" name="password" placeholder="Twoje hasło" value="">
  59. </div>
  60. <button type="submit">Zaloguj się</button>
  61. </form>';
  62. }
  63. ?>


Skrypt działa dobrze. Przy pierwszym wejściu na stronę przechodzimy na koniec kodu do formularza, ponieważ zmienna login, password i session nie istnieją.
Jeżeli wyślemy login, hasło i skrypt sprawdzi, że nie są puste to jest porównywany hash z tym znajdującym się w bazie. Dalej jeśli się zgadzają jest tworzona zmienna sesyjna, w której jest id, czas i nazwa użytkownika. W drugiej części skrypt sprawdza, że istnieje sesja między innymi z id użytkownika i wyświetla dane przeznaczone tylko dla niego.

Problem w tym, że jeżeli nie znam loginu ani hasła użytkownika to też mogę się dostać do danych przeznaczonych tylko dla danego użytkownika. Wystarczy, że w sposób "sztuczny" utworzę zmienną sesyjną z id i zmieniając tylko id mogę sobie skakać z konta na konto.

Pytanie jak zabezpieczyć taki skrypt?

PS: Trafiłem przypadkiem na ten błąd robiąc kopię tego skryptu, ale z podpiętą inną bazą innym loginem i hasłem. Odpaliłem jeden skrypt podałem login i hasło, a potem nie zamykając przeglądarki odpaliłem drugi skrypt z całkiem inną bazą loginem i hasłem w niej (tylko id użytkownika się zgadzało) i byłem zalogowany na obu skryptach. Mogłem sobie zmieniać id użytkownika w jednym skrypcie, a w drugim byłem zalogowany na tym użytkowniku o danym id. Wnioskuję więc, że każdy mógłby wysłać zmienną sesyjną z id i by został wpuszczony i by mu się wyświetliły dane tego użytkownika.

PS2: Po linii 39 następuje sprawdzenie czy została utworzona zmienna sesyjna między innymi z id użytkownika, a w linii 46 jest select który pobiera dane przeznaczone dla użytkownika o tym id. I właśnie tu jest luka, którą nie wiem jak załatać, jedyne co mi przychodzi do głowy to ponowne sprawdzenie czy nazwa użytkownika i hasło się zgadzają, ale wtedy jaki sens ma kod przed linią 39? Mam nadzieję, że jasno to opisałem smile.gif W skrócie macie 2 kopie tego skryptu logujecie się na jednej to w drugiej jesteście zalogowani mimo, że hasła użytkownika w bazie podpiętej do drugiego skrypcie nie znacie. Prościej nie umiem smile.gif

Ten post edytował Baku12345 4.03.2017, 21:40:30
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 19.08.2025 - 10:54