yanmai
Goto Top

PHP MySQL Login

Hallo ihr Administratoren,
ich habe eine Datenbank, in der alle User des Netzwerkes enthalten sind. Wenn ein User sich einloggen will, dann soll PHP die Datenbank durchsuchen und das Passwort abgleichen. Wenn dies korrekt ist, soll eine Session Variable erstellt werden und eine neue Seite aufgerufen werden (<meta http-equiv="refresh" content="2; URL=seite2.php"/>). Die seite2.php enthält dann auch die Session und ruft anhand von dieser Variable dann den Username ab. Ich habe schonmal einen Ansatz:

<?php
session_start();
$verhalten = 0;

   	$conn = mysqli_connect($servername, $username,$password,$database);

	if($conn)
	{
		if(!isset($_SESSION["username"]) AND !isset($_GET["page"])) {  
			if($_GET["page"] == "log") {  
				$CurrentUser = mysqli_real_escape_string($conn, $_POST["user"]);  
				$UserPasswort = mysqli_real_escape_string($conn, $_POST["password"]);  
				$sqlQuery = "SELECT passwort FROM `Benutzerliste` WHERE username='$CurrentUser'";  
				$result = mysqli_query($conn, $sqlQuery);
				if($result)
				{	
					if(password_verify($UserPasswort, $result["passwort"]))  
					{
						$_SESSION["username"] = $CurrentUser;  
						$verhalten = 1;
					} else {
						echo "Fehler";  
						$verhalten = 2;
					}
				}
				else
				{
					echo "Error in SQL statement";  
					$vergessen = 2;
				}
			}
		}
	}
?>

<form method="post" action="mslogin.php?page=log">  
				<table cellpadding="20px">  
					<tr>
						<td><font color="919191" size="+1" face="Calibri"><label>Benutzername:</label></font></td>  
						<td><input type="text" name="user"/></td>  
					</tr>
					<tr>
						<td><font color="919191" size="+1" face="Calibri"><label>Passwort:</label></font></td>  
						<td><input type="password" name="password"/></td>  
					</tr>
					<tr>
						<td colspan="2"><input type="submit" /></td>  
					</tr>
				</table>
			</form>

Der <meta refresh Teil befindet sich im header der Website. Wie kann man dieses Problem lösen? Es passiert im Moment nichts face-sad

Content-Key: 320791

Url: https://administrator.de/contentid/320791

Printed on: April 19, 2024 at 09:04 o'clock

Member: BirdyB
BirdyB Nov 12, 2016 at 22:25:10 (UTC)
Goto Top
Hi,
ich würde schonmal garkeine Passwörter direkt übertragen, sondern nur Hashes!!!
Und wieso der <meta>-Tag?

Beste Grüße!
Member: maretz
maretz Nov 13, 2016 at 08:39:57 (UTC)
Goto Top
Moin,

zuerst mal würde ich ebenfalls dazu tendieren keine plain-Strings zu übertragen. Mit Escape ist zwar schon gut aber generell gibt es dafür keinen Grund (ok, https usw. wäre natürlich auch möglich).

Dann würde ich z.B. eine Abfrage machen wie "select xyz from abc where username LIKE "$username" AND password LIKE "$passwort"". Damit hast du schon mal einen Vergleich gespart - die DB muss eh vergleichen (den Usernamen), dann brauchst du nich 100.000 Ergebnisse noch mal vergleichen lassen (passwort).

Weiterhin würde ich die Felder im Quellcode nicht "user" und "password" nennen - dies macht heute jeder script-robot dann direkt als brute-force. Nenne die Felder halt "jubelju" und "halleluja" oder sonstwie. Dies schützt natürlich nicht vor einem Angriff, aber zumindest etwas ruhe vor den Skript-Kiddys die einfach nur ihr Script auf das Internet losjagen.
Member: kaiand1
kaiand1 Nov 13, 2016 at 09:55:12 (UTC)
Goto Top
Gegen Angriffe ist ja noch meist ein Script das die Abfragen zählt und wenn x Fehlerhafte/Anfragen in y Zeit erfolgen wird IP/User gesperrt Temporär was weitere Angriffe erschwert.
Zudem ist es auch nicht Optimal alles in Kekse zu schreiben die der Angreifer eh Manipulieren kann.
Member: Yanmai
Yanmai Nov 13, 2016 at 11:28:00 (UTC)
Goto Top
Vielen Dank erstmal für die Antworten face-smile

In der Datenbank werden nur gehashte Passwörter gespeichert. Wenn sich Benutzer a einloggt, wird das gehashte Passwort von Benutzer a ausgegeben und über password_verify() überprüft. Also soll ich das plain Password auch hashen? Kommt dann genau das selbe raus?

Wenn der Login erstmal funktioniert, werde ich mir Gedanken machen, wie man den Login gegen brute force Angriffe schützen kann face-smile
Member: Yanmai
Yanmai Nov 13, 2016 at 11:32:51 (UTC)
Goto Top
Ich habe das in einem YouTube Tutorial gesehen, dass dann die andere Seite geöffnet wird und dieser dann die Session Variable übergeben wird.
Member: eagle2
eagle2 Nov 14, 2016 at 19:39:49 (UTC)
Goto Top
Moin Yanmai,

versuch mal den Redirect direkt in PHP zu machen, über die Header-Funktion (Erklärung wie das geht).

Ansonsten würde ich dir empfehlen, dich systematisch in das Thema einzuarbeiten. Auch wenn ja inzwischen alles online und kostenlos sein soll, möchte ich dabei mal Werbung für zwei Bücher machen (mit denen ich nichts zu tun habe und auch keine Affiliate bekomme oder sonst irgendwas):

PHP & MySQL für Kids
PHP & MySQL Praxisbuch für Kids

Im ersten Buch lernt man die Basics, im zweiten wird dann u.a. auch ein vollständiges Loginsystem entwickelt (abgesehen davon, dass da noch SHA1 für Passwörter verwendet wird - die password_hash/password_verify-Funktionen sind da deutlich besser).

Viele Grüße
eagle2
Member: Sheogorath
Sheogorath Nov 15, 2016 at 10:02:38 (UTC)
Goto Top
Moin,

ich würde schonmal garkeine Passwörter direkt übertragen, sondern nur Hashes!!!

Ähm.. nein?

Denn was machst du auf der Gegenseite mit Hashes? Du vergleichst sie mit dem Hash der in deiner DB gespeichert ist? Dann speicherst du deine Passwörter ja doch quasi wieder im Plaintext. Nur dass du sie eben Clientseitig nochmal in was anderen verpackst.

Deswegen werden Passwörter in der Regel tatsächlich übertragen. Aber man kann natürlich so schöne Dinge wie Challange-Response implementieren. Aber nun ja, das ist in der heutigen Praxis zum Glück eigentlich untergegangen, denn man hat halt HTTPS, 2FA und OAuth. Alles mehr oder weniger sicher, aber wie gesagt Hashes überträgt man eigentlich nur da, wo man keine Lust mehr auf sonst was hat.

Und nicht zu vergessen dass CR auch nur funktioniert solange auf beiden Seiten die Passwörter vorliegen, sprich du deine Passwörter irgendwo im Plaintext speichern musst. Das ist bei diesem Use-case weit fahrlässiger als sie irgendwo zu übertragen. Zumindest wenn man HTTPS oder ähnliches als Transport Protokoll verwendet.

Noch sicherer wäre natürlich eine zertifikatsbasierte Authentifizierung, aber das wird die meisten hier überfordern, also lassen wir das mal.

---

Und um dem Thread noch was sinnvolles beizufügen: Sichere Methoden zur Speicherung von Passwörtern in Datenbanken:
https://crackstation.net/hashing-security.htm

Gruß
Chris