XHTMLforum

XHTMLforum (http://xhtmlforum.de/index.php)
-   Serveradministration und serverseitige Scripte (http://xhtmlforum.de/forumdisplay.php?f=80)
-   -   $var = $_POST['stuff'] ist immer leer, var_dump[$_POST] nicht (http://xhtmlforum.de/showthread.php?t=69877)

NicknameMk2 21.08.2013 17:50

$var = $_POST['stuff'] ist immer leer, var_dump[$_POST] nicht
 
Hey, ich hab ein Problem bei der Übergabe von Daten mit POST.

Folgende Gegebenheiten:

Mit var_dump sehe ich die übergebenen Daten. Exakt, wie sie sein sollten.

Wenn ich dann aber die die Variablen aufrufe, in denen die Daten von dem POST Aufruf gespeichert werden sollten, sind diese leer.

Wenn noch Fragen offen sind, beantworte ich die gern.

Bis dahin schonmal danke!

explanator 21.08.2013 18:56

Kannst mal ein wenig Code zur Verfügung stellen, sonst weiss man ja gar nicht von was du sprichst.
Bitte rücke den Code entsprechend ein und verwende die PHP-Tags aus dem Edtitor zum Code einfügen.

NicknameMk2 21.08.2013 20:15

Ok! Ich hab's rausgefunden... :D

Mit $_Post gehts nich,... ABER mit $_POST! Wer hätte das gedacht? Danke trotzdem.



PHP-Code:

<?php
error_reporting
(0);
$uMail $_Post['umail'];
$uPw $_Post['upw'];
//echo "umail ".$_Post['umail'];
//var_dump($_POST);
var_dump($_REQUEST);
$db = new PDO('mysql:host=localhost;dbname=DB;charset=utf8''USER''PASSWORT');
//echo "upw ".$uPw;
$result $db->query("select email, pw from users where email='$uMail' and pw ='$uPw'");
//$result = $db->query("select count(*) from users");
//echo "select email, pw from users where email='$uMail' and pw ='$uPw'";
if($result->fetch(PDO::FETCH_ASSOC)) {
    
//echo "1";
}
else{
     
//echo "0";    
}

//echo "select email, pw from users where email=".$uMail." and pw =".$uPw;
//echo var_dump($uMail);
?>


Das ganze bekommt die 2 Variablen über eine Android app. Wie schon gesagt, seh ich mit var_dump den gesendet Inhalt und der stimmt auch. Nur sind $uMail und $uPW dann leer, wenn ich sie ausgebe oder sonstwas damit tue.

explanator 21.08.2013 20:48

1. Es heistt $_POST und nicht $_Post
2. Du brauchst die Variablen nicht umzukopieren. du kannst das $_POST Array auch in der SQL-Abfrage verwenden.
3. In SQL Abfragen Schlüsselwörter gross schreiben, wegen der Übersichtlichkeit und auf mehrere Zeilen verteilen.
4. Gewöhne dir an lesbaren Code zu schreiben.
5. Parameter sollten man nicht ungeprüft übernehmen. Dein Code ist anfällig für SQL-Injections.
6. Dein Error-Reporting (E_ALL) solltest du einschalten, während der Entwicklungsphase
7. Aufgrund des Kontextwechsels kannst du PHP-Variablen nicht direkt in SQL-Abfragen nutzen:
Das hier:
PHP-Code:

 where email='$uMail' 

funktioniert nicht, weil nach dem String $uMail gesucht wird und nicht nach der Variablen.
Du musst die Stringverkettung anwenden.

sauberer Code sieht so aus:
PHP-Code:

 
$result 
$db->query("
SELECT email, pw 
FROM users 
WHERE email = ' . 
$uMail . ' AND pw = ' . $uPw . '
"
); 


NicknameMk2 21.08.2013 20:53

Ok, ich werds noch etwas umschreiben. Danke vielmals. Bin erst seit n paar Tagen in dem Thema drin. Ist alles noch ein wenig verwirrend :D

Pr0g 22.08.2013 02:52

Zitat:

Zitat von explanator (Beitrag 532356)
sauberer Code sieht so aus:
PHP-Code:

 
$result 
$db->query("
SELECT email, pw 
FROM users 
WHERE email = ' . 
$uMail . ' AND pw = ' . $uPw . '
"
); 


Hier mischt du die Anführungszeichen etwas. Entweder die Punkte um die Variablen noch entfernen oder
PHP-Code:

 
$result 
$db->query('
SELECT email, pw 
FROM users 
WHERE email = "' 
$uMail '" AND pw = "' $uPw '"
'
); 

... speichert hier jemand Klartextpasswörter :P

lottikarotti 27.08.2013 14:23

Hallo,

Zitat:

Zitat von explanator (Beitrag 532356)
2. Du brauchst die Variablen nicht umzukopieren. du kannst das $_POST Array auch in der SQL-Abfrage verwenden.

Dies verschlechtert allerdings nicht nur die Lesbarkeit des Codes, sondern stellt auch noch ein Sicherheitsrisiko dar. Ich persönlich bevorzuge bei der Verarbeitung von Benutzereingaben eine klare Struktur:

- Parameter aus $_POST/ $_GET extrahieren
- Parameter auf Existenz prüfen
- Parameter validieren
- Parameter verarbeiten

Zitat:

Zitat von explanator (Beitrag 532356)
3. In SQL Abfragen Schlüsselwörter gross schreiben, wegen der Übersichtlichkeit und auf mehrere Zeilen verteilen.

Ich denke das ist Geschmackssache. Gerade bei einem so "kurzen" Statement, kann man die Abfrage ruhig in einer Zeile stehen lassen.

Zitat:

Zitat von explanator (Beitrag 532356)
5. Parameter sollten man nicht ungeprüft übernehmen. Dein Code ist anfällig für SQL-Injections.

Nicht nur das. Es ist empfehlenswert hier auf Prepared-Statements zu setzen um die Sicherheitsrisiken zu verringern.

Zitat:

Zitat von explanator (Beitrag 532356)
7. Aufgrund des Kontextwechsels kannst du PHP-Variablen nicht direkt in SQL-Abfragen nutzen:
Das hier:
PHP-Code:

 where email='$uMail' 

funktioniert nicht, weil nach dem String $uMail gesucht wird und nicht nach der Variablen.
Du musst die Stringverkettung anwenden.

Das stimmt so nicht ganz. Wenn eine Zeichenkette in Anführungszeichen umschlossen ist, werden alle sich darin befindlichen Variablen vom PHP-Interpreter aufgelöst. Nur wenn eine Zeichenketten in einfache Anführungszeichen umschlossen wird, muss der Vereinigungs-Operator verwendet werden. Ein Beispiel:

PHP-Code:

// Eine beliebige Variable
$username 'lottikarotti' ;

// Anführungszeichen -> funktioniert!
echo "Herzlich willkommen, $username! -- " ;
echo 
"Herzlich willkommen, \"$username\"! -- " ;
echo 
"Herzlich willkommen, '$username'! -- " ;

// Einfache Anführungszeichen kombiniert mit
// dem Vereinigungs-Operator -> funktioniert!
echo 'Herzlich willkommen, ' $username '! -- ' ;

// Einfache Anführungszeichen ohne
// den Vereinigungs-Operator -> funktioniert nicht!
echo 'Herzlich willkommen, $username! -- ' 

Man achte insbesondere darauf, welche Anführungszeichen verwendet werden. Insofern hat NicknameMk2 zumindest das richtig gemacht.

Zitat:

Zitat von explanator (Beitrag 532356)
sauberer Code sieht so aus:
PHP-Code:

$result $db->query("
SELECT email, pw 
FROM users 
WHERE email = ' . 
$uMail . ' AND pw = ' . $uPw . '
"
); 


Dieser Code ist fehlerhaft, da die Zeichenkette in Anführungszeichen umschlossen wurde. Das führt dazu, dass die einfachen Anführungszeichen und der Vereinigungs-Operator (welche du innerhalb der Zeichenkette platziert hast) Teil der Zeichenkette sind.

In meinen Augen sollte eine saubere und funktionsfähige Umsetzung der gesamten Problemstellung in etwa so aussehen:

PHP-Code:

/** Konfiguration */
define'SQL_DATASOURCE''' ) ;
define'SQL_USERNAME''' ) ;
define'SQL_PASSWORD''' ) ;


/** Logik */
try {

    
/** Variablen ermitteln */
    
$method $_GET ;
    
$username = isset( $method'username' ] ) ? $method'username' ] : null ;
    
$password = isset( $method'password' ] ) ? $method'password' ] : null ;

    
/** Prüfen ob die Variablen gesetzt wurden */
    
if( $username === null || $password === null ) {
        throw new 
Exception'Benutzername und Kennwort müssen übergeben werden.' ) ;
    }

    
/** Werte der Variablen validieren */
    
if( ! ctype_alnum$username ) || ! ctype_alnum$password ) ) {
        throw new 
Exception'Benutzername und Kennwort müssen alphanumerisch sein.' ) ;
    }

    
/** Datenbankverbindung herstellen */
    
$pdo = new PDOSQL_DATASOURCESQL_USERNAMESQL_PASSWORD ) ;
    
$pdo->setAttributePDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION ) ;

    
/** SQL-Statement vorbereiten */
    
$sql 'SELECT username, password FROM users WHERE username = ? LIMIT 1' ;
    
$stm $pdo->prepare$sql ) ;

    
/** SQL-Statement ausführen */
    
$stm->execute( [ $username ] ) ;
    
$res $stm->fetchPDO::FETCH_ASSOC ) ;

    
/** Authentifizierung prüfen */
    
$auth $res && hash'sha256'$password ) === $res'password' ] ;
    if( 
$auth ) {
        echo 
'Willkommen ' $username ;
    } else {
        echo 
'Anmeldung für ' $username ' fehlgeschlagen.' ;
    }

} catch( 
Exception $e ) {
    echo 
'Fehler: ' $e->getMessage( ) ;


Viele Grüße,
lotti

mymaksimus 28.08.2013 02:20

Zitat:

Zitat von lottikarotti (Beitrag 532574)
Hallo,
Dies verschlechtert allerdings nicht nur die Lesbarkeit des Codes, sondern stellt auch noch ein Sicherheitsrisiko dar.

In diesem fall wird die lesbarkeit eher nicht beintraechtigt, das ist an der stelle eher geschmackssache. Ich finde zum beispiel das man bei der direkten benutzung der post variable sofort erkennen kann worum es sich handelt, und das so lesbarer ist. Und das ganze erhoeht definitv nicht das sucherheits risiko, denn wenn man die variablen vorher prueft kommt es aufs selbe hinaus.

lottikarotti 28.08.2013 10:58

Morgen,

Zitat:

Zitat von mymaksimus (Beitrag 532624)
In diesem fall wird die lesbarkeit eher nicht beintraechtigt, das ist an der stelle eher geschmackssache. Ich finde zum beispiel das man bei der direkten benutzung der post variable sofort erkennen kann worum es sich handelt, und das so lesbarer ist.

Das mag in diesem Fall so sein, da es sich nur um eine Variable handelt - nämlich dem Benutzername. Wenn man es sich aber angewöhnt, $_POST oder $_GET Variablen immer direkt zu verwenden, wird das bei komplexeren Problemstellungen schnell unübersichtlich. Gerade im Hinblick auf die Validierung geht da in der Eile schnell mal etwas unter. Das verursacht nicht nur minderwertigen Code, sondern fördert auch Sicherheitsrisiken.

Zitat:

Zitat von mymaksimus (Beitrag 532624)
Und das ganze erhoeht definitv nicht das sucherheits risiko, denn wenn man die variablen vorher prueft kommt es aufs selbe hinaus.

Sicherheitsrisiken gibt es natürlich nicht, wenn der Entwickler keine Fehler macht. Davon sollte man aber nicht pauschal ausgehen. Schnell ist ein SQL-Statement mal um einen Parameter erweitert und in der Eile hat man die Validierung komplett vergessen - mögliche SQL-Injections sind die Folge. Deshalb sollte man bei Daten die von extern kommen immer einen festen Ablauf einhalten:

- Variablen auf Existenz/ prüfen und extrahieren
- Variablen validieren

Wenn man diesen Ablauf befolgt kann man sich später relativ sicher sein, dass die Variable "$username" sauber ist. Bei einem $_POST['username'] im Code muss ich - wenn ich zwei Wochen später in den Code schaue - mir erstmal die Frage stellen: habe ich die auch validiert?

Wie ein Entwickler die Dinge letztlich löst bleibt allerdings seine eigene Entscheidung. Wer vorsichtig ist, der kriegt's auch anders hin. Ich bevorzuge klare Strukturen im Code, da sich weitere Team-Mitglieder dann besser und schneller in meinem Code zurechtfinden.

Viele Grüße,
lotti

explanator 28.08.2013 12:32

Um SQL-Injections zu verhindern sollte der Contextwechsel beachtet werden und mysql_real_escape_string() angewendet werden.

Weiteres dazu findet sich im Handbuch :>PHP: SQL Injection - Manual

Das Umkopieren der übergebenen Variablen wird zwar oft gesehen, ist aber eigentlich nicht notwendig. Eine Variable bleibt eine Variable auch wenn sie durch umkopieren anders benannt wird.

Es bleibt dem Programmierer überlassen ob er das macht oder nicht, es ging hier lediglich um die Notwendigkeit und die ist nicht gegeben.

Das man SQL-Abfragen, auch wenn sie kurz sind, nicht in einer Zeile stehen lässt hat nichts mit der Übersichtlichkeit zu tun, sondern vielmehr damit, dass bei einem Fehler einem dann die Zeile angezeigt wird in der der Fehler auftrat.
Je weniger man splittet, desto mehr muss man selber suchen.

Prepared Statesment sind nicht der Weisheit letzter Schluss, sie können um einiges langsamer sein und vermeiden SQL-Injections nicht.
In diesem gezeigten Fall, Abfrage der Useremail in Verbindung mit Passwort sind sie sogar kontraproduktiv, das sie das Caching des Abfragestrings auf Datenbankseite verhindern.
Siehe dazu das Mysql-Handbuch.unter MySQL :: MySQL 5.1 Referenzhandbuch :: 5.14 MySQL-Anfragen-Cache

lottikarotti 28.08.2013 13:13

Morgen,

Zitat:

Zitat von explanator (Beitrag 532656)
Um SQL-Injections zu verhindern sollte der Contextwechsel beachtet werden und mysql_real_escape_string() angewendet werden.

Dies ist nicht weiter nötig, wenn man mit Prepared Statements arbeitet.
Zitat:

(...) and helps to prevent SQL injection attacks by eliminating the need to manually quote the parameters.
Zitat:

Zitat von explanator (Beitrag 532656)
Das Umkopieren der übergebenen Variablen wird zwar oft gesehen, ist aber eigentlich nicht notwendig. Eine Variable bleibt eine Variable auch wenn sie durch umkopieren anders benannt wird.

Es geht mir weniger um das "Umkopieren" an sich, als um die Tatsache, dass es Konzepte und klare Strukturen braucht, wenn man qualitativ hochwertige Software entwickeln möchte. Wie diese Konzepte aussehen, spielt dabei keine große Rolle. Bei mir lautet das Konzept: externe Daten niemals direkt in den Verarbeitungsprozess einzubeziehen.

Zitat:

Zitat von explanator (Beitrag 532656)
Es bleibt dem Programmierer überlassen ob er das macht oder nicht, es ging hier lediglich um die Notwendigkeit und die ist nicht gegeben.

Aus meiner Sicht ist aber eine Sache klar: Entwickler die keinen klaren Strukturen folgen, machen früher oder später fatale Fehler. Im schlimmsten Fall treten diese erst beim Kunden auf.

Zitat:

Zitat von explanator (Beitrag 532656)
Das man SQL-Abfragen, auch wenn sie kurz sind, nicht in einer Zeile stehen lässt hat nichts mit der Übersichtlichkeit zu tun, sondern vielmehr damit, dass bei einem Fehler einem dann die Zeile angezeigt wird in der der Fehler auftrat.
Je weniger man splittet, desto mehr muss man selber suchen.

Grundsätzlich stimme ich dir hier natürlich zu, auch wenn sich das bei der betroffenen Zeile weitestgehend ignorieren lässt, da dort nur eine Zeichenkette zugewiesen wird:
PHP-Code:

$sql 'SELECT username, password FROM users WHERE username = ? LIMIT 1' 

Zitat:

Zitat von explanator (Beitrag 532656)
Prepared Statesment sind nicht der Weisheit letzter Schluss, sie können um einiges langsamer sein

Die Performance ist natürlich ein anderes Thema. Hier muss man von Fall zu Fall abwägen und sich für die effizienteste Lösung entscheiden.

Zitat:

Zitat von explanator (Beitrag 532656)
und vermeiden SQL-Injections nicht.

Doch, genau das tun sie und das liegt bereits in der Fuktionsweise von Prepared Statements begründet. Dies ist nicht zu Verwechseln mit dem plumpen zusammenbasteln eines SQL-Statements mittels Vereinigungs-Operator.

Zitat:

Zitat von explanator (Beitrag 532656)
In diesem gezeigten Fall, Abfrage der Useremail in Verbindung mit Passwort sind sie sogar kontraproduktiv, das sie das Caching des Abfragestrings auf Datenbankseite verhindern.

Da die Anmeldung an einem System kein massiv genutzter Prozess ist, sollte das in diesem Fall keine große Rolle spielen. Wenn dieser Teil der Anwendung allerdings als performance-kritisch betrachtet wird, sollte man natürlich nach der effizientesten Lösung suchen.

Viele Grüße,
lotti


Alle Zeitangaben in WEZ +2. Es ist jetzt 08:51 Uhr.

Powered by vBulletin® Version 3.8.11 (Deutsch)
Copyright ©2000 - 2024, vBulletin Solutions, Inc.

© Dirk H. 2003 - 2023