| 

.NET C# Java Javascript Exception

2
Hallo, Ich habe ein kleines PHP Script geschrieben das einen Datensatz in einer Datenbank aktualisiert auf basis eines HTML-Forms. Es gibt keine Fehlermeldungen oder irgendwas. Nur werden die Daten nicht Aktualisiert.

Das HTML Form
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html" />
</head>

<body>
<form action="Einstellung_Submit.php" method="get" target="_self" enctype="text/plain">

<fieldset>
<label>Name:</label><input type="text" size="20" name="komponentenName" title="Name" required="true" /><br>

<label>Status:</label><input type="hidden" name="status" value="0" /><input type="checkbox" name="status" value="1" required="true" /><br>

<label>Zustand:</label><input type="number" name="zustand" min="0" max="100" value="0" required="true"><br>
<input type="submit" />
<input type="reset" />

</fieldset>
</form>
</body>

</html>


Dann das PHP Script

<?php

/**
* @author Chase
* @copyright 2014
*
*/

require('vars.php');

$KomponentName = $_GET['komponentenName'];

$Status = $_GET['status'];

$Zustand = $_GET['zustand'];

#Wenn der Zustand 0 (Zerstört) ist wird der Status auf Offline gesetzt
if ($Zustand == 0) {
$Status = 0;
}



$querry = "UPDATE ".$Tabelle." SET Status=".$Status.", Zustand=".$Zustand." WHERE KomponentName =".$KomponentName.";";


$res = mysqli_query($db, $querry); // Query ausführen.

if(!$res) {
die(mysql_error());
}

echo "Übertragung erfolgreich";

?>


und schließlich die vars.php

<?php

/**
* @author
* @copyright 2014
*/

#Name, Passwort und DB Name zensiert ;)
$db = mysqli_connect('localhost', 'name', 'passwort', 'someDB')OR die(mysql_error());

$Tabelle = 't_components';

?>
News:
26.07.2014
Chase 35 4
2 Antworten
1
Du baust zwar das SQL-Statement zusammen aber du sendest es nie zur Datenbank. Versuchs mal mit der Änderung:

$querry = "UPDATE ".$Tabelle." SET Status='".$Status."', Zustand='".$Zustand."' WHERE KomponentName='".$KomponentName."'";

$res = mysqli_query($db, $querry); // Query ausführen.

if(!$res) {
die(mysql_error());
}
26.07.2014
phg 1,6k 3
:facepalm:

ja... danke. Allerdings funktioniert es immer noch nicht wirklich
Chase 26.07.2014
1
Was mir eben noch aufgefallen ist, Strings in der Query müssen eigentlich in Hochkomma stehen. Vielleicht liegts daran.
Ansonsten müsstest du etwas genauer werden was nicht funktioniert
phg 26.07.2014
yay, jetzt klappt's :D
Danke ^^
Chase 26.07.2014
2
Hallo zusammen,
also wenn überhaupt so unsicher (du validierst deine Variablen überhaupt nicht, Stichwort SQL-Injection), dann würde ich mit sprintf() arbeiten, um eine bessere Übersichtlichkeit zu haben:
$querry = sprintf("UPDATE %s SET Status='%s', Zustand='%s' WHERE KomponentName='%s';", $Table, $Status, $Zustand, $KomponentName);


Aber grundsätzlich würde ich dir einen anderen Weg vorschlagen:

Konfiguration der Datenbank in einer ini Datei:
; Datenbank Config
[dbms_DeineDatenbank]
database.adapter = pdo_mysql
database.params.host = "DB-Host"
database.params.username = "DB-User"
database.params.password = "DB-PW"
database.params.dbname = "DB-Name"



mit dem Zend-Framework die Datenbank und Konfiguration ansprechen:
<?php
# Zend Autoloader laden
require_once 'Zend/Loader.php';
require_once 'Zend/Loader/Autoloader.php';
$obj_loader = Zend_Loader_Autoloader::getInstance();


# Config initialisieren
$obj_config =& new Zend_Config_Ini('config.ini', 'dbms_DeineDatenbank');
# Datenbank connection
$obj_db =& connectDb($obj_config);
$str_sql = sprintf("UPDATE %s SET Status=?, Zustand=? WHERE KomponentName=?;", $Table);
$arr_sqlParams = array($Status, $Zustand, $KomponentName);
# Query absetzen, dabei wird das '?' durch die Variable ersetzt. Prepaired Statement
$ref_stmt = $obj_db->query($str_sql, $arr_sqlParams );
while ($arr_row = $ref_stmt->fetch()) {
echo <deine Daten>;
}
exit();

/**
* Datenbank Connect oder abbruch
*
* @param object $obj_config Zend Config Objekt
* @return object
*/
function connectDb($obj_config) {
try {
$obj_db =& Zend_Db::factory($obj_config->database);
$obj_db->getConnection();
} catch (Zend_Db_Adapter_Exception $e) {
$str_messages = "HTTP/1.0 500 Internal Server Error - Database Error";
print $str_messages;
header($str_messages);
exit();
} catch (Zend_Exception $e) {
$str_messages = "HTTP/1.0 500 Internal Server Error - Database Error";
print $str_messages;
header($str_messages);
exit();
}
$obj_db->setFetchMode(Zend_Db::FETCH_ASSOC);
return $obj_db;
}

?>


Zur Zeit dürfte wohl Prepaired Statement die sicherste Art sein, eine Datenbank anzusprechen. Das ist auch mit mysqli möglich. (http://de1.php.net/manual/en/mysqli.prepare.php)

Alternative dazu könnte ich dir auch noch RedBean (http://redbeanphp.com/) empfehlen. Eine kleine selbstlernende Datenbank Klasse die dir die Arbeit deutlich leichter machen kann.

Gruß Jens

P.S. Ich würde auch, um Phishing zu verhindern, immer nur $_POST Variablen akzeptieren. $_GET ist da nicht so cool.
28.07.2014
XJenso 322 7
Danke für die ausführliche Antwort. Allerdings habe ich keine Möglichkeit die Datenbank groß zu konfigurieren auch ist ein großer Konfigurationsaufwand mit neuem Framework nicht das was ich brauche. Dafür ist das Projekt und die verwalteten daten nicht wichtig genug.

Den Vorschlag mit der Post methode werde ich einbauen. Obwohl niemand versuchen würde die Daten abzufangen und selbst wenn. Sie wären absolout wertlos.
Chase 28.07.2014
1
okay, ich hab mich blöd ausgedrückt. Die Konfiguration ist natürlich für das Zend-Config Objekt. Damit soll nicht die Datenbank konfiguriert werden. Könnte auch als Array übergeben werden.
Grundsätzlich möchte ich auch immer wieder nur sensibilisieren. Vielleicht sind die Daten ja wertlos. Wenn man den Server aber einmal gehackt hat, ist es nicht mehr weit böse Dinge damit zu tun. Hier liegt für mich die Gefahr. Spam- oder Dos-Attacken.
XJenso 28.07.2014
1
Ganz ehrlich, ich hab SQL-Injections als Grundwissen vorausgesetzt und darum war ich am Wochenende einfach zu Faul darauf näher einzugehen ;)
@Chase: Sollte das nicht zum Grundwissen gehören, befass dich bitte noch vor POST damit. (Ein anschauliches Angriffs-Szenario ist unter http://xkcd.com/327/ illustriert)
Statt prepared Statements kannst du auch http://php.net/manual/de/mysqli.real-escape-string.php verwenden, aber prepared Statements sind übersichtlicher.
phg 28.07.2014
1
@XJenso: Für den (von mit angenommenen) Anwendungsfall finde ich ein Framework etwas übertrieben, aber für den (anscheinend nötigen) Hinweis auf SQL-Injection... +1 für deine Antwort!

Was mich noch wirklich interessieren würde ist, wie POST (ohne weitere Techniken) vor Phishing schützt. Soweit ich weiß schützt POST vor versehentlich ausgelösten Aktionen z.B. durch Link-Prefetcher oder (einfach gestrickte) Bots aber vor Phishing? Kannst du da noch etwas näher drauf eingehen? Gerne auch in der Lounge oder so.
phg 28.07.2014
1
POST Parameter kannst du nicht so einfach in einen Link einbinden. Ich generiere einen Link mit den GET-Parametern und verteile diese per Email oder Foren => Fertig.

Phishing ist natürlich auch mit POST möglich, aber aufwendiger.

Validieren von Parametern ist IMMER Pflicht. Bei einem abgesendeten Formular (POST) kann ich vor dem parsen der Parameter den Request auswerten. Kommt der nicht von meiner Website wird er verworfen. Auch einmal Token die über ein Hidden Feld gesendet und im Backend ausgewertet werden sind eine gute Idee.

Keine weiter Technik nur Logik und Hirnschmalz.
XJenso 29.07.2014
1
@phg Framework übertrieben? Hier kann man 2 Meinungen haben.

Ich muss ja nicht das ganze Framework nutzen. Bei meinem Beispiel reichen 3 Module aus. (Autoloader, Config, DB). Ich könnte sogar noch auf den Autoloader verzichten. Schreibe ich mir noch eine kleine Wrapper Klasse komme ich nachher mit 2 Zeilen an die Daten und kann das immer wieder in meinen Projekten nutzen ohne großen Testaufwand.

Ich habe aber auch geschrieben, dass man mit PHP Boardmittel PrepairedStatement nutzen kann. Hier ist aus meiner Sicht aber die Fehleranfälligkeit höher und somit mehr Testaufwand.

Gruß Jens
XJenso 29.07.2014
Also ihr beiden,
Erstmal vielen dank für die Ausführlichen Antworten und Hilfen. Ich werde das mit den Prepared Statements überdenken.

Die Validierung der Daten muss ich mir mal anschauen. Wenn ich über Post gehe und filtere das man nur das vorgefertigte Formular nutzen kann wird die Validierung kein Problem mehr sein. Die wird mit vom Formular durchgeführt.

Ein Framework finde ich für das Projekt schlicht zu übertrieben. Schon diese 3 Module haben vermutlich mehr Quellcode als das Komplette Projekt ;)
Ja, mit SQL-Injections habe ich mich noch nicht beschäftigt.
Chase 29.07.2014
@XJenson Wegen POST: Jetzt kann ich dir Folgen, wir haben nur eine leicht unterschiedliche Ansicht. Für mich ist ein Token schon eine zusätzliche Technik (wenn auch eine simple) da der Token auch in einer Session gespeichert werden muss und die Token-Verwaltung implementiert werden will (außer man verwendet eh ein Framework, welches die Token-Verwaltung wegkapselt ;) ).

Deine Ansicht finde ich genau so richtig.
phg 29.07.2014
@XJenso Zum Framework: Ein Framework halte ich immer dann für etwas übertrieben, wenn eine sehr kleine Anwendung (z.B. nur ein Formular und eine Tabelle dahinter) gebaut werden soll und man sich dazu erst in ein Framework einarbeiten müsste oder wenn das Framework für diese Anwendung sehr viel mehr Ressourcen benötigt.

Wenn jemand für eine 1-Tabellen-App ein Framework verwendet das er eh schon kennt ist das natürlich etwas anderes. Solange das Framework nicht extrem viel Ballast im Hintergrund lädt ist es natürlich sinnvoll auch in dem Fall das Framework einzusetzen.
phg 29.07.2014

Stelle deine Php-Frage jetzt!