Ist dieser Code Safe?

5 Antworten

Wie ich dir schon vor einem Monat schrieb:

Beachte im Übrigen, dass dein Login-Skript nicht sicher ist. Zum einen ermöglichst du einem Anfragenden, SQL-Injections durchzuführen (...) Verwende stattdessen Prepared Statements (...)

Ausführungen und Beispiele dazu findest du in der PHP-Dokumentation oder auf W3Schools.

Im Weiteren prüfenswert:

1) Achte darauf, in der Kommunikation (Client-Server, Server-DB-Server) stets eine stabile Zeichenkodierung wie UTF-8 (für MySQL wäre das utf8mb4) zu verwenden.

2) Die email-Spalte sollte ein Primärschlüssel in der Tabelle sein.

3) Die Verbindung sollte über TLS laufen.

4) Praktisch wäre es, für die Kommunikation einen zusätzlichen Schlüssel zu übermitteln, der das Spiel als Senderquelle ausweist. Das ist natürlich keine völlig vertrauenswürdige Information, aber ein erster grober Filter.

5) Werden bei jeder Anfrage die Logindaten geprüft oder öffnest du eine Art Session / generierst einen Zugriffstoken / o.ä.? Das ist eine relevante Frage, wenn es darum geht, folgende Client-Anfragen (Daten auslesen/Ausführen von Operationen) zu bearbeiten.

6) Nicht komplett im Zusammenhang mit Sicherheit, aber dennoch überdenkenswert: Wieso steht 0 für Erfolg? Es gibt doch bekannte HTTP Status Codes (202, 400, 403, ...), die sich für ein Statusfeedback eignen (siehe http_response_code).

Wenn du dazu im Response Textmeldungen aufführen möchtest, überlege dir ein festes Format (z.B. JSON: { "message": "...", "success": true }) und formuliere Fehlermeldungen etwas abstrakter (Bsp.: Wenn das Passwort falsch war, sollte das nicht konkret in der Fehlermeldung stehen, da ein Angreifer daraus schlussfolgern könnte, dass es zumindest den Nutzernamen gibt).


nikeboycookie 
Beitragsersteller
 27.10.2023, 16:21

$stmt = $conn->prepare("SELECT password FROM users WHERE email = ?");

$stmt->bind_param("s", $email);

// Ausführen des Statements

$stmt->execute();

$result = $stmt->get_result();

if ($result->num_rows > 0) {

    $row = $result->fetch_assoc();

    $hashedpassword = $row['password'];

    if (password_verify($password, $hashedPassword)) {

        // Successfully logged in

        $errors[] = "505";

    }

} else {

 

    $errors[] = "303";

}

$stmt->close();

$conn->close();

Ich hab das jetzt so gemacht, aber irgendwas klappt da nicht

regex9  27.10.2023, 17:55
@nikeboycookie

Nun, das irgendwas musst du dann wohl genauer untersuchen. Lass dir z.B. Zwischenwerte ausgeben.

nikeboycookie 
Beitragsersteller
 27.10.2023, 16:00

bei jeder Anfrage werden die Daten geprueft

LG

$sql = "SELECT * FROM users WHERE email = '$email'";

Niemals Benutzereingaben einfach so an einen String hängen!

Du ermöglichst damit SQL-Injections.

Ansonsten: Der HTTP Code 303 könnte irreführend sein, da du damit einen Redirect vorgibst.

Ebenfalls der Error Code 0 ist kein HTTP Code.

Da kommt jetzt noch drauf an, was passiert, wenn du den Error Code 0 zurückgibst. Da lässt sich gerade nicht sagen ob das sicher oder unsicher ist.

Woher ich das weiß:Studium / Ausbildung – Bachelor-Student in Informatik

nikeboycookie 
Beitragsersteller
 27.10.2023, 17:38

nach 0 passiert in unity das
              Debug.Log("Successfull);

              DBManager.Instance.Email = email;

              SceneManager.LoadScene(1);

NoArtFX  27.10.2023, 17:46
@nikeboycookie

Ah hab überlesen, dass es sich um ein Unity Projekt handelt.

Da kenn ich mich nicht aus, aber ausser der SQL Injection seh ich grad weniger Probleme auf PHP Seite.

Wichtig ist einfach, dass du eine SSL Verbindung zum Server aufbaust, also dass dein PHP Script, bzw. der Webserver wo dein PHP Script drauf ist, ein SSL Certificate hat.

Hinsichtlich Cyber Security Standarts? Nein, nicht so sehr.

Du machst doch gar nichts um die verbindung zum server zu sichern. Du liesst doch nur krams aus der datenbank aus, checkst, ob das Passwort richtig ist oder nicht und fertig. Du verhinderst nicht das Hacker die Datenbank einfach auslesen.


nikeboycookie 
Beitragsersteller
 27.10.2023, 14:51

Von cyber security hab ich leider nicht so eine Ahnung, da das mein erstes Login System ist. Wie kann ich es denn verbessern?

LG

Da ist so Einiges. Du erhöhst die Sicherheit, wenn der Code auf der Clientseite schon gehasht wird.

Aber wichtiger ist: Es geht ja nicht darum, ob Du eine gewisse Seite herausgibst, sondern Du möchtest bei allen Seiten unterschiedlichen Inhalt ausgeben, je nachdem ob die Person eingeloggt ist. Dafür gibt es üblicherweise Frameworks, die Dir dabei helfen.

Die $email so als Teil der SQL-Abfrage zu nutzen macht Deinen Code verwundbar für SQL Injection.


smiregal8472  20.03.2024, 18:41
Du erhöhst die Sicherheit, wenn der Code auf der Clientseite schon gehasht wird.

Damit würde sich die Sicherheit um exakt 0 erhöhen.

Vollkommen egal, ob das Kennwort oder ein Hash übertragen und dann serverseitig abgeglichen wird, sollte sich jemand in die Leitung hängen, dann läuft beides exakt auf's gleiche raus.

Und das wäre noch der beste Fall.

W00dp3ckr  20.03.2024, 18:44
@smiregal8472

Na, da bist Du aber gedanklich etwas limitiert, was Angrifsszenarien angeht. Stell Dir vor, Du hast Datenabfluss, dann macht der Hash schon einen immensen Unterschied.

smiregal8472  20.03.2024, 18:51
@W00dp3ckr
dann macht der Hash schon einen immensen Unterschied.

Wie sollte er?

Wenn du den Hash zum Server überträgst um ihn dann dort abzugleichen, dann brauchst du beim Aufzeichnen des Datenflusses auch nur den Hash abzugreifen und schon kannst du dich beim Server authentifizieren.

Was glaubst du, warum heutzutage so ziemlich alles über HTTPS läuft statt unverschlüsselt?

W00dp3ckr  20.03.2024, 19:04
@smiregal8472

Ich gehe einfach mal davon aus, dass jemand mit Hirn das über HTTPS laufen lässt. Alles Andere ist momentan eh ein Kunstfehler. Viele Frameworks erlauben das gar nicht mehr.

Aber zu den Passwort-Hashes: Wenn Du Datenabfluss hast, und Die Passwörter nicht gehasht waren, bekommst Du Ärger. Ganz einfach. Weil die Passwörter im Klartext sehr viel “brauchbarer” sind als gehashte PWs mit Salz.

Wenn Du mir das nicht glaubst, dann google das mal, bekommst Du sicher hin.

smiregal8472  20.03.2024, 19:07
@W00dp3ckr

Diese Hashes von denen du sprichst liegen auf dem Server.

Den Hashvorgang bereits Clientseitig durchzuführen bringt im besten Fall gar keine Verbesserung der Sicherheit und im schlimmsten Fall eine massive Verschlechterung derselben.

P.S.: Googlen kannst du mal schön selber machen, da liegt bei dir offensichtlich weit mehr Notwendigkeit für vor...

W00dp3ckr  20.03.2024, 19:49
@smiregal8472

LOL. Also ganz langsam. Dass ein Passwort irgendwo abgegriffen wird, das kann passieren. Da hilft dann auch kein Hash, damit ist dann EIN Nutzer kompromittiert. Wenn der Hash mit Salt verwendet wird, ist er aber auch nur auf EINER Seite kompromittiert. Mit dem ohne Hash und ohne Salt, ist es dann ein Problem für einen Nutzer auf potentiell vielen Websites.

Das, wovor man als Betreiber einer Webseite mit personenbezogenen Daten wirklich Angst hat, ist, dass jemand sie hackt, und dann die Passwörter im Klartext abfließen, die dann zusammen mit den ebenfalls gespeicherten Mailadressen für Scam oder auch einfach für das Einloggen bei möglichst vielen anderen Seiten genutzt werden können. Das kann man mit den Hashes sehr stark erschweren, wenn der Hash groß genug ist, die Passwörter lang genug sind und Salz verwendet wird.

smiregal8472  20.03.2024, 19:57
@W00dp3ckr

Meine Fresse, genau das sag ich ja.

Du hast aber behauptet, dass das Hashen auf Clientseite zur Verbesserung der Sicherheit beitragen würde. Und das ist einfach nur völliger Mumpitz.

Aber hier nochmal, damit du's auch kapierst:

  1. Der Client überträgt das Kennwort zum Server.
  2. Der Server hasht das Kennwort und gleicht das Ergebnis mit dem zur Benutzer-ID gehörenden Hash aus seiner Datenbank ab.
  3. Entweder stimmen gespeicherter und berechneter Hash überein, dann ist der Login erfolgreich, ansonsten nicht.
W00dp3ckr  20.03.2024, 21:54
@smiregal8472

Und wann ist es schlechter den Hash im Client zu berechnen? Wenn auf dem Weg der Hash abgegriffen wird, ist nur der Hashwert kompromittiert, nicht das PW. Aber wie wir uns einig sind ist der Sicherheitsgewinn davon marginal. Und SSL muss benutzt werden. Danke, dass Du mir meinen Job erklärst, vielleicht finden sich ja noch andere, denen Du alles ganz genau und von oben herab erklären kannst.

smiregal8472  20.03.2024, 22:04
@W00dp3ckr

Der Sicherheitsgewinn ist nicht marginal, sondern exakt 0.

Der einzige "Sicherheitsgewinn", den man hierbei haben könnte, wäre der, dass der Datenangreifer sich zwar bei dem einen Server authentifizieren könnte, ohne das Kennwort zu kennen, aber nicht bei anderen Servern, bei denen der Benutzer ebenfalls das Kennwort "1234567" verwendet.

Aber in diesem Fall müsste der Client natürlich auch das Salz kennen, das verwendet wurde, was den Aufwand bei dieser Herangehensweise unverhältnismäßig höher als den wirklichen Nutzen treiben würde.

Und wenn du tatsächlich einen Fall suchst, in dem clientseitiges Hashen einen definitiven Nachteile hat: Das wäre der Fall, wenn der Client für jeden Authentifizierungsvorgang ein neues Salz generieren würde. Denn dann müsste dem Server das ungehashte Kennwort vorliegen.

Würde zwar (hoffentlich) niemals jemand so implementieren, aber es gibt immer den einen wahnsinnigen Idioten, man weiß nur nicht wo und wann er zuschlägt.

nein, der Code ist alles andere als sicher. du quotest die eingabe nicht, das ist ein klassischer SQL Injection fall


nikeboycookie 
Beitragsersteller
 27.10.2023, 16:43

eine Frage ist sql injection bei Register quch ein ding? Denke nein oder?

geheim007b  27.10.2023, 17:23
@nikeboycookie

bei register?

du darfst usereingaben nie ungeprüft in eine SQL Abfrage überführen

W00dp3ckr  20.03.2024, 19:50
@nikeboycookie

Ganz allgemein kannst Du SQL Injizieren, wenn ein Parameter aus dem Web ungeprüft verwendet wird.