• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

PHP: mysql_real_escape_string() - Problem

venom2k6

NGBler

Registriert
15 Juli 2013
Beiträge
107
Tag zusamen ^^
ich arbeite grade an meinen Login system und model mir das in mysqli um... nun habe ich beim einloggen ein Problem ich bekomme ständig eine Fehlermeldung angezeigt, finde aber leider dazu derzeit keine lösung :/ ich hoffe mir kann einer von euch helfen ^^

Aktuell benutze ich

XAMPP 1.8.3-2
Apache 2.4.7
MySQL 5.6.14
PHP 5.5.6
phpMyAdmin 4.0.9
FileZilla FTP Server 0.9.41
Tomcat 7.0.42 (with mod_proxy_ajp as connector)
Strawberry Perl 5.16.3.1 Portable
XAMPP Control Panel 3.2.1 (from hackattack142)

FEHLERMELDUNG:
Deprecated: mysql_real_escape_string(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in C:\XXX\YYY\htdocs\www\dsl2014\acp\auloggedin.php on line 12

im grunde geht es da um diesen part:
[src=php]<?php
// Session starten
session_start();

include 'src/iconnect.php';

$login_sql = "SELECT ".
"usr_id, usr_name, usr_passwd, usr_lastip, usr_last_login, usr_lvl, usr_firstname, usr_lastname, usr_email, usr_short, usr_gender".
"FROM ".
"acp_users ".
"WHERE ".
"(usr_name = '".mysql_real_escape_string($_REQUEST["username"])."') AND ".
"(usr_passwd = '".md5(mysql_real_escape_string($_REQUEST["userpass"]))."')"; //md5(); für verschlüsselung
$login_query = $db->query($login_sql);
//...
?>
[/src]
da scheint irgendwas an mir vorbeigegangen zu sein ^^"
schon mal danke im vorraus :)
 

misterunknown

Wannabe

Registriert
19 Jan. 2014
Beiträge
135
Du benutzt mysqli - dann benutze auch mysqli_real_escape_string(). Beachte, dass dieser Funktion, wenn du sie im prozedoralen Stil verwendest, das Verbindungsojekt mit übergeben werden muss.

Für derartige Anwendungsfälle gibt es aber auch, wie die Fehlermeldung schon sagt, PDO. Gucks dir mal an, das ist eine wirklich schöne Sache.
 

venom2k6

NGBler

Registriert
15 Juli 2013
Beiträge
107
  • Thread Starter Thread Starter
  • #3
Super, danke. Hätte ich auch selbst drauf kommen können ist ja beim verbinden ähnlich ^^

nun hab ich ein neues Problem...

FEHLERMELDUNG:
Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at C:\XXX\YYY\htdocs\www\dsl2014\acp\src\partner.php:46) in C:\XXX\YYY\htdocs\www\dsl2014\acp\auloggedin.php on line 3

Problem hierbei ist...
in der partner.php ist lediglich ein Div Container, sonst nichts... sowie in den PHP dateien die davor included werden ^^ und nirgendswo wird eine Session gestartet :unknown:

hab schon versuch auf der login seite mit session_destroy() die session zu zerstören aber auch das bleibt leider ohne erfolg
 

misterunknown

Wannabe

Registriert
19 Jan. 2014
Beiträge
135
Super, danke. Hätte ich auch selbst drauf kommen können ist ja beim verbinden ähnlich ^^
Ja, hättest du^^

in der partner.php ist lediglich ein Div Container, sonst nichts... sowie in den PHP dateien die davor included werden ^^ und nirgendswo wird eine Session gestartet :unknown:
Eine Session kannst du nur starten, wenn noch keine Header gesendet wurden; das bedeutet: Nur vor jeglicher Ausgabe! (Auch, wenn die "Ausgaben" noch nicht zum Client gesendet wurden...) Ich habe mir angewöhnt, in allen Fällen, in denen ich mit PHP-Sessions arbeiten muss, eine extra Datei dafür zu schreiben, die immer in der ersten Zeile eines Skripts included wird. Damit geht man einigem Ärger aus dem Weg.
 

venom2k6

NGBler

Registriert
15 Juli 2013
Beiträge
107
  • Thread Starter Thread Starter
  • #5
ja einen Header hab ich aber noch nicht gesendet ^^
um ehrlich zu sein hab ich noch nicht so ganz verstanden wozu der gut sein soll, ich habe an sich so gelöst das ich eine normale META weiterleitung nutze...

vielleicht ist auch das das Problem ^^

wie kann ich dieses problem genau lösen? ^^

EDIT:
hab grade gefunden eine datei wird mittendrin included die session_start() ganz oben hatte ^^ nach dem entfernen war der fehler weg ^^, da vor dieser includierten datei diverse PHP variablen und HTML geschichten liefen ^^
 

antu

NGBler

Registriert
11 Nov. 2013
Beiträge
396
Ort
/home/antu
Die Fehlermeldung besagt, dass die Funktion mysql_real_escape_string() veraltet ist und nicht mehr verwendet werden sollte. Wie misterunkown bereits geschrieben hat, kannst du stattdessen mysqli_real_escape_string() verwenden.

[src=php]"(usr_passwd = '".md5(mysql_real_escape_string($_REQUEST["userpass"]))."')"; //md5(); für verschlüsselung[/src]
Die Reihenfolge ist falsch, du solltest erst eine Prüfsumme aus dem Kennwort berechnen und das Ergebnis anschließend escapen. Außerdem ist das Bilden einer einfachen MD5-Prüfsumme heutzutage nicht mehr sicher, da heutige Hardware in der Lage ist solche Prüfsummen in relativ kurzer Zeit mittels Brute-Force zu knacken, bzw. es gibt bereits umfangreiche Regenbogentabellen um aus MD5-Prüfsummen die Kennwörter zu berechen. Zur Absicherung von Kennwörtern wurde in PHP 5.5 die neue Funktion password_hash() eingeführt, die für diesen Zweck besser geeignet ist.

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at C:\XXX\YYY\htdocs\www\dsl2014\acp\src\partner.php:46) in C:\XXX\YYY\htdocs\www\dsl2014\acp\auloggedin.php on line 3
Wenn ich mich recht entsinne, muss eine Session gestartet werden bevor irgendeine Ausgabe an den Benutzer gesendet wurde. Achte also darauf keine Ausgaben zu machen, bevor du die Session startest, also auch keine Leerzeichen/Zeilenumbrüche. Vielleicht hast du in einer der inkludierten Dateien nach dem "?>" noch eine Leerzeile/Leerzeichen?

Tipp: Du kannst in reinen PHP-Dateien das abschließende "?>" auch weglassen.
 

misterunknown

Wannabe

Registriert
19 Jan. 2014
Beiträge
135
ja einen Header hab ich aber noch nicht gesendet ^^
Wenn nicht manuell, dann wird das automatisch gemacht, sobald ein Output started.

Und dein Output started in partner.php auf Zeile 46, wie der Fehlermeldung zu entnehmen ist.

--- [2014-01-22 12:23 CET] Automatisch zusammengeführter Beitrag ---

Tipp: Du kannst in reinen PHP-Dateien das abschließende "?>" auch weglassen.
Das ist aber sehr schlechter Stil und dient weder der Lesbarkeit, noch hat es einen anderen Vorteil ;) Diese zwei Zeichen tun doch nicht weh.
 

venom2k6

NGBler

Registriert
15 Juli 2013
Beiträge
107
  • Thread Starter Thread Starter
  • #8
Zur Absicherung von Kennwörtern wurde in PHP 5.5 die neue Funktion password_hash() eingeführt, die für diesen Zweck besser geeignet ist.

kann mysql mit den werten vernünftig arbeiten???

denn immerhin generiert er immer einen anderen Hashwert...


Laut Umrechnung des Passworts: 12345678
Durchlauf 1: $2y$11$P6a5AmnIYDFcpMIPAKOVwOQJPUHFy3RhprmYVhivzzthl0mqYI7RK
Durchlauf 2: $2y$11$d/9JiXF8t0wTFuq.Iv.n8.72LPJEW/hant4Yc/PE4e9a2Iy6RgHH6
Durchlauf 3: $2y$11$AJ05TASs4kl.JdVLhdLw1u9f5TXtmCJmRrK3lz2RRGz47vnMRWWie

Umwandel-Option:
[src=php]
$options = [
'cost' => 11,
'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
];
password_hash('12345678', PASSWORD_BCRYPT, $options)[/src]

war jetzt ein Beispiel von PHP.net
 

sars

Agent Provocateur

Registriert
15 Juli 2013
Beiträge
54
Das ist aber sehr schlechter Stil und dient weder der Lesbarkeit, noch hat es einen anderen Vorteil ;) Diese zwei Zeichen tun doch nicht weh.

Im Gegenteil: Das weglassen des abschließenden '?>' entspricht den gängigen best practices, siehe u.a. Zend Framework Coding Standard for PHP. Ein unbeabsichtigtes Leerzeichen nach dem closing tag kann sonst schnell zu der oben erwähnten headers already sent-Fehlermeldung führen und ist ggf. schwer auszumachen.

venom2k6 schrieb:
kann mysql mit den werten vernünftig arbeiten???
denn immerhin generiert er immer einen anderen Hashwert...

Das liegt daran, dass in dem Beispiel in $options bei jedem Durchlauf ein zufälliger Wert für 'salt' generiert wird, der in die Berechnung des Hashs mit einfließt.

Schau dir einfach mal den Thread hier an: Ist dieses Loginscript gut und sicher?
 

antu

NGBler

Registriert
11 Nov. 2013
Beiträge
396
Ort
/home/antu
Das ist aber sehr schlechter Stil und dient weder der Lesbarkeit, noch hat es einen anderen Vorteil ;) Diese zwei Zeichen tun doch nicht weh.
Ganz im Gegenteil, es wird sogar in der PHP-Dokumentation empfohlen: PHP tags. Und zwar genau aus dem Grund, eben um zu verhindern, dass versehentlich Leerzeichen/Zeilenumbrüche ausgegeben werden. :)

kann mysql mit den werten vernünftig arbeiten???

denn immerhin generiert er immer einen anderen Hashwert...


Laut Umrechnung des Passworts: 12345678
Durchlauf 1: $2y$11$P6a5AmnIYDFcpMIPAKOVwOQJPUHFy3RhprmYVhivzzthl0mqYI7RK
Durchlauf 2: $2y$11$d/9JiXF8t0wTFuq.Iv.n8.72LPJEW/hant4Yc/PE4e9a2Iy6RgHH6
Durchlauf 3: $2y$11$AJ05TASs4kl.JdVLhdLw1u9f5TXtmCJmRrK3lz2RRGz47vnMRWWie

Umwandel-Option:
[src=php]
$options = [
'cost' => 11,
'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
];
password_hash('12345678', PASSWORD_BCRYPT, $options)[/src]

war jetzt ein Beispiel von PHP.net
Wie meinst du das, ob MySQL damit arbeiten kann?

Das Salz musst du nicht selbst generieren, das kannst du weglassen, PHP generiert dann automatisch einen Zufallswert fürs Salzen. Die errechnete Prüfsumme ist immer unterschiedlich, weil das Kennwort vor der Berechnung der Prüfsumme jedes mal mit anderen Zufallsdaten "gesalzen" wird, d.h. es werden noch zufällige Daten an das Kennwort angehängt.

Das Ergebnis von password_hash enthält die Zufallsdaten mit denen das Kennwort gesalzen wurde, den Kostenfaktor (in deinem Fall 11), sowie die berechnete Prüfsumme und den verwendeten Algorithmus. Mithilfe dieser 4 Parameter kann password_verify überprüfen, ob ein gegebenes Kennwort mit der Prüfsumme übereinstimmt. Hintergrundinformationen dazu, wie die Parameter kodiert werden, findest du hier.

Ein Beispiel:
[src=php]$eingegebenesKennwort = '12345678';

$optionen = [
'cost' => 11,
];

$pruefsumme = password_hash($eingegebenesKennwort, PASSWORD_BCRYPT, $optionen);

echo "Dein Kennwort: $eingegebenesKennwort\n";
echo "Berechnete Pruefsumme: $pruefsumme\n";

// Ueberpruefe Kennwort

$ueberpruefung = password_verify($eingegebenesKennwort, $pruefsumme);

echo "Stimmt das Kennwort mit der Prüfsumme ueberein?: " . (($ueberpruefung) ? 'ja' : 'nein') ."\n";

$ueberpruefung = password_verify('falscheskennwort', $pruefsumme);

echo "Stimmt das Kennwort 'falscheskennwort' mit der Prüfsumme ueberein?: " . (($ueberpruefung) ? 'ja' : 'nein') ."\n";[/src]

Ausgabe:
[src=text]Dein Kennwort: 12345678
Berechnete Pruefsumme: $2y$11$ttLFVByOTaHeVcziMUFoFeacLOIf2QHn9FjyCAiGj7DuRXo.oJJoi
Stimmt das Kennwort mit der Prüfsumme ueberein?: ja
Stimmt das Kennwort 'falscheskennwort' mit der Prüfsumme ueberein?: nein[/src]
 

venom2k6

NGBler

Registriert
15 Juli 2013
Beiträge
107
  • Thread Starter Thread Starter
  • #12
Wie meinst du das, ob MySQL damit arbeiten kann?

was ich meine ist

wenn in der Datenbank
im Feld Passwort: $2y$11$P6a5AmnIYDFcpMIPAKOVwOQJPUHFy3RhprmYVhivzzthl0mqYI7RK
steht kann ich doch nicht erfolgreich: $2y$11$d/9JiXF8t0wTFuq.Iv.n8.72LPJEW/hant4Yc/PE4e9a2Iy6RgHH6
Abfragen... zumindest nicht mit = wie

muss ich das nun anders abfragen???

Nutzer Logged sich mit seinen Daten ein

Benutzername & Passwort wird aus der MySQL Datenbank ausgelesen und ggf. in variablen $from_sql_user & $from_sql_passwd gespeichert

Die eingegebenen Daten vom Nutzer werden mit mit password_hash verhasht ($eingabe_hash) und das verashte password wird mit password_verify($eingabe_hash, $from_sql_passwd) überprüft? also ein direktes abgleichen im SQL statement wird somit nicht mehr gemacht?
versteh ich das richtig?
 

antu

NGBler

Registriert
11 Nov. 2013
Beiträge
396
Ort
/home/antu
Nicht ganz. Das Kennwort steht ja nicht in der Datenbank, sollte es jedenfalls nicht. ;)

  1. Benutzer gibt Name und Kennwort ein ($name, $kennwort).
  2. Du machst eine SQL-Abfrage um die Prüfsumme des Kennwortes vom Benutzer zu erfahren ($kennwort_pruefsumme).
    [src=mysql]SELECT kennwort_pruefsumme FROM benutzer WHERE benutzername = 'venom2k6'[/src]
  3. Du überprüfst mit password_verify, ob das eingegebene Kennwort zu der Prüfsumme aus der Datenbank passt.
    [src=php]if (password_verify($kennwort, $kennwort_pruefsumme))
    {
    // Kennwort stimmt, melde Benutzer an ...
    }
    else
    {
    // Kennwort stimmt nicht, zeige Fehlermeldung ...
    }[/src]

Die Prüfsumme erstellst du nur, wenn der Benutzer sein Kennwort ändert bzw. sich registriert.

also ein direktes abgleichen im SQL statement wird somit nicht mehr gemacht?
Korrekt.
 

drfuture

Zeitreisender
Teammitglied

Registriert
14 Juli 2013
Beiträge
8.754
Ort
in der Zukunft
Bei der Verwendung solch *neuer* Funktionen sollte man dann auch dran denken wo das script später laufen soll - php 5.5 ist nicht zwingend bei jedem Webhoster schon angekommen ....
 

venom2k6

NGBler

Registriert
15 Juli 2013
Beiträge
107
  • Thread Starter Thread Starter
  • #15
Nicht ganz. Das Kennwort steht ja nicht in der Datenbank, sollte es jedenfalls nicht. ;)
? das heißt absolut nicht mehr??? oder meinst du damit nicht im klartext? ^^ im Klartext habe ich dieses nie in der DB gespeichert früher immer md5 aber jetzt muss wirklich mal was neues her. wegen meiner abschlussprüfung im dezember und der vorbereitung davor habe ich ich viel verpasst und muss nun nachholen ^^ zum ende des 1. Quartals will ich die Homepage fertig haben. und ich schreib alles selbst. die jetzige HP ist auch komplett selbst erstellt. und bisher ist nix markantes passiert :)

[*]Du überprüfst mit password_verify, ob das eingegebene Kennwort zu der Prüfsumme aus der Datenbank passt.
[src=php]if (password_verify($kennwort, $kennwort_pruefsumme))
{
// Kennwort stimmt, melde Benutzer an ...
}
else
{
// Kennwort stimmt nicht, zeige Fehlermeldung ...
}[/src]
genau das wäre meine nächste frage gewesen ^^ :) du fuchs... :T
 
Zuletzt bearbeitet:

antu

NGBler

Registriert
11 Nov. 2013
Beiträge
396
Ort
/home/antu
Ich meinte nicht im Klartext. ;) In irgendeiner Art und Weise musst du das Kennwort ja speichern. :D
 

venom2k6

NGBler

Registriert
15 Juli 2013
Beiträge
107
  • Thread Starter Thread Starter
  • #17
gut, bei der If-abfrage

[src=php] if (password_verify($kennwort, $kennwort_pruefsumme))
{
// Kennwort stimmt, melde Benutzer an ...
}
else
{
// Kennwort stimmt nicht, zeige Fehlermeldung ...
}
[/src]

Gehe ich da mit recht der annahme davon aus, so wie ich es auf php.net verstanden habe, das die Variable $kennwort, das Kennwort in klartext ist welches durch die funktion password_verify() verhasht wird und mit dem hashwert aus der DB verglichen wird? ^^
 

accC

gesperrt

Registriert
14 Juli 2013
Beiträge
5.250
kann mysql mit den werten vernünftig arbeiten???

denn immerhin generiert er immer einen anderen Hashwert...
Das liegt am Salt. Wenn du einen anderen (zufälligen) Salt hast, bekommst du einen anderen Hash.
password_verify() bekommt zunächst das Passwort vom Nutzer und als zweiten Parameter den Hash aus der Datenbank.

Im Gegenteil: Das weglassen des abschließenden '?>' entspricht den gängigen best practices, siehe u.a. Zend Framework Coding Standard for PHP. Ein unbeabsichtigtes Leerzeichen nach dem closing tag kann sonst schnell zu der oben erwähnten headers already sent-Fehlermeldung führen und ist ggf. schwer auszumachen.
Was dann aber am Nutzer/ Betriebssystem/ der Entwicklungsumgebung liegt. Ich sehe es jetzt nicht unbedingt als schön an mit irgendwelchen hacks zu arbeiten.


[src=php]<?php
// Benutzerregistrierung / Passwort ändern
$UserPW = $_POST['password'];
$UserHash = password_hash($UserPW, PASSWORD_BCRYPT);
// speichere $UserHash in der Datenbank


// Login / Passwortabfrage
$UserPW = $_POST['password'];
// lade $UserHash aus der Datenbank
if(password_verify($UserPW, $UserHash)){
// Login erfolgreich
echo 'Geheime Information';
}else{
// Login fehlgeschlagen
echo 'Du darfst diese Information nicht sehen';
}
?>[/src]
 

antu

NGBler

Registriert
11 Nov. 2013
Beiträge
396
Ort
/home/antu
Gehe ich da mit recht der annahme davon aus, so wie ich es auf php.net verstanden habe, das die Variable $kennwort, das Kennwort in klartext ist welches durch die funktion password_verify() verhasht wird und mit dem hashwert aus der DB verglichen wird? ^^
Ja. Im von password_hash() erzeugten Hash sind auch die Informationen zum benutzten Algorithmus/Salz enthalten, password_verify() benutzt diese Informationen um aus dem Klartext-Kennwort den Hash zu berechnen und diesen dann mit dem gegebenen Hash (aus der Datenbank) zu vergleichen.

Was dann aber am Nutzer/ Betriebssystem/ der Entwicklungsumgebung liegt. Ich sehe es jetzt nicht unbedingt als schön an mit irgendwelchen hacks zu arbeiten.
Das ist kein Hack, sondern die in der offiziellen PHP-Dokumentation empfohlene Vorgehensweise. Man hat dann halt eine Fehlerquelle weniger. ;)
php.net schrieb:
If a file is pure PHP code, it is preferable to omit the PHP closing tag at the end of the file. This prevents accidental whitespace or new lines being added after the PHP closing tag, which may cause unwanted effects because PHP will start output buffering when there is no intention from the programmer to send any output at that point in the script.
 

accC

gesperrt

Registriert
14 Juli 2013
Beiträge
5.250
Willst du jetzt darüber reden, dass das eine kluge Designentscheidung ist? :confused:
 
Oben