Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Bezpieczny system logowania
Forum PHP.pl > Forum > PHP
akurczyk
Napisałem prosty system logowania.
Formularz logowania przesyła dane do tego pliku:
  1. <?php
  2. mysql_connect("localhost", "root", "vertrigo");
  3. mysql_select_db("porady");
  4. mysql_query("SET NAMES 'utf8'");
  5. if(isset($_POST['zaloguj_sie']) && isset($_POST['login']) && !empty($_POST['login']) && isset($_POST['haslo']) && !empty($_POST['haslo'])) {
  6.    $wykonaj_zapytanie = mysql_query("SELECT * FROM uzytkownicy WHERE login='".addslashes($_POST['login'])."' AND haslo='".addslashes($_POST['haslo'])."'");
  7.    if(mysql_num_rows($wykonaj_zapytanie) == 1) {
  8.        $wiersz = mysql_fetch_array($wykonaj_zapytanie);
  9.        $_SESSION['zalogowany'] = "tak";
  10.        $_SESSION['administrator'] = $wynik['administrator'];
  11.        $_SESSION['id'] = $wiersz['id'];
  12.    }
  13. }
  14. if(isset($_GET['przekierowanie']) && !empty($_GET['przekierowanie'])) {
  15.    header("Locatio: ".$_GET['przekierowanie']);
  16. } else {
  17.    header("Locatio: index.php");
  18. }
  19. ?>

Następnie następuje przekierowaniu (do pliku index.php):
  1. <?php
  2. if(isset($_SESSION['zalogowany']) && $_SESSION['zalogowany'] == "tak") {
  3.    echo "zalogowany";
  4. } else {
  5.    echo "niezalogowany";
  6. }
  7. ?>

Proszę o pomoc w zabezpieczeniu tego skryptu!!!
Exek
zamiast addslashes używaj mysql_escape_string

header("Locatio: index.php");

powinno być:

header("Location: index.php");
pyro
$_SESSION['administrator'] = $wynik['administrator'];

skad sie wziela tablica $wynik?

po header(); dawaj exit;
kazag
Pewnie zamiast $wynik, miało być $wiersz.
vokiel
Hasło w bazie przechowuj zhashowane (SHA1 albo MD5).
  1. <?php
  2. $wiersz = mysql_fetch_array($wykonaj_zapytanie);
  3. // wyzej masz $wiersz a na dole $wynik -> tak to nie zadziala&nbsp:)
  4. $_SESSION['zalogowany'] = "tak";
  5. $_SESSION['administrator'] = $wynik['administrator'];
  6. $_SESSION['id'] = $wiersz['id'];
  7. ?>

Zrób funkcję czyszczącą i przez nią filtruj wprowadzone przez usr dane
  1. <?php
  2. function cleanOneData($input){    
  3.         $input = trim($input);     // funkcja ta usuwa z napisu wiodące i końcowe białe znak:
  4.        $input = str_replace("[ ]+", " ", $input);            // zmiana wielokrotnych spacji na pojedyncze
  5.        $input = ereg_replace("[\nr\t ]+", " ", $input);     // zmiana bialych znaków na pojedyncze spacje
  6.       if (!get_magic_quotes_gpc()) {
  7.           $input = mysql_real_escape_string($input);    // dodawanie znacznikow przed tymi niebezpiecznymy (magic_quotes gpc off)
  8.    }
  9.    $input = htmlspecialchars($input);                     // zamiana znaków '<' na '<'
  10.    return $input;
  11. }// end of cleanOneData
  12. ?>


Poza tym jeśli w bazie będziesz trzymał hasło zhashowane nie musisz go filtrować bo i tak będziesz robił coś w stylu:
  1. <?php
  2. $wykonaj_zapytanie = mysql_query("SELECT * FROM uzytkownicy WHERE login='".cleanOneData($_POST['login'])."' AND haslo='".sha1($_POST['haslo'])."'");
  3. ?>
akurczyk
a coś na wypadek edycji cookie?questionmark.gif
pyro
jakiej edycji?
akurczyk
gdyby ktoś zmienił sobię $_SESSION['administrator'] z "" na "tak".
PS: COOKIE EDITOREM
Exek
sesja jest trzymana po stronie serwera, w cookie to masz tylko session id
pyro
Cytat(akurczyk @ 10.09.2008, 14:44:40 ) *
gdyby ktoś zmienił sobię $_SESSION['administrator'] z "" na "tak".
PS: COOKIE EDITOREM


zacznij odrozniac sesje od ciasteczek smile.gif
akurczyk
myślałem że sesja to takie ciasteczko
pyro
sesja i ciasteczko to zupelnie odrebne rzeczy, jest jedynie wysylane jedno ciasteczko ktore jest identyfikatorem sesji
akurczyk
skoro hasła będą kodowane w md5 lub sha1 to jak je pużniej odkodować (Przypomnienie hasła)
MWL
a ja dam ci małą radę. Daj jedną zmienną sesji z ip używanym przy zalogowaniu. Pozwoli ci to na trochę bezpieczniejsze logowanie i brak możliwości przejęcia sesji jeśli 'żezimieszek' ma inne ip niż osoby zalogowanej
Exek
@MWL
Zły pomysł. Miałem kiedyś neta z kablówki i miałem zmieniane ip co parę minut.

@akurczyk

przypominanie hasła działa wtedy na zasadzie generowania nowego hasła. User podaje w formularzu swojego maila. Dla tego maila tworzysz authkey (klucz weryfikacyjny) który wysyłasz na podany mail ( i zapisujesz w bazie danych). Potem user wchodzi na linka z maila i ustala nowe hasło i kodujesz je od nowa.
akurczyk
a jak wygenerować ten authkey (i jak zrobić żeby był on usuwany po 24 godzinach)questionmark.gif?
Exek
zrób np md5(time().rand().'mail@uzytkownika.pl') i zapisuj do bazy danych.

Szczerze mówiąc, osobiście nie usuwam tych authkeyów z bazy danych, ale jak chcesz to dorób kolumnę w bazie danych z wpisem kiedy wygenerowano klucz, a potem np. za pomocą cron'a odpalaj skrypt.php ktory czysci baze danych ze starych authkeyow.
bllitz
Cytat(akurczyk @ 10.09.2008, 11:37:39 ) *
  1. <?php
  2. if(isset($_POST['zaloguj_sie']) && isset($_POST['login']) && !empty($_POST['login']) && isset($_POST['haslo']) && !empty($_POST['haslo'])) {
  3.  
  4. if(isset($_GET['przekierowanie']) && !empty($_GET['przekierowanie'])) {
  5.  
  6. ?>


taki zapis jest zbędny jeśli stosujesz isset to nie ma potrzeby żeby używać też !empty, isset w zupełności wystarczy.
Exek
@blitz

isset sprawdza czy coś takiego zostało wysłane z formularza, nie oznacza to wcale że ma jakąś zawartość.
Sprawdzenie isset a potem !empty jest IMHO bardzo dobre.
SHiP
Cytat(Exek @ 10.09.2008, 14:19:48 ) *
@blitz

isset sprawdza czy coś takiego zostało wysłane z formularza, nie oznacza to wcale że ma jakąś zawartość.
Sprawdzenie isset a potem !empty jest IMHO bardzo dobre.


bllitz ma rację tyko chyba mu się kolejność pomieszała. !empty() zawiera w sobie isset() ;] wiec sprawdzanie najpierw isset() a potem !empty() jest zbędne. Po prostu od razu dajemy !empty()

  1. <?php
  2. if(isset($_POST['zaloguj_sie']) && !empty($_POST['login']) && !empty($_POST['haslo'])) {
  3.  
  4. if(!empty($_GET['przekierowanie'])) {
  5.  
  6. ?>
akurczyk
i jeszcze jedno dawać addslashes czy to mysql_escape_string czy jakoś tak?questionmark.gif
Exek
@SHiP
Ooo, masz rację, nie wiedziałem o tym, dzięki smile.gif

@akurczyk
mysql_escape_string jest bezpieczniejsze bo czyści ze wszystkich 'złych' znaków. Tylko używaj tego jeśli masz wyłączone magic_quotes. Domyślnie w php5 jest wyłączone, ale administratorzy wszędzie to włączają, zresztą nie dziwię się im tongue.gif.
MWL
Cytat(Exek @ 10.09.2008, 15:24:07 ) *
@MWL
Zły pomysł. Miałem kiedyś neta z kablówki i miałem zmieniane ip co parę minut.


Nie może zmieniać ci się ip podczas zmieniania strony tylko podczas kolejnego połączenia!!
Nie inaczej!
pyro
Cytat(MWL @ 10.09.2008, 19:08:18 ) *
Nie może zmieniać ci się ip podczas zmieniania strony tylko podczas kolejnego połączenia!!
Nie inaczej!


teoretycznie moze, ale jednoczescnie polaczenia (np. sciaganie) by sie przerwalo
Exek
@MWL

heh nie może? Dobrze wiedzieć, szkoda tylko że trafiłem na jedną stronę z zabezpieczeniem o którym mówisz i wywalało mnie. Potem sprawdziłem i czasami mi się nawet wydawało że co request miałem jedno ip z puli, tak na oko, 1 z 8 ip.

@pyro

nie rozumiem? ściąganie pliku to 1 request i 1 response? Tak mi się przynajmniej wydaje, więc głowy nie dam. W jaki sposób miałoby to przerwać proces ściągania? Mógłbyś napisać?
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.