PHP login

Diskuter dine og andres prosjekter. Alt fra Widgets til programmer.

PHP login

Innleggav KiNexus » ons 24.10.2007 0:17

Hei, jeg har et par spørsmål til PHP-MySQL-guruene der ute.


Jeg lager en side som trenger bruk av brukernavn/passord. For øyeblikket har jeg laget et enkelt system som går noenlunde slik:
1) Skriv inn brukernavn og passord -- sendes med POST til neste side
2) Side 2 tar $_POST['username'], henter en record fra en MySQL-database med det brukernavnet, og tar med passordet. Deretter sjekkes passordene mot hverandre, og hvis de er like registreres brukernavnet i $_SESSION['username'].
3) alle senere sider tar ut records fra databasen ved hjelp av variablen $_SESSION['username'].

Spørsmålene mine er som følger
1) en av mine venner som kan PHP litt bedre enn meg mener at jeg burde lagre både username og passord i $_SESSION[''], og deretter kjøre en MySQL-request for hver side for å kontrollere at alt stemmer. (eventualt kjøre "die" hvis passordet ikke stemmer når man kommer til en side som krever riktig brukernavn og passord)

+ Er det nødvendig?
+ Er det verdt den ekstra loaden på serveren?
+ Er det forsvarlig å lagre passord i $_SESSION
+ Kan brukeren lese/skrive til $_SESSION på noen måte
+ Hvor åpen er $_SESSION ovenfor XSS-angrep i forhold til f.eks. å lagre annet sted.

2) Hvor mange SQL-requests må til for at en nettside skal bli tynget ned (dvs: hvor mange sql-requests per sekund bør en normal shared webhost godta)


Beklager hvis noen av spørsmålene mine er retarderte, men jeg tenkte at jeg likegodt kunne spørre om alle jeg hadde når jeg først ber om hjelp.


-Ki
medlem i 230 måneder
 

Innleggav tjodolv » ons 24.10.2007 0:51

Jeg er ikke noen guru, men det kan absolutt lønne seg å sette i alle fall et navn i $_SESSION som kontrolleres ved hver page request. En gjennomsnittlig webhost bør tåle i alle fall 10 queries per page load. Jeg har kjørt med 20-30 (++) uten å få noe pepper for det.

Når det gjelder det du sier om at brukernavn/passord fra $_POST brukes for å sjekke mot MySQL databasen, håper jeg for guds skyld du hindrer sql-injection på en eller annen måte. Det enkleste er slik jeg har lært det er på denne måten:

Kode: Merk alt
$username = mysql_escape_string($_POST['username']);
$sql = "SELECT * FROM table WHERE username = '$username'";
// osv...


Når det gjelder XSS er det tilsvarende funksjoner i PHP sin API som kan bidra til å gjøre ting tryggere, men du må nesten lese deg opp litt på det selv. Feks funksjonene htmlspecialchars, urlencode og strip_tags kan være nyttige.

Det som uansett er viktig, er: Aldri stol på det brukeren putter inn.

Dersom noen vil arrestere meg på det, så gjerne, og forklar hvorfor. Jeg er ikke noen sikkerhetsguru
Sist endret av tjodolv den ons 24.10.2007 0:56, endret 1 gang

Brukerens avatar
medlem i 209 måneder
 

Innleggav KiNexus » ons 24.10.2007 0:55

Kontrollere navn ved page request? Det er vel relativt unødvendig med mindre den sjekker etter passord også (hvis ikke variablen session kan settes inn på en annen måte av brukeren? eller forstår jeg svaret helt feil?

edit:
takk for svar, forresten :)

edit 2:
og ja, kontroll av brukerens stings skal være med (står som neste ting på listen)
medlem i 230 måneder
 

Innleggav tjodolv » ons 24.10.2007 0:59

Jeg er som sagt ingen stor sjef, og kan ikke huske helt begrunnelsen, men i en tutorial jeg leste stod det at man feks kunne sette et navn i $_SESSION, som serveren sjekker når spesielle sider eller funksjoner kalles. Det kan feks være tegn nr 5-15 i md5-hashen av brukernavnet eller noe slikt – hva som helst som gjør det enda litt vanskeligere å stoppe forsøk på snusk

edit: det er jo mange veier til Rom, og jeg er som nevnt ikke stor sjef her. Men å legge en kontrollfunksjon i $_SESSION er absolutt en løsning. $_SESSION settes jo av serveren, men blir puttet på klienten som en cookie, dermed er den strengt tatt åpen for manipulasjon. Derfor må man sørge for å sql-escape input fra brukeren, og sørge for at scriptet aldri vil kunne spy ut feilmeldinger som hinter en angriper i riktig retning. Selv ønsker jeg meg boka "Innocent Code" til jul, som visstnok skal være veldig bra.

Håper noen med mer peiling kan svare, får nå står jeg til rett opp under nesa dypt i vannet :rolls eyes:
Sist endret av tjodolv den ons 24.10.2007 1:04, endret 1 gang

Brukerens avatar
medlem i 209 måneder
 

Innleggav KiNexus » ons 24.10.2007 1:03

som jeg sa i første post legges username inn i $_SESSION, og deretter blir alle funksjoner i senere sider kjørt med $_SESSION['username'] i funksjonen. Beklager hvis jeg var litt uklar. [edit: Så lenge sluttbrukeren ikke kan endre $_SESSION-variablene på noen måte skulle det vel være nok med den første kontrollen, skulle det ikke?]

Litt eksempel på måten den er brukt:


Kode: Merk alt
session_start();
include "connect.php";
$username = $_SESSION['username'];
$getname = $_GET['n'];
if (!$getname == '') {$name = $getname;} else {if (!$username == '') {$name = $username;} else {$name = 'standard';}}

$query  = "SELECT username, role FROM kiusers WHERE username='$username' LIMIT 1";
$result = mysql_query($query);
$row = mysql_fetch_array($result, MYSQL_ASSOC);
$userelevation = $row['role'];


Bare et lite eksempel, det er nok noe der som er "feil" når det gjelder sikkerhet.

edit: Så at du endret svaret litt etter at jeg postet denne. Har bare et spørsmål til det du skrev. blir ikke $_SESSION-data lagret på serveren. Synes at jeg husker noen diskusjoner rundt $_SESSION-sikkerheten der de snakket om hvor man måtte plassere temp-filene til serveren... Tror det var noe av grunnen til at jeg ungikk å bruke cookier ^^

edit 2: Leste litt opp på det, og tenkte jeg kunne oppdatere posten så andre kan lære:
Session gir en unik id til sluttbrukeren. Denne sendes i plaintext. Men du slipper at data er lagret på sluttbrukerens datamaskin. Dataene er lagret på serveren, og hentes ut ved hjelp av session-id-en. Man kan ta ut disse dataene hvis man vet session-iden, så ikke legg denne i URLen. Hvis du er paranoid bør du også bruke mandatory SSL for å slippe at en person som leser packetene kan ta ut session-id av dem.
medlem i 230 måneder
 

Innleggav homer » ons 24.10.2007 7:09

I stedet for å legge brukernavn eller (aldri!) passordet i $_SESSION bør man heller sørge for at innloggingsprosedyren finner frem til riktig bruker, og så lagre brukerens unike ID-nr fra databasen, f.eks. i $_SESSION['userid']. Det er databasemessig 'bedre' for systemet at den verdien som evt. skal brukes som nøkkel for annen informasjon knyttet til brukeren er den som brukes i oppslag, f.eks. om den aktuelle brukeren skal sjekkes mot en brukergruppe som har tilgang til akkurat denne siden el.l., da er det logisk at bruker-ID er det som knytter brukeren til gruppen. Det er i alle fall det som er vanlig i andre databasesystemer.

Du kan gjerne også lagre brukernavn, adresse osv. i $_SESSION, men for oppslag og kontroll etter login, bruk ID. Og aldri, aldri lagre passord i $_SESSION. Du burde også vurdere å lagre passordet kryptert i databasen, men ulempen er at man da også må lage en passordgenerator for de som må nullstille passordet.

Bare noen tanker...

h 8)

Brukerens avatar
medlem i 212 måneder
 

Innleggav KiNexus » ons 24.10.2007 7:24

Ok, det skal jeg huske på. Må uansett skrive om inloggingen "fra bunnen av" for en ny side, så da begynner jeg med userid fra da av. Ganske logisk, med tanke på at folk kanskje vil bytte navn også...

Selv var jeg ganske enig i det å aldri lagre passord i variabler/arrays, men "guruen" min mente at man burde gjøre det, så jeg tenkte jeg kunne spørre noen flere mennesker, noe som jeg er veldig takknemmlig for nå.

Tusen takk for all hjelp. Med mindre det er noen flere som har innspill kan dere regne saken som løst.


-Ki
medlem i 230 måneder
 

Innleggav perfle » ons 24.10.2007 7:59

Husk at du ikke må lagre passordet i ren tekst. Bruk en enveiskryptering, gjerne med salt.

Brukerens avatar
medlem i 217 måneder
 

Innleggav homer » ons 24.10.2007 8:19

Guruen tar feil. Det finnes ingen som helst grunn til å aksessere brukerens (for det er det det er) passord annet enn for å logge inn (eller for å endre det). Alt annet blir bare oppfattet som uprofesjonelt og potensielt en sikkerhetsrisiko.

Når du likevel bygger om innloggingen, pass på at du søker på 'exact match' når du søker i basen etter brukernavn og passord. Hvis ikke er det en liten sjanse for at f.eks. brukeren 'anders' og brukeren 'anders_and' kan bli forvekslet av systemet. Det er også derfor man bygger innloggingen slik at den med 100% sikkerhet finner rett bruker, og deretter bruker man kun referansen til brukeren (userid) for resten av systemet. Exact match på tekst tar lenger tid enn et raskt oppslag på et tall, derfor er det hensiktsmessig å bruke det kun ved innlogging.

h 8)

Brukerens avatar
medlem i 212 måneder
 

Innleggav KiNexus » ons 24.10.2007 8:54

Vil denne metoden fungere? Dette er orginalkoden, før endring til det "nye systemet":

Kode: Merk alt
///////////////////////////////////////
#Stuff for starting the script properly
///////////////////////////////////////
session_start();
include 'connect.php';

///////////////////////////////////////
#POST information
///////////////////////////////////////
$username = $_POST['username'];
$password = $_POST['password'];

///////////////////////////////////////
#Debug information
///////////////////////////////////////
#echo "username - $username <br> password - $password";

///////////////////////////////////////
#Query to database
///////////////////////////////////////
$query  = "SELECT username, password, ip, password FROM kiusers WHERE username='$username' LIMIT 1";
$result = mysql_query($query);

///////////////////////////////////////
#Set results to readable variables
///////////////////////////////////////
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{$databaseusername = $row['username'];
$databasepassword = $row['password'];}
if ($databasepassword == $password) {
$_SESSION['username'] = $databaseusername;
$sessionusername = $_SESSION['username'];
} else {
echo "Error, wrong password. Please try again";echo '<head>
<meta>
</head>'; die;}

///////////////////////////////////////
#Debug information
///////////////////////////////////////
#echo "<br><br>username - $databaseusername <br> password - $databasepassword";
echo "<br><br>username now in the session is $sessionusername. You will now be redirected back to the index";
include 'disconnect.php';
echo '<head>
<meta>
</head>';
?>


Jeg ser nå at jeg kanskje burde kontrollere om $databaseusername er lik $username, men hvordan skal jeg utforme sqlen så den bare tar ut riktig person? Nå er vel (så vidt jeg ser) det eneste hullet om to brukere med liknende navn bruker samme passord.

edit: Det ser ut som om mac1 stripper ut html-content, men på stedene med meta-tagger skal det være en refresh på 5 sek med redirection til sidene de skal til (ny login-side/index)
medlem i 230 måneder
 


Returner til Utvikling på Mac



Hvem er i Forumene

Registrerte brukere: Google [Bot]