[php] PHP_AUTH_USER veilig? *

Pagina: 1
Acties:
  • 503 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • vitrix
  • Registratie: Januari 2006
  • Laatst online: 23-08-2021
Ik heb een simpele vraag.
Ten eerste ik heb op google en hier rond gekeken en zie vrij veel voorbeelden.
Dit is niet mijn probleem om het zo te zeggen.

Ik heb het volgende script geschreven wat perfect werkt.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
if(!isset($_SERVER['PHP_AUTH_USER'])) {
    Header("WWW-Authenticate: Basic realm=\"Login\"");
    Header("HTTP/1.0 401 Unauthorized");
    echo "Je heb op annuleren geklikt<br />Hierdoor ben je niet bevoegd om deze site te bezoeken.\n";
    exit;
} else {
    //Funcie voor mysql injection tegen te gaan
    function quote_smart($value) {
       // Stripslashes
       if (get_magic_quotes_gpc()) {
           $value = stripslashes($value);
       }
       //Controleer of query een string is
       if (is_string($value)) {
           require('connect.php');
           $value = mysql_real_escape_string($value);
           mysql_close($verbinding);
       }
       return trim($value);
    } 
    $gebruiker = quote_smart($_SERVER['PHP_AUTH_USER']);
    $wachtwoord = md5($_SERVER['PHP_AUTH_PW']);
    require('connect.php');
    $query = "SELECT Id FROM dvdtrix_gebruikers WHERE Gebruikersnaam = '$gebruiker' AND Wachtwoord = '$wachtwoord'";
    $result = mysql_query($query) or die ('<p>Fout tijdens het inloggen:</p><p>' . mysql_error() . '</p>');
    if (mysql_num_rows($result) == '1') {
        while ($rij = mysql_fetch_assoc($result)) {
            $_SESSION['gebid'] = quote_smart($rij['Id']);
            $_SESSION['ipadres'] = $_SERVER['REMOTE_ADDR'];
            echo '<script>location.href="home.php"</script>';
        }
    } else {
        Header("WWW-Authenticate: Basic realm=\"Login\"");
        Header("HTTP/1.0 401 Unauthorized");
        echo "Je heb op annuleren geklikt<br />Hierdoor ben je niet bevoegd om deze site te bezoeken.\n";
        exit;
    }
    
    echo "Hallo ".$_SERVER['PHP_AUTH_USER']."<P>";
    echo "Je gebruikte ".$_SERVER['PHP_AUTH_PW']." als je password.<P>";
}


Maar mijn vraag is of dit eigenlijk wel veilig is?
Ik had het mapje eerst met een .htaccess en .htpasswd beveiliged maar er gaan verschillende account komen en dan zouden ze 2 keer moeten inloggen voor de map en dan voor hun account.
Dus ik dacht ik kijk even of ik die gegevens kan uitlezen van de eerste login.
Ik kwam om de bovenstaande script.

Volgens mij is dit bijna even veilig als .htaccess maar dat weet ik dus niet zeker.
Daarom mijn vraag is werken met header en zo uit php lezen veilig om een site te beveiligen ?

Acties:
  • 0 Henk 'm!

  • TheRookie
  • Registratie: December 2001
  • Niet online

TheRookie

Nu met R1200RT

PHP:
26
27
    if (mysql_num_rows($result) == '1') {
        while ($rij = mysql_fetch_assoc($result)) {

Als je al weet dat er 1 rij in het result zit, waarom dan toch een while ?

Acties:
  • 0 Henk 'm!

Verwijderd

En, als je weet dat mysql_num_rows() een getal teruggeeft, waarom vergelijk je 't dan met een string?

Acties:
  • 0 Henk 'm!

  • vitrix
  • Registratie: Januari 2006
  • Laatst online: 23-08-2021
Oki die if kan ik in iedergeval weg laten.
Maar is het voor de rest een veilige manier van inloggen?
En die while lus is om een id op te halen.

edit:

ik heb mijn script iets aan gepast.
Heb om alles heen een if statement gedaan die controleerd of de $_SESSION['id'] is ingevult
Als die is ingevult hoef die heel de WWW-Authenticate niet te doen.
Dit lijk mij al iets veiliger.
Maar kan iemand mij vertellen of dit wel veilig is?
Anders ga ik terug op een dubbele beveiling met .htacces / .htpasswd en een inlog script in php.

[ Voor 75% gewijzigd door vitrix op 03-05-2007 18:50 ]


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Dan wordt het dus zo :
PHP:
1
2
3
4
5
if (mysql_num_rows($result) == 1) 
{
        $rij = mysql_fetch_assoc($result);
        $id = $rij['id'];
}


while is een loop, dus als je meer dan 1 row op te halen hebt.
En '1' is een string, 1 is een integer.

Zijn wel basis dingen hoor, bekijk de mysql manual van php.net nog eens goed.

edit:
En dit: echo '<script>location.href="home.php"</script>';
Ga eens kijken naar de header() functie in PHP...

Ook is het, zeker voor een loginscript, niet aan te raden om mysql_error(); aan de user te laten zien. Mocht iemand er mee rotzooien krijgt ie nog mooi te zien wat voor query's jij gebruikt.

Om trouwens de echte vraag nog te beantwoorden:
Ik vind het niet veilig. Het wachtwoord gaat plain over de lijn. Als je het veilig wilt doen ga dan eens googlen naar 'challenge/response' inlogsystemen. Heb zelf laatst een versie gemaakt icm. SHA256 die ervoor zorgt dat het wachtwoord dat de hash die over de lijn gaat altijd anders is. Zo wordt het al een stuk moeilijker gemaakt allemaal.

[ Voor 54% gewijzigd door Cartman! op 03-05-2007 18:56 ]


Acties:
  • 0 Henk 'm!

  • vitrix
  • Registratie: Januari 2006
  • Laatst online: 23-08-2021
Tnx voor je replay.

Ja was ff met mijn hoofd niet bij met die while lus.
Zoals er gezegd is wordt toch maar 1 rij opgehaald dat kan je net zo goed zonder while doen.

Ik deed ook een md5 crypti, zal wel ff naar die SHA256 kijken hoe die werkt.
Had volgens mij er wel eens van gehoord en dat die ook telkens anders is.
Ik heb weer verder rond gekeken en na gedacht en op zich kan je net zo goed een html formulier maken en dat laten controleren. Heeft het zelfde effect en is misschien ook weer iets veiliger.
En ik las ook dat sommige mensen problemen hebben met IE7 en www-Auth login met basic.

Dus ik ga mijn script gewoon terug zetten hoe ik het eerst had en dan met sha beveiliging.

Die <script> redirect had ik ff van een andere pagina gehaald.
Daar werdt eerst wat output gedaan en kon dus niet met header en die had ik toch open staan ;)

[ Voor 10% gewijzigd door vitrix op 03-05-2007 19:10 ]


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Waarom doe je op 2 plekken require(connect.php); ?
PHP:
17
 mysql_close($verbinding);
Makes no sense.
PHP:
28
$_SESSION['gebid'] = quote_smart($rij['Id']);
Hier hoeft je die quote_smart niet te doen.

Verder kan je beter (imo: moet) als je op deze manier md5 digest als wachtwoorden opslaat werken met een salt (==zoekterm). En als je code naar productie gaat, moeten die mysql_error() en echo van het wachtwoord er echt uit.
vitrix schreef op donderdag 03 mei 2007 @ 19:09:Die <script> redirect had ik ff van een andere pagina gehaald.
Daar werdt eerst wat output gedaan en kon dus niet met header en die had ik toch open staan ;)
Niet zomaar iets copy pasten puur omdat je die pagina het eerste open hebt staan. :P Jij wil het beter aanpakken (anders was er geen topic), dus je zorgt dat er geen output is en doet het gewoon op de mooie manier. :Y)

[ Voor 93% gewijzigd door Voutloos op 04-05-2007 08:01 ]

{signature}


Acties:
  • 0 Henk 'm!

  • RRX
  • Registratie: Mei 2000
  • Laatst online: 29-05 15:34

RRX

@life-

Voutloos schreef op vrijdag 04 mei 2007 @ 07:53:
PHP:
17
 mysql_close($verbinding);
Makes no sense.
PHP:
28
$_SESSION['gebid'] = quote_smart($rij['Id']);
Hier hoeft je die quote_smart niet te doen.

Verder kan je beter (imo: moet) als je op deze manier md5 digest als wachtwoorden opslaat werken met een salt (==zoekterm). En als je code naar productie gaat, moeten die mysql_error() en echo van het wachtwoord er echt uit.
[...]
Niet zomaar iets copy pasten puur omdat je die pagina het eerste open hebt staan. :P Jij wil het beter aanpakken (anders was er geen topic), dus je zorgt dat er geen output is en doet het gewoon op de mooie manier. :Y)
http://nl3.php.net/manual/nl/function.mysql-close.php
Het gebruik van mysql_close() is normaal niet nodig, omdat niet-persisente open links automatisch gesloten worden aan het eind van het script. Zie ook het vrijmaken van resources.

mijn T.net systeemspecspagina


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Ja, leuk, maar dat is mijn punt niet. Die close staat op een absurde plek. 'Makes no sense' is misschien niet de meest uitgebreide uitleg, maar ik verwacht dat ts dan gewoon gaat nadenken over wat er mis is met dat statement op die genoemde plek.

Nog iets gevonden:
PHP:
35
        echo "Je heb op annuleren geklikt<br />Hierdoor ben je niet bevoegd om deze site te bezoeken.\n";
Dit is een copy paste van de error bovenaan. Maar hier is de fout dat het een ongeldige user/pass combinatie is.

[ Voor 84% gewijzigd door Voutloos op 04-05-2007 08:12 ]

{signature}


Acties:
  • 0 Henk 'm!

  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online
De vraag in dit topic is of de gebruikte methode (van Authenticatie headers sturen via de php ipv via en htaccess file)... daar is nog niemand op ingegaan.... ik vind dat eigenlijk ook wel een interessante vraag... dus gaat er nog iemand op antwoorden of gaat er 'doorgezeurd' worden over de al dan niet netheid van de rest van de code? ;)

Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Tja veilig is het vast wel aangezien de headers aangeroepen worden door de webserver dus die bepaald wie erin mag en niet, in PHP zelf kan dus weinig fout gaan. Ik werk er zelf nooit mee omdat het met meerdere users kut is met de administratie van .htpasswd en omdat je anders je wel je eigen mooie login formpje kan maken...

Als je nou eens een simpel formpje maakt die na het drukken op "Login" het wachtwoord met javascript md5 codeerd en die aan de server doorgeeft. Heb je geen plain text over je lijn gaan en als je de gegevens checkt met de functie die je hebt geschreven is de kans super klein dat iemand er tussen kan komen met injection.

Acties:
  • 0 Henk 'm!

  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online
Megamind schreef op vrijdag 04 mei 2007 @ 09:31:
Als je nou eens een simpel formpje maakt die na het drukken op "Login" het wachtwoord met javascript md5 codeerd en die aan de server doorgeeft.
offtopic:
Dat is toch net zo onveilig als het wachtwoord direct over de lijn sturen? of nou de md5 hash gekaapt wordt of het wachtwoord, dat boeit niet zoveel....

oeps, nu doe ik het zelf ook...

Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Edwardvb schreef op vrijdag 04 mei 2007 @ 10:14:
[...]


offtopic:
Dat is toch net zo onveilig als het wachtwoord direct over de lijn sturen? of nou de md5 hash gekaapt wordt of het wachtwoord, dat boeit niet zoveel....

oeps, nu doe ik het zelf ook...
Dan kan je net zogoed een SSL lijntje gaan kopen, die ook niet 100% veilig zijn. Als jij een sterk wachtwoord hebt en je stuurd die samen met een salt oid over de lijn, dan is het vrijwel onmogelijk het wachtwoord te achterhalen. Je kan natuurlijk wel de hash intercepten zodat je wel kan inloggen als die gebruiker... Hmm...

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
'password equivalent' is de term. Als je zelf met salt werkt (elke hashfunctie moet eigenlijk gewoon altijd met salt) is het alleen maar een password equivalent voor jouw site. Zonder salt is het ook een equivalent voor elke andere site met md5 zonder salt waar gebruiker hetzelfde wachtwoord heeft en is bovendien de input te achterhalen middels rainbow tabellen.

{signature}


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Ik genereer een random code die ik met javascript in de pagina zet en die sla ik op in de serversessie. Als iemand de verstuurde code onderschept heeft ie er dan niks aan omdat zn code niet meer overeenkomt met die op de server. Niks is 100% veilig maar t komt dicht in de buurt.
Eerst dus wachtwoord met salt hashen (zoals t ook in de db staat) en daarna hashen met de tijdelijke code. Die hash stuur je naar de server waarna je serverside dezelfde hash maakt. Komen ze overeen? Dan is de user ingelogd.

Acties:
  • 0 Henk 'm!

  • vitrix
  • Registratie: Januari 2006
  • Laatst online: 23-08-2021
Ik heb nu ook een normale php/html login formulier gemaakt.
Omdat het qua uitstraling beter uit ziet en makkelijk nieuwe users aan te maken is.

Heb mijn script ook aan gepast qua connection en die close connection verwijderd.
Aangezien ik die quote smart gebruikt voor database hoef ik geen connection in die function te zetten.
Ik maak nu 1 keer connection met de database aan begin van de index pagina gewoon 1 keer.
Hierdoor moet je altijd de index laden om connection te maken met de database en moet je dus ook inloggen.

Die error codes van mysql is alleen om te testen en als je het gaat uploaden moet je ze toch allemaal verwijderen?

Voutloos je heb gelijk alle 'critiek' die ik nu krijg onthoud ik ook zodat ik volgende keer daar aan denk.
Als niemand zeg dat ik het fout doe dan blijf ik eht tenslotte fout doen ;)

Over die code beveiling heb ik nog een vraagje.
Ik krijg een error dat die mijn hash niet herken.

Fatal error: Call to undefined function hash() in *****/login.php on line 4
Mijn regel 4 ziet er als volged uit:
$shawachtwoord = hash('SHA512', ($_POST['wachtwoord']));

Dat klopt volgens mij gewoon.
Mijn php is 5.1.6 daar lig het ook niet aan.
Moet je nog iets speciaals hebben om hash te gebruiken ?

[ Voor 39% gewijzigd door vitrix op 04-05-2007 12:38 ]


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Heb je de module wel geladen? Volgens php.net moet ie wel geladen zijn std bij jou versie maar controleer het eens met phpinfo();. Anders gewoon md5 gebruiken.

[ Voor 137% gewijzigd door Megamind op 04-05-2007 13:47 ]


Acties:
  • 0 Henk 'm!

  • vitrix
  • Registratie: Januari 2006
  • Laatst online: 23-08-2021
Dat was het :)
hij staat er helemaal niet tussen dus is waarschijnlijk disabled.
Dan maar sha1 gebruiken.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
SHA1 is opzich ook prima, het ligt meer aan de methode namelijk. Overigens stuur je nu alsnog je password plain over de lijn zo te zien, wat niet veilig is. Dan heeft je SHA256/1 ook weinig nut imo.
Wat je wilt is client side met javascript onsubmit de hash maken en die versturen. Die kun je dan vergelijken met hetgeen in je database.

edit:
misschien heb je wel mhash lib erin zitten?
check dan ff : http://nl2.php.net/mhash
1e comment daar is van mij en die gebruik ik ook nu, werkt fantastisch :)

[ Voor 39% gewijzigd door Cartman! op 06-05-2007 13:28 ]


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Cartman! schreef op zondag 06 mei 2007 @ 13:27:
SHA1 is opzich ook prima, het ligt meer aan de methode namelijk. Overigens stuur je nu alsnog je password plain over de lijn zo te zien, wat niet veilig is. Dan heeft je SHA256/1 ook weinig nut imo.
Wat je wilt is client side met javascript onsubmit de hash maken en die versturen. Die kun je dan vergelijken met hetgeen in je database.
nobel streven, maar hoe wil je dat bij registratie doen? dan kan je niet clientside hashen.. tenzij je dan direct het gehashde ding in de DB gooit, waarbij het hele nut van de hashing verdwijnt.

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

Verwijderd

BasieP schreef op zondag 06 mei 2007 @ 13:29:

nobel streven, maar hoe wil je dat bij registratie doen? dan kan je niet clientside hashen.. tenzij je dan direct het gehashde ding in de DB gooit, waarbij het hele nut van de hashing verdwijnt.
Waarom? Je kunt toch gewoon bij de registratie de hash in de database stoppen, en bij elke volgende authenticatie de hash daarmee vergelijken? Dat hashen heeft maar 1 doel, en dat is zorgen dat niemand zomaar het originele wachtwoord kan achterhalen. Een hash maakt je authenticatie in theorie minder veilig (mogelijke collisions) maar zorgt er wel voor dat bij een beveiligingsfout niet in 1 keer de originele wachtwoorden te achterhalen zijn. Het is meer een "dienst" om de bezoeker enige bescherming te bieden mochten ze dezelfde wachtwoorden ook voor andere doelen gebruiken. Ik snap je punt dus niet.

Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Verwijderd schreef op zondag 06 mei 2007 @ 13:35:
[...]

Waarom? Je kunt toch gewoon bij de registratie de hash in de database stoppen, en bij elke volgende authenticatie de hash daarmee vergelijken? Dat hashen heeft maar 1 doel, en dat is zorgen dat niemand zomaar het originele wachtwoord kan achterhalen. Een hash maakt je authenticatie in theorie minder veilig (mogelijke collisions) maar zorgt er wel voor dat bij een beveiligingsfout niet in 1 keer de originele wachtwoorden te achterhalen zijn. Het is meer een "dienst" om de bezoeker enige bescherming te bieden mochten ze dezelfde wachtwoorden ook voor andere doelen gebruiken. Ik snap je punt dus niet.
Je kan alleen niet zomaar password checks erop bouwen, zonder Javascript, wat erg simpel te beïnvloeden is natuurlijk...

Acties:
  • 0 Henk 'm!

Verwijderd

Waarom kun je geen "password checks erop bouwen"? Wat bedoel je daar eigenlijk mee? Waarom zou het uit moeten maken dat iets met JavaScript simpel te beïnvloeden is? Wat wilde je gaan beïnvloeden dan? Je wilt alleen maar iets hebben dat alleen de client en de server kunnen weten, zoals een wachtwoord, een hash van een wachtwoord, of wat dan ook. Zolang het maar niet zomaar te raden is.

En het is natuurlijk geen punt om het zonder javascript ook te laten werken, dan heb je alleen het nadeel dat wachtwoorden plain text over het internet zeilen. Maar als je "onsubmit" het wachtwoord hasht en een verborgen waarde in het formulier zet dat het gehasht is, is het hooguit een paar extra regels code om het server-side te verwerken.

Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Als je een javascriptje inbouwd dat simpelweg alles versleuteld en controleerd of het wachtwoord niet leeg, of controleerd of het wachtwoord wel sterk is, dan kan je die supersimpel natuurlijk bypassen als het in javascript wordt verwerkt. Als je deze dingen ook in PHP checkt dan kan je er niet omheen. Als je met een vaste salt werkt en iemand registreerd met een leeg pw, die snifft de hash die over de lijn gaat, dan weet diegene je salt. Of je er iets aan hebt is een 2e, maar theoretich gezien is het een lek

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Cheatah gaf t al aan, je hasht em ook tijdens t registreren client side al. Een van de grootste problemen bij ww/pass systemen is ook de uitwisseling van de wachtwoorden, dat is algemeen bekend.

Het systeem wat ik heb 'bedacht' maakt bij registratie een hash van ww+salt en slaat deze op in de dbase. Tijdens inloggen stuur ik salt+random code mee in t formulier en onsubmit wordt er gehashed volgens hash(random code+hash(ww+salt)). Zo is je ingestuurde wachtwoord altijd anders en niet meer geldig als ie door n ander gesniffed is.
Het werkt volgens het challende/response systeem maar dan met 1 salt ipv per user salt. Dit is met een websysteem gewoon heel onhandig omdat je dan eerst de gebruikersnaam moet weten en met 2 forms moet werken : 1. naam, 2. wachtwoord en dat is gewoon niet praktisch.
Het voordeel aan de methode die ik gebruik is, vind ik, dat t verhoogde veiligheid heeft terwijl de gebruiker er niks van merkt. Serverside wordt gecheckt of er een form variabele bestaat die meld of er een beveiligde login is of niet. Als dit niet zo is (bijv. omdat javascript uistaat) kan de gebruiker toch inloggen.

Megamind : je check doe je dus niet met javascript, alleen het hashen doe je daarmee en hoe die hash gemaakt wordt is geen geheim verder. De check zelf wordt natuurlijk alleen serverside gedaan.

[ Voor 8% gewijzigd door Cartman! op 06-05-2007 21:03 ]


Acties:
  • 0 Henk 'm!

  • pietje63
  • Registratie: Juli 2001
  • Laatst online: 22:05

pietje63

RTFM

Misschien interessant om hier te melden, maar op een vorige site had ik de vorige structuur.

code:
1
2
3
4
5
public/login.php          --> login volgens het systeem uit je startpost, gekoppeld aan een mysql DB
public/leden/.htaccess     --> vanaf nu is deze dir beveiligd op leden niveau (staat in de htaccess)
public/leden/admin/.htaccess --> vanaf nu is deze dir beveiligd op adminniveau (staat in de htaccess)
private/.htpasswdleden     --> kan geen kwaad om dit buiten de public te zetten; verschillende niveaus door meerdere htpasswd bestanden
private/.htpasswdadmin


Ik weet niet of je site design dit toestaat, maar ik vond het wel fijn werken. Je gebruikt php alleen maar voor de primaire check, waarna je eventueel wat sesse variabelen door kan sturen naar de user. Vervolgens controleer je alles op apache niveau (en zo loop je ook niet het risico om ergens je controle te vergeten). Verder heb je ook geen download.php en dergelijke grappen nodig.

De grootste Nederlandstalige database met informatie over computers met zoekfunctie!!

Pagina: 1