• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

Sessionvariable in Datenbank speichern

dudl313

New member
Hallo,

ich habe ein mehrseitiges Formular. Die Daten werden per Session von einer Seite zur nächsten übergeben. Am Endes soll dann alles in einer Db gespeichert werden. Dabei erscheint dann folgende Fehlermeldung:

Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING

PHP:
mysql_query("
	INSERT INTO test (feld1,feld2,feld3,feld4)
	VALUES ('$_SESSION['a1'], $_SESSION['a2'], $_SESSION['a3'], $_SESSION['a4'])");

Was mache ich falsch? Wenn ich anstelle der Sessionvariablen normale Variablen verwende, klappt es einwandfrei.

Danke
Dudl313
 
Ja, da hab ich als erstes auch schon dran gedacht und verschiedene Varianten ausprobiert, wie diese

PHP:
VALUES ('$_SESSION['a1']', '$_SESSION['a2']', '$_SESSION['a3']', '$_SESSION['a4']')");

oder diese

PHP:
VALUES ("$_SESSION['a1']", "$_SESSION['a2']", "$_SESSION['a3']", "$_SESSION['a4']")");

oder diese

PHP:
VALUES ('$_SESSION['a1']\', \'$_SESSION['a2']\', \'$_SESSION['a3']\', \'$_SESSION['a4']\')");

oder diese

PHP:
VALUES ('$_SESSION[\'a1\']', '$_SESSION[\'a2\']', '$_SESSION[\'a3\']', '$_SESSION[\'a4\']')");

Alle führen aber zu der oben genannten Fehlermeldung. Ich denke, daran kanns nicht liegen sondern ich hab da irgend einen anderen Fehler drin, den ich vor lauter Blindheit einfach nicht sehe :D

Im vorletzten Beispiel scheint ein Fehler bei den Anführungszeichen bei

...., \'$_SESSION['a4])") :confused:

zu bestehen, das ist aber in Wirklichkeit ein Fehler in der Darstellung des PHP Codes hier im Fenster. In Wirklichkeit sollte dort

...., \'$_SESSION['a4']\')")

erscheinen.


dudl313
 
PHP:
mysql_query("INSERT INTO test (feld1,feld2,feld3,feld4) VALUES ('" . $_SESSION['a1'] . "', " . $_SESSION['a2'] . ", " . $_SESSION['a3'] . ", " . $_SESSION['a4'] . ")");
 
Hmm, jetzt gibts zwar keine Fehlermeldung mehr, aber es wird auch nichts in die Db geschrieben. Trotzdem danke.
 
Hast du die Felder auch richtig eingestellt? Vllt. zu wenige Zeichen...

Was meinst du damit? :confused:

Also, wenn ich es so mache klappt alles wunderbar:
PHP:
mysql_query("INSERT INTO test (feld1,feld2,feld3,feld4) VALUES ('$var1', '$var2', '$var3', '$var4')");

Wenn ichs dagegen so mache kommt nix in der Db an:
PHP:
mysql_query("INSERT INTO test (feld1,feld2,feld3,feld4) VALUES ('" . $_SESSION['a1'] . "', " . $_SESSION['a2'] . ", " . $_SESSION['a3'] . ", " . $_SESSION['a4'] . ")");
 
Damit meine ich:
Du hast doch sicher eine Tabelle angelegt in phpmyadmin, mit verschiedenen Zeilen, in dem Fall: feld1, feld2, feld3 usw.
Diese Felder haben bestimmt alle den Typ Varchar - und es geht mir jetzt um die Länge der varchars, sie sind wahrscheinlich nicht lang genug für die Sessions...kann mich aber auch irren.
 
Die Länge habe ich bei allen Feldern auf 50 gesetzt. Sollte eigentlich lang genug sein, da ja sowiso nur ein paar sinnlose Zeichen zu Testzwecken rein geschrieben werden.
 
AAh, super. Das mit dem mysql_error() hat den Durchbruch gebracht. Da war doch ein Fehler mit den doppelten und einfachen Anführungszeichen. Und für alle, die das selbe Problem haben hier nun die funktionierende komplette Anweisung:

PHP:
mysql_query("INSERT INTO test (feld1,feld2,feld3,feld4) VALUES ('" . $_SESSION['a1'] . "', '" . $_SESSION['a2'] . "', '" . $_SESSION['a3'] . "', '" . $_SESSION['a4'] . "')");

Das ist aber auch ein Kreuz mit diesem Gemisch aus einfachen und doppelten Anführungszeichen. Und das war hier nur ein kleiner Test mit gerade mal 4 Feldern. Jetzt kann ich das Ganze auf ein Riesenformular mit über 160 Feldern anwenden. Das kann ja was werden - danach sehe ich keine Sterne sondern Anführungszeichen.

Vielen Dank
dudl313
 
Wenn deine Daten aus einem Formular kommen bist du aber überhaput nicht vor SQL-Injections geschützt...

PS: Bei so vielen Feldern würde ich das über ein Array der Feldernamen und eine for-Schleife machen...
 
Ja, da bin ich jetzt gerade dran. War heute den ganzen Tag am googeln und lesen über Gegenmaßnahmen zu diesem Thema und werde das morgen mal versuchen umzusetzten. Leider kenne ich mich mit SQL nicht wirklich gut aus. Und dann hab ich das Problem das ich nicht direkt sehen kann, ob Schutzmaßnahmen greifen oder nicht. Da ich mich, wie gesagt, mit SQL auch nicht so gut auskenne, kann ich auch die verschiedenen Möglichkeiten einer Injection nicht, oder nur unzureichend, an meiner eigenen Db testen.

Ich denke, daß ich diesbezüglich in den nächsten Tagen hier wieder mit Fragen auftauchen werde. Aber erst mal sehen, wie weit ich autodidaktisch komme.

P.S.: Das mit der Schleife hab ich schon umgesetzt. Bei 160 Feldern wird man sonst ja irre. :icon7:

dudl313
 
benutz die mysqli Erweiterung und prepared Statements. Das macht die Query einfacher und verhindert mysqli injection. Bei 160 Feldern würde ich auch mal überlegen ob die alle in eine Tabelle gehören, aber dazu müßte ich wissen wie die Daten n Beziehung stehen.
 
Hallo, da bin ich wieder. Also ich habe mir da was mit mysqli und prepared statments gebastelt. Da ich aber nicht sagen kann, ob das auch sicher ist, würde ich gerne eure geschätzte Meinung dazu einholen. Soll ich das hier posten, oder lieber ein neues Thema eröffnen? Was meint unser Mod dazu?

Na gut, ich werte das als "ja" und mache ein neues Thema auf. :)
 
Zuletzt bearbeitet:
SQL-Injection

Hallo,

ich habe ein mehrseitiges Formular, wo die Daten per Session von einer Seite zur nächsten übergeben werden und am Ende alles in einer Db gespeichert wird.
Auf jeder Seite des Formulars werden die Daten per $_POST an ein Script übergeben, welches zuerst eine Plausibilitätsprüfung durchführt (nur bei den Textfeldern) und anschließend die Daten in Sessionvariablen ablegt.
Die Datenbankzugriffe habe ich mit mysqli und prepared statements gemacht. Leider bin ich jedoch werde in mysql noch mit mysqli wirklich fit, so daß ich nicht sagen kann, ob das was ich da zusammengeschustert habe auch wirklich sicher ist. Zum anderen, da ich wie gesagt in SQL nicht so der Held bin, weiß auch gar nicht richtig, was mit SQL-Injections alles Möglich ist und erst recht nicht wie das geht - also, wie soll ich Angriffe abwehren und mich gegen Techniken schützen, die ich selber nicht beherrsche.
Lange Rede, kurzer Sinn: ich bitte euch, euch mal den folgenden Code anzuschauen (ist nur ein kurzes Testscript) und mit dann zu sagen, ob der Code sicher ist, bzw. was ich besser oder anders machen müßte um die Db gegen SQL-Injections zu schützen.

PHP:
<?php
session_start();

$_SESSION['a1']='dddd';
$_SESSION['a2']='ssssssssss';
$_SESSION['a3']='ffffffff';
$_SESSION['a4']='ggggggggg';

// Maskierende Slashes aus SESSION Array entfernen
if (get_magic_quotes_gpc()) { $_SESSION = array_map( 'stripslashes', $_SESSION ); }

// Neues Datenbank-Objekt erzeugen
$db = @new mysqli( 'localhost', 'root', '', 'testdb' );

// Pruefen ob die Datenbankverbindung hergestellt werden konnte
if (mysqli_connect_errno() == 0)
{
   $sql = 'INSERT INTO tabelle (a1,a2,a3,a4) VALUES (?,?,?,?)';
   $entry = $db->prepare( $sql );
   $entry->bind_param( 'ssss', $_SESSION['a1'], $_SESSION['a2'], $_SESSION['a3'], $_SESSION['a4']);
   $entry->execute();
}
else
{
   // Fehlermeldung wenn Db Verbindung nicht erfolgreich
   echo 'Datenbankverbindung fehlgeschlagen.<br>' .mysqli_connect_errno(). ' : ' .mysqli_connect_error();

}
// Datenbankverbindung schliessen
$db->close();

session_unset();
$_SESSION=array();

?>

So, ich sag schon mal danke an alle
dudl313
 
Also mit Prepared Statements kann man SQL Injections verhindern, somit können Eltern ihre little Bobby Tables wieder in Deine Datenbank eintragen, ohne dass diese kompromitiert wird.
Allerdings hilft das nicht gegen die Eingabe von <script>alert("Ich bin ein echter Gangster!");</script> in Deinen Textfeldern, wenn Du diesen Text ungefiltert oder unbehandelt wieder als HTML Code ausgibst.

Außerdem ist Dein Datenbankentwurf mit Sicherheit suboptimal. 160 Felder in einer einzigen Tabelle lassen nichts gutes ahnen.

Und: Threads zusammengeführt
 
Ich sehe, meine Beschreibung oben war nicht ganz vollständig. Als erstes, noch vor der
Plausibilitätsprüfung werden die meisten Sonderzeichen aus dem $_POST Array entfernt. Das mache ich
so:

PHP:
// Verbotene Zeichen 
$pattern = '!(<|>|:|;|,|;|_|=|#|&|\$|\*|\?|\\\|\{|\}|\[|\]|\(|\))!'; 

// ersetzten durch
$replace = ' ';

//Alle verbotenen Zeichen aus allen $_POST Feldern ersetzten
for ($x = 0; $x < sizeof($_POST); ++$x)
{
	$_POST[$errorFields[$x]] = preg_replace($pattern, $replace, $_POST[$errorFields[$x]]);
}

Damit sollten eigentlich auch Scriptcodes in den Textfeldern entschärft sein. Dann kommt die Plausi,
danach kommt der Inhalt in die Sessionvariable.

Nun noch etwas zur Db und den vielen Feldern: Darauf habe ich keinen Einfluss. Ein Kunde will, dass
ich einen komplexen Fragenkatalog, der zur Zeit nur in gedruckter Form vorliegt, exakt 1 zu 1 als
Online-Formular umsetzte und für jedes Feld im Formular auch ein Feld in der Db existiert. Ich habe
diesbezüglich auch schon stundenlange, erfolglose Telefonate geführt. Also ich sag mir da: 'des
Menschen Wille ist sein Himmelreich' und schließlich muß ich damit später nicht arbeiten.

Wichtig ist jedoch, dass das Ganze gut abgesichert ist und in die Db kein, wie auch immer gearteter,
Fremdcode eingeschleust werden kann. Daher auch meine Bitte an euch mir zu sagen, ob der oben
abgebildete Code sicher ist.

Danke
dudl313
 
Sieht jetzt nicht schlecht aus - ich würde ja die Sonderzeichen nicht löschen, sondern einmal durch htmlentities laufen lassen... dann wird einfach 1zu1 das ausgegeben, was der Befrage eingegeben hat.
 
Na, da bin ich aber erleichtert. Eine Frage habe ich trotzdem noch. Und zwar habe ich Probleme damit, in den mysqli Anweisungen Variablen anstatt von Literealen zu verwenden. Beispiel:

PHP:
$sql = 'INSERT INTO tabelle (a1,a2,a3,a4) VALUES (?,?,?,?)';

Das klappt. Aber

PHP:
$fieldString = "a1,a2,a3,a4";
$valueString = "?,?,?,?";
$sessionString = "$_SESSION['a1'], $_SESSION['a2'], $_SESSION['a3'], $_SESSION['a4']";

$sql = 'INSERT INTO tabelle ($fieldString) VALUES ($valueString)'; 
$entry = $db->prepare( $sql );
$entry->bind_param( 'ssss', $sessionString);
$entry->execute();
}

klappt nicht.
Bei normalen sql Anweisungen hatte ich damit keine Probleme, anscheinend müssen bei mysqli die Variablennamen irgendwie anders behandelt werden. Aber wie?
 
Zurück
Oben