sql >> Databasteknik >  >> RDS >> Mysql

PHP Inloggningsformulär med HTML-formulär

Bara för headstuffs skull (så att du har en uppfattning om varför Fred -ii- sa att han inte skulle använda den här koden) - jag ska ta isär den här lite i ordning när jag går igenom den (det är inte en personlig grävning hos personen som ställer frågan - men bara för att ge en uppfattning om att att försöka bygga en halvvägs säker applikation på LAMP-stacken kräver lite försiktighet och eftertanke ... och blodig cynism i kombination med att anta det värsta i mänskligheten hjälper):

Punkt 1

Inte så stor - men egentligen om du ska starta en session bör du starta en session oavsett om det finns $_POST data eller inte. Du bör förmodligen kräva din konfigurationsfil och starta sessionen överst innan något annat.

Inte ett terminalfel (eftersom du inte har någon sessionsvalidering) - bara konstigt.

Punkt 2

Du har utdata i den här filen (echo ) därför måste den finnas under dokumentroten och tillgängligt i webbträdet.

include("config.php");

Det här är inte riktigt skrivet korrekt, det borde förmodligen vara require_once 'config.php'; (förutsatt att det är en obligatorisk programfil och inte en valfri inkludering som kan tillåtas misslyckas) men det är inte felet. Felet är att du har din konfigurationsfil i din dokumentrot. En serverfelkonfiguration eller ett enkelt stavfel i den filen skulle teoretiskt kunna tillåta att innehållet i den filen matas ut på skärmen i vanlig text, vilket potentiellt avslöjar dina databasanslutningssträngar (och vem vet vad mer) för världen + hund.

Konfigurationsfiler bör finnas utanför webbträdet eller, om det inte är möjligt, i en katalog som skyddas med något som .htaccess Deny from all . De ska aldrig vara tillgängliga via HTTP.

Punkt 3

mysql biblioteket är föråldrat och bör inte användas alls; MySQLi eller PDO är vägen att gå, helst med bundna parametrar/värden:

http://uk3.php.net/PDO

http://uk3.php.net/mysqli

Personligen hade jag valt PDO.

Punkt 4 och 5

$password = mysql_real_escape_string(stripslashes(md5($_POST['password'])));

För det första är ordningen på detta fel. Du hashar $_POST['password'] och sedan försöker ta bort snedstreck - det kommer inte att finnas några snedstreck när det väl har hashas. Men om du försöker hindra människor från att använda snedstreck (eller vad som helst) i lösenord måste du ta bort dem innan du hasha strängen.

Nästa md5 bör inte användas som en hashningsalgoritm för lösenord, den har visat sig vara svag och kan tvingas att skapa strängkollisioner mycket oftare än den borde.

Ja, du bör lagra bara hash eller "fingeravtryck" av lösenorden istället för själva lösenorden, men helst vill du salta och hasha (med åtminstone sha1 ) dessa lösenord istället för att bara kasta dem i en md5() funktion.

Se:http://uk3.php.net/mcrypt till exempel

Och gör en sökning på "password salting hashing" med hjälp av din sökmotor.

Punkt 6

SELECT id FROM $table 
WHERE username = '" . $username . "' 
and password = '" . $password . "';

Jag lade till = som saknades i den ursprungliga frågan, men ändå matchar inte användarnamn och lösenord i din fråga ... om någon lyckades få en SQL-injektion i ditt användarnamn skulle lösenordet aldrig kontrolleras. Föreställ dig:

SELECT user.id 
FROM user WHERE user.username = 'fred' OR 1 = 1 
-- AND user.password = 'abc123'

Det är bättre att välja användar-id och lösenordsfingeravtryck från databasen och sedan utvärdera lösenordet i programmet snarare än att lita på en lösenordskontroll i databaslagret. Det betyder också att du kan använda en dedikerad hash- och saltningsalgoritm i själva applikationen för att validera dina lösenord.

Punkt 7

$_SESSION['user'] = $_POST["username"];

Detta lagrar bara användarnamnet i sessionen? Detta bör inte på något sätt användas som en "inloggningsverifierare", särskilt eftersom det (tydligen) inte finns något i din session som förhindrar kapning .

Sessions-id:t skulle lätt kunna sniffas från cookien från en livesession och det är allt som skulle krävas för att "låna" någon annans inloggning. Du bör åtminstone försöka minska risken för att sessionen kapas genom att associera användarens IP-adress, UserAgent-sträng eller någon annan kombination av relativt statisk data som du kan jämföra med på varje sida... det finns dock nackdelar med praktiskt taget alla metoder. (särskilt, som jag har upptäckt, om du har besökare som använder AOL) - men du kan göra ett förmodligen 99+ % effektivt sessionsfingeravtryck för att mildra kapning med mycket liten chans att användarens session dumpas felaktigt.

Helst kanske du också vill skapa en token för sessionen för att mildra CSRF attacker när användaren behöver utföra en "privilegierad" åtgärd på databasen (uppdatera sina uppgifter eller vad som helst). Token kan vara en helt slumpmässig och unik kod som lagras i databasen och/eller i en SSL-cookie när användaren loggar in (förutsatt att användaren inte kan utföra någon åtgärd som uppdaterar databasen utanför HTTPS eftersom det bara skulle överföra data i klartext över hela Internet – vilket vore en dålig idé ).

Tokenen placeras i ett dolt formulärfält för alla formulär och kontrolleras mot värdet som lagras i cookien (eller sessionen eller databasen) närhelst det formuläret skickas. Detta säkerställer att personen som skickar formuläret åtminstone har en livesession på din webbplats.



  1. Fundamentals of table expressions, Del 4 – Härledda tabeller, optimeringsöverväganden, fortsättning

  2. Hur tar jag reda på standardserverns teckenuppsättning i mysql?

  3. SQLite JSON_EACH()

  4. mysql kastar okänd kolumn 'mac' i 'fältlista'