SQL Injection Diskussion zu "MySQL Rückgabewert inkorrekt"

Ich möchte mit meinen eigenen Augen sehen, dass jemand meine Querys manipulieren kann, egal wie...
(was mit der Onlineversion regulär nicht funktioniert)
Das scheint eine serverseitige Sperre mit einer mir unbekannten Bedingung zu sein.
Das sind relativ unfaire Bedingungen, um eine SQL-Injection zu demonstrieren. Wenn du gar keinen Zugang zur Datenbank erlaubst, kann man natürlich nichts injecten. Insofern ist das dann trivial "sicher".
Es gibt aber ja auch andere Zugänge zur Datenbank, z.B. über die Datumsabfrage. Wenn da der Sourcecode verfügbar wäre, könnte man vielleicht etwas basteln.
@tklustig Magst du den Code von dataTime.php und dataAll.php hier veröffentlichen? Oder sind diese Elemente Injection-safe?
Ja, das ist ein Shortcut, aber wir haben ja auch keine kriminelle Energie, sondern wollen ein Beispiel aufzeigen. Und ich mag solche Challenges durchaus :)

Ansonsten schliesse ich mich meinen Vorrednern an: Das Internet ist böse. Hast du mal in deine /var/log/apache2/access.log geschaut? Und jetzt schau mal bei abuseipdb nach, woher diese IPs kommen.
Dazu eine ernste Warnung: phpmyadmin gehört nicht ans Netz. Wenn dein Passwort nicht stark ist, hat man damit vollen Zugriff auf deine Datenbanken, und muss sich nicht mit Injections herumschlagen. Deine Version ist immerhin modern, was das Risiko einer Sicherheitslücke senkt.
Du scheinst einen Router mit NAT vor den Pi zu schalten und einfach den Port weiterzuleiten. Das ist schon mal gut, um anderen Einfallswegen vorzubeugen.

Gruss
cwriter
 
Injection-safe ist momentan noch gar nix. Selbstverständlich werde ich den Code veröffentlichen. Wenn es jemand gelingt, in mein System einzudringen, nur zu....Allerdings gebe ich zu Bedenken, dass ein 'normaler' Angreifer nicht über diese Infos verfügt! Der sieht letztlich nur die Anwendung, keinen Code!
P.S.: phpmyadmin werde ich demnächst online nicht mehr zur Verfügung stellen, da gehe ich mit Dir konform:sneaky:. phpinfo() bleibt!
Hier der Code von dataAll.php(die Zugriffsparameter im Konstruktor habe ich natürlich abgeändert...)
PHP:
<!Doctype html> <!-- Definition des doctype-Modus -->
<html> <!-- Definition des Stammverzeichnises -->
    <head> <!-- Definition des Kopfbereiches -->
        <meta charset="utf-8"><!-- charset[utf-8:]  definiert den deutschen Zeichensatz -->
        <meta name="msvalidate.01" content="8B12875037645A4090EE64488042FDA9" /><!--validiert die Website für Bing und Yahoo-->
        <meta name="date" content="2019-05-19T08:49:37+02:00">        <!-- Angaben, wann die Seite publiziert wurde-->
        <meta name="keywords" content="Temperatur, Analyse, Graphics">    <!-- versorgt die Spider der Suchmaschinen mit Informationen zwecks Suchbegriffen -->
        <meta name="description" content="Eine Auswertung der Datenbankdaten / Pi-Temperatursensor">    <!-- Beschreibung, die in den Suchmaschinen erscheinen soll. -->
        <meta name="robots" content="index,follow">            <!-- Links sollen mitindiziert werden //NOINDEX:Seite soll nicht aufgenommen werden//NOFOLLOW Links werden nicht verfolgt-->
        <meta name="audience" content="alle">                <!-- definiert die Zielgruppe der Website  -->
        <meta name="page-topic" content="Hobby">        <!-- Zuordnungsdefinition für die Suchmaschine -->
        <meta name="revisit-after" CONTENT="7 days">            <!-- definiert den erneuten Besuch des Spiders//hier:nach sieben Tagen  -->
        <title lang="de">Temperatur Analyse</title>     <!-- weist dem HTML-Dokument in der Registerkarte einen Namen zu -->    
        <!-- Online JQuery Bibliotheken. Werden zwar nicht benötigt, können aber auch nicht schaden... -->
        <script src="js/menus.js"></script>
        <script src="js/datetime.js"></script>
        <script src="js/Alert.js"></script>
        <script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="crossorigin="anonymous"></script>
        <link href="css/style.css" rel="stylesheet">
    </head>

    <body> <!-- Definition des Bodybereiches -->
        <div class="mainDiv">
            <div id="uhr"></div>
        </div>
        <ul>
            <li class="dropdown">
                <a href="javascript:void(0)" class="treffer_0" onclick="myFunction_0()">Home</a>
                <div class="dropdown-inhalt_0" id="auswahl_0">
                    <a href="info.php">PHP-Info</a>
                    <a href="javascript:impressum()">Impressum</a>
                    <a href="index.php">Startseite</a>
                </div>
            </li>
            <li class="dropdown">
                <a href="javascript:void(0)" class="treffer_0" onclick="myFunction_1()">Daten abrufen</a>
                <div class="dropdown-inhalt_0" id="auswahl_1">
                    <a href="showGraphics.php">Grafik erstellen</a>
                    <a href="dataTime.php">bestimmte Daten abrufen </a>
                </div>
            </li>
            <li class="dropdown">
                <a href="javascript:void(0)" class="treffer_0" onclick="myFunction_2()">Adminbereich</a>
                <div class="dropdown-inhalt_0" id="auswahl_2">
                    <a href="dataDelete.php">Daten löschen</a>
                    <a href="dataRemove.php">Duplikate entfernen</a>
                    <a href="index.php">Startseite</a>
                </div>
            </li>
        </ul>
        <script>
            function impressum() {
                alert("Programmierer &  V.i.S.d.P: Thomas Kipp\nAnschrift:\nKlein - Buchholzer - Kirchweg 25\n30659 Hannover\nMobil:0152/37389041");
            }
        </script>
    <center><h2>Daten ohne Filter</h2></center>
    <p>Diese Seite zeigt zunächst die ersten 50 Records ab erster Aufzeichnung an. Nach Betätigung des SubmitButtons werden die nächsten Records angezeigt. Die Id hat Vorrang!</p>
    <form action="<?= htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">
        <center>
            <div id="dropdown">
                <?php
                require_once 'inc/anzeigen.php';
                echo auswahlStep(48, 48, 1500);
                ?>
            </div>
            <div id="textbox1">
                <?php
                require_once 'inc/autoloader.php';
                spl_autoload_register('classAutoloader');
                $DatabaseObject = new MySQLClass('2BeHacked', '2BeHacked', 'mysql', '127.0.0.1', '2BeHacked');
                $connection = $DatabaseObject->Verbinden();
                if (!$connection) {
                    print_r("MySQL-Aufbau ist gescheitert!<br>");
                    die();
                }
                $sql = "SELECT max(id) AS max FROM temperaturs";
                $query1 = $DatabaseObject->Abfragen($connection, $sql);
                if (is_array($query1))
                    $maxId = $query1[0]['max'];
                else {
                    print_r('!!Error!!<br>Datenbankfehler. Abbruch!');
                    foreach ($connection->errorInfo() as $item) {
                        print_r('<br>' . $item);
                    }
                    die();
                }
                ?>
                <label>Ab Id:</label>
                <input type="text" name="startId" size="30" maxlength="30" placeholder="maximal bis zu ID: <?= $maxId ?>">
            </div>
            <div id="submitDropDown">
                <label>Abfeuern!</label>
                <input class="button3" type="submit" name="submit0" value="Submit">
            </div>
            <div>
                <input type="radio" name="rad" id="dummy1" value="frontOf">vor
                <input type="radio" name="rad" id="dummy2" value="back">zurück
            </div>
            <br>
        </center>
    </form>
    <script>
        function saveContents() {
            var rbIsClicked = $("input[type='radio'][name='rad']:checked");
            if (rbIsClicked.length != 0)
                localStorage['rbIsClicked'] = rbIsClicked.attr("id");
        }
        function restoreContents() {
            var rbIsClicked = localStorage['rbIsClicked'];
            if (rbIsClicked != undefined) {
                $('#' + rbIsClicked).attr('checked', true);
            }
        }
        $("input[type='radio'][name='rad']").on("change", saveContents);
        restoreContents();
    </script>
    <?php
    $folder = getcwd();
    $datei = $folder . '/txt/dropDownID.txt';
    require_once 'inc/autoloader.php';
    spl_autoload_register('classAutoloader');
    $DatabaseObject = new MySQLClass('2BeHacked', '2BeHacked', 'mysql', '127.0.0.1', '2BeHacked');
    $connection = $DatabaseObject->Verbinden();
    if (!$connection) {
        print_r("MySQL-Aufbau ist gescheitert!<br>");
        die();
    }
    $sql = "SELECT max(id) AS max FROM temperaturs";
    $query1 = $DatabaseObject->Abfragen($connection, $sql);
    if (is_array($query1))
        $maxId = $query1[0]['max'];
    else {
        print_r('!!Error!!<br>Datenbankfehler. Abbruch!');
        foreach ($connection->errorInfo() as $item) {
            print_r('<br>' . $item);
        }
        die();
    }
    if (!empty($_REQUEST['submit0'])) {
        if (!empty($_REQUEST['startId'])) {
            $id = $_REQUEST['startId'];
            if (!is_numeric($id)) {
                ?>
                <script>
                    var alertWidth = 250;
                    var alertHeight = 200;
                    var xAlertStart = 650;
                    var yAlertStart = 200;
                    var alertTitle = "<p class='pTitle'><b>! Warnung !</b></p>";
                    var alertText = "<p class='pAlert'>Nur Zahlen werden bzgl. der Primärschlüsselabfrage akzeptiert!</p>";
                    showAlert(alertWidth, alertHeight, xAlertStart, yAlertStart, alertTitle, alertText);
                </script>
                <?php
                die();
            }
            $sql = "SELECT id,datum,uhrzeit,Temperatur_Celsius,Luftfeuchtigkeit_Prozent,created_at FROM temperaturs WHERE id>=$id LIMIT 49";
            $query2 = $DatabaseObject->Abfragen($connection, $sql);
            if (is_array($query2))
                anzeigen($query2);
            else {
                print_r('!!Error!!<br>Datenbankfehler. Abbruch!');
                foreach ($connection->errorInfo() as $item) {
                    print_r('<br>' . $item);
                }
                die();
            }
            file_put_contents($datei, $id);
            die();
        }
        $boolQuery2 = true;
        //Da Sessions hier aus unerklärlichen Gründen nicht funktionieren, wird die DropDown-Id in eine Textdatei geschrieben bzw. ausgelesen    
        $id = file_get_contents($datei);
        if (isset($_REQUEST['rad'])) {
            if ($_REQUEST['rad'] == 'frontOf') {
                $dummy = $id;
                if ($id <= 18000)
                    $id += $_REQUEST["anzahlItems"];
                else
                    $id += 2 * $_REQUEST["anzahlItems"];
                if ($id > $maxId) {
                    ?>
                    <script>
                        var alertWidth = 250;
                        var alertHeight = 200;
                        var xAlertStart = 650;
                        var yAlertStart = 200;
                        var alertTitle = "<p class='pTitle'><b>! Warnung !</b></p>";
                        var alertText = "<p class='pAlert'>Sie befinden sich am oberen Ende der Meßwerte.<br>Bitte reduzieren, anstatt erhöhen!</p>";
                        showAlert(alertWidth, alertHeight, xAlertStart, yAlertStart, alertTitle, alertText);
                    </script>
                    <?php
                    $id = $dummy;
                } else
                    file_put_contents($datei, $id);
            } else if ($_REQUEST['rad'] == 'back') {
                $dummy = $id;
                if ($id <= 18000)
                    $id -= $_REQUEST["anzahlItems"];
                else
                    $id -= 2 * $_REQUEST["anzahlItems"];
                if ($id < 0) {
                    ?>
                    <script>
                        var alertWidth = 250;
                        var alertHeight = 200;
                        var xAlertStart = 650;
                        var yAlertStart = 200;
                        var alertTitle = "<p class='pTitle'><b>! Warnung !</b></p>";
                        var alertText = "<p class='pAlert'>Sie befinden sich am unteren Ende der Meßwerte.<br>Bitte erhöhen, anstatt reduzieren!</p>";
                        showAlert(alertWidth, alertHeight, xAlertStart, yAlertStart, alertTitle, alertText);
                    </script>
                    <?php
                    $id = $dummy;
                } else
                    file_put_contents($datei, $id);
            }
        } else
            print_r('!!ERROR!! Abbruch');
    } else {
        if (file_exists($datei))
            unlink($folder . '/txt/dropDownID.txt');
        $boolQuery2 = false;
        file_put_contents($datei, '50');
    }
    if (!$boolQuery2)
        $sql = "SELECT id,datum,uhrzeit,Temperatur_Celsius,Luftfeuchtigkeit_Prozent,created_at FROM temperaturs LIMIT 49";
    else
        $sql = "SELECT id,datum,uhrzeit,Temperatur_Celsius,Luftfeuchtigkeit_Prozent,created_at FROM temperaturs WHERE id>=$id LIMIT 49";
    $query2 = $DatabaseObject->Abfragen($connection, $sql);
    if (is_array($query2))
        anzeigen($query2);
    else {
        print_r('!!Error!!<br>Datenbankfehler. Abbruch!');
        foreach ($connection->errorInfo() as $item) {
            print_r('<br>' . $item);
        }
        die();
    }
    ?>

hier der Code von dataTime.php
PHP:
<!Doctype html> <!-- Definition des doctype-Modus -->
<html> <!-- Definition des Stammverzeichnises -->
    <head> <!-- Definition des Kopfbereiches -->
        <meta charset="utf-8"><!-- charset[utf-8:]  definiert den deutschen Zeichensatz -->
        <meta name="msvalidate.01" content="8B12875037645A4090EE64488042FDA9" /><!--validiert die Website für Bing und Yahoo-->
        <meta name="date" content="2019-05-19T08:49:37+02:00">        <!-- Angaben, wann die Seite publiziert wurde-->
        <meta name="keywords" content="Temperatur, Analyse, Graphics">    <!-- versorgt die Spider der Suchmaschinen mit Informationen zwecks Suchbegriffen -->
        <meta name="description" content="Eine Auswertung der Datenbankdaten / Pi-Temperatursensor">    <!-- Beschreibung, die in den Suchmaschinen erscheinen soll. -->
        <meta name="robots" content="index,follow">            <!-- Links sollen mitindiziert werden //NOINDEX:Seite soll nicht aufgenommen werden//NOFOLLOW Links werden nicht verfolgt-->
        <meta name="audience" content="alle">                <!-- definiert die Zielgruppe der Website  -->
        <meta name="page-topic" content="Hobby">        <!-- Zuordnungsdefinition für die Suchmaschine -->
        <meta name="revisit-after" CONTENT="7 days">            <!-- definiert den erneuten Besuch des Spiders//hier:nach sieben Tagen  -->
        <title lang="de">Temperatur Analyse</title>     <!-- weist dem HTML-Dokument in der Registerkarte einen Namen zu -->    
        <!--  JQuery Bibliotheken -->
        <script src="js/jquery-1.7.1.min.js"></script>
        <script src="js/jquery-ui-1.8.17.custom.min.js"></script>
        <script src="js/menus.js"></script>
        <script src="js/datetime.js"></script>
        <script src="js/Alert.js"></script>
        <!--  CSS Bibliotheken -->
        <link href="css/style.css" rel="stylesheet">
        <link rel="stylesheet" href="css/jquery-ui-1.8.17.custom.css">
        <style type="text/css"></style>
    </head>

    <body> <!-- Definition des Bodybereiches -->
        <script>
            $(document).ready(function () {
                $('#date').datepicker({
                    showOn: 'button',
                    buttonImage: 'calendar.png',
                    buttonImageOnly: true,
                    numberOfMonths: 2,
                    showButtonPanel: true,
                    autoSize: true,
                    monthNames: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],
                    dateFormat: 'dd-mm-yy'
                });
            });
        </script>
        <div class="mainDiv">
            <div id="uhr"></div>
        </div>
        <ul>
            <li class="dropdown">
                <a href="javascript:void(0)" class="treffer_0" onclick="myFunction_0()">Home</a>
                <div class="dropdown-inhalt_0" id="auswahl_0">
                    <a href="info.php">PHP-Info</a>
                    <a href="javascript:impressum()">Impressum</a>
                    <a href="index.php">Startseite</a>
                </div>
            </li>
            <li class="dropdown">
                <a href="javascript:void(0)" class="treffer_0" onclick="myFunction_1()">Daten abrufen</a>
                <div class="dropdown-inhalt_0" id="auswahl_1">
                    <a href="showGraphics.php">Grafik erstellen</a>
                    <a href="dataAll.php">alle Daten abrufen </a>
                </div>
            </li>
            <li class="dropdown">
                <a href="javascript:void(0)" class="treffer_0" onclick="myFunction_2()">Adminbereich</a>
                <div class="dropdown-inhalt_0" id="auswahl_2">
                    <a href="dataDelete.php">Daten löschen</a>
                    <a href="dataRemove.php">Duplikate entfernen</a>
                    <a href="index.php">Startseite</a>
                </div>
            </li>
        </ul>
        <script>
            function impressum() {
                alert("Programmierer &  V.i.S.d.P: Thomas Kipp\nAnschrift:\nKlein - Buchholzer - Kirchweg 25\n30659 Hannover\nMobil:0152/37389041");
            }
        </script>
    <center><h2>Daten gemäß Datum</h2>
        <p>Hier werden nach dem Push auf den Submittbutton Records ab dem gewählten Datum angezeigt.</p>
        <div>
            <center>
                <form action="<?= htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">
                    <div>
                        <input class="feld" type=text name="date0" id="date" placeholder="Datum:" value="<?php
                        if (!empty($_REQUEST['date0'])) {
                            echo $_REQUEST['date0'];
                        }
                        ?>">
                    </div>                
                    <div>
                        <br>
                        <label>gemäß Datum anzeigen</label>
                        <input class="button3" type="submit" name="submit1" value="Submit">
                    </div>
                </form>
            </center>
        </div>
        <?php
        if (!empty($_REQUEST['submit1'])) {
            if (empty($_REQUEST['date0'])) {
                ?>
                <script>
                    var alertWidth = 250;
                    var alertHeight = 200;
                    var xAlertStart = 650;
                    var yAlertStart = 200;
                    var alertTitle = "<p class='pTitle'><b>! Warnung !</b></p>";
                    var alertText = "<p class='pAlert'>Warum erzeugen Sie unnötigen Traffic?<br>Bitte ein Datum wählen, bevor Sie einen Request abfeuern!</p>";
                    showAlert(alertWidth, alertHeight, xAlertStart, yAlertStart, alertTitle, alertText);
                </script>
                <?php
                die();
            } else {
                $strDatum = "";
                //splitte das Datumfeld anhand des Trenners(-) in ein Array
                $arrayOfDate = explode('-', $_REQUEST['date0']);
                //iteriere über das Array und setze den Datumstring so zusammen, dass die Datenbank ihn erkennt
                for ($i = 0; $i < count($arrayOfDate); $i++) {
                    if ($i != count($arrayOfDate) - 1)
                        $strDatum .= $arrayOfDate[$i] . '.';
                    else
                        $strDatum .= $arrayOfDate[$i];
                }
                //jetzt enthalt die Variable strDatum das Datum so, wie ihn die Datenbank mitunter enthält. Initialisere Datenbankabfrage
                require_once 'inc/autoloader.php';
                spl_autoload_register('classAutoloader');
                $DatabaseObject = new MySQLClass('2BeHacked', '2BeHacked', 'mysql', '127.0.0.1', 'temperatur');
                $connection = $DatabaseObject->Verbinden();
                if (!$connection) {
                    print_r("MySQL-Aufbau ist gescheitert!<br>");
                    die();
                }
                $sql = "SELECT datum FROM temperaturs;";
                $query1 = $DatabaseObject->Abfragen($connection, $sql);
                if (is_array($query1)) {
                    //Iteriere über das Array(query1) und überprüfe, ob strDatum in der Datenbank enthalten ist
                    for ($i = 0; $i < count($query1); $i++) {
                        //Sofern der Wert gefunden wurde, weise ihn der Session zu und verlasse die Schleife
                        if ($strDatum == $query1[$i]['datum']) {
                            $datum = $query1[$i]['datum'];
                            break;
                            //andernfalls setze die Session auf 1
                        } else
                            $datum = 1;
                    }
                } else {
                    print_r("Fehler bei der Datenbankabfrage!");
                    die();
                }
                //Sofern der Wert nicht gefunden wurde, benachrichtige den User
                if ($datum == 1) {
                    ?>
                    <script>
                        var alertWidth = 300;
                        var alertHeight = 150;
                        var xAlertStart = 650;
                        var yAlertStart = 200;
                        var alertTitle = "<p class='pTitle'><b>! Warnung !</b></p>";
                        var alertText = "<p class='pAlert'>Das angeforderte Datum konnte nicht gefunden werden. Suchen sie ggf. erneut mit einem anderen Datum!</p>";
                        showAlert(alertWidth, alertHeight, xAlertStart, yAlertStart, alertTitle, alertText);
                    </script>
                    <?php
                } else {
                    require_once 'inc/anzeigen.php';
                    $sql = "SELECT id,datum,uhrzeit,Temperatur_Celsius,Luftfeuchtigkeit_Prozent,created_at FROM temperaturs WHERE datum='$datum' LIMIT 49";
                    $query2 = $DatabaseObject->Abfragen($connection, $sql);
                    if (is_array($query2))
                        anzeigen($query2);
                    else {
                        print_r('!!Error!!<br>Datenbankfehler. Abbruch!');
                        foreach ($connection->errorInfo() as $item) {
                            print_r('<br>' . $item);
                        }
                        die();
                    }
                }
            }
        }
        ?>
 
Zuletzt bearbeitet:
Selbstverständlich werde ich den Code veröffentlichen.
Sehr nett :)

Allerdings gebe ich zu Bedenken, dass ein 'normaler' Angreifer nicht über diese Infos verfügt! Der sieht letztlich nur die Anwendung, keinen Code!
Das ist wahr, aber ein "echter" Angreifer schert sich auch nicht um Internetanschlusssperren. Die Probieren einfach mal durch und haben dafür ihre Programme, die alles automatisch testen, oft in Botnets. Wenn da ein Anschluss gesperrt wird, juckt die das nicht.

Wenn es jemand gelingt, in mein System einzudringen, nur zu
Also mit SQL-Injections sehe ich hier ziemlich schwarz.

Bei der DataAll.php prüfst du, ob die Eingabe numerisch ist. SQL commands werden somit gar nicht weitergeleitet, obwohl du die $id aus startID direkt übergibst.

Bei der DataTime.php benutzt du zwar die Datenbank, wie man sie nicht benutzen soll (99% der Arbeit macht hier PHP in linearen Suchen, welche wahrscheinlich sehr viel langsamer sind als MySQL mit Indices / Sortierung, geschweige denn der Lokalität. (Siehe SQL WHERE).

Aber immerhin ist es so sicher vor Injections, da selbst das $datum, das du in die Query einsetzt, aus der Datenbank selbst und nicht aus dem Input kommt.

Also gewinnst du diese Runde, und dein Code ist "sicher" vor Injections: Mal durch manuelles Abschalten, mal durch nicht-Übergeben der Parameter an die Datenbank.

Das ist etwas doof, denn so fehlt die Schockwirkung. :(
Das Problem ist: Irgendwann machst du einen Fehler, wo Injections möglich sind. Dein Löschformular z.B.
Es falsch zu lernen gibt schlussendlich mehr Probleme, da du es wieder korrigieren musst. ComFreek hat ja schon ein Beispiel gemacht, was aber eigentlich keine echte Injection ist.

Eine echte Injection, welche du bei dir lokal ausprobieren könntest, wäre diese hier:
Code:
; INSERT INTO temperaturs(Temperatur_Celsius) VALUES (1337);
(Einfach in das Feld einfüllen. Wenn du keine Defaults gesetzt hast, musst du ID, Datum etc. noch mit dazugeben, aber ich denke, das zeigt das Problem schön genug: Man könnte damit irgendwelche Werte einfügen: Das Semikolon terminiert die Abfrage nach IDs, dann kommt ein eigenes Input-Statement, das auch mit dazu ausgeführt wird).
Eingesetzt dann hier:
PHP:
$sql = 'DELETE FROM temperaturs WHERE id=' . $_REQUEST["anzahlItems"];
Deine Maxlength im HTML-Teil kann mit mit den Entwicklertools einfach auf 3000 hochschrauben, ist also kein Hindernis.

Kleine Geschichtsstunde: Früher hatte man (wie du jetzt auch) tatsächlich mit Funktionen auf Injections geprüft, mysql_escape (das hatte einen Bug, dann hiess es mysql_real_escape) und später mysqli_real_escape, welches die Inputs auf Non-SQL-Specialchars reduzierte. Das Problem dabei: Man musste immer daran denken. PDO ist viel einfacher, macht alles automatisch, und ist bei grösseren Anfragen oft schneller als das alte Stringbauen.

TL;DR: In deinem Fall gibt es keine angreifbaren Statements. Vor allem, weil du die Datenbanken extrem unkonventionell nutzt.

Gruss
cwriter
 
Ich habe mich jetzt nicht durch den Code gewühlt, denn @cwriter hat das wohl schon gründlich gemacht :)

Worum es aber eigentlich ging und noch immer geht:

1. $_POST (und natürlich auch $_REQUEST und überhaupt erstmal alle Superglobalen) kann gefaked werden.
Und selbstverständlich laden solche Konstrukte wie

$sql = 'DELETE FROM temperaturs WHERE id=' . $_REQUEST["anzahlItems"];

geradezu dazu ein, sich an der DB zu vergreifen. Dabei meine ich die generelle Vorgehensweise des Verwendens von ungeprüften Benutzereingaben und nicht nur speziell diesen einen Befehl.

2. In einfachen Projekten, wo man die "gefährlichen" Stellen an einer Hand abzählen kann, mag das noch zu überblicken sein. Wenn es mal richtig viel wird, wirst Du, @tklustig, mal an den Punkt kommen, wo Du unsicher bist, ob Du wirklich alle kritischen Stellen adäquat behandelt hast. Da ist es schon beruhigend, wenn man sich nicht erst auf solche Sachen eingelassen, sondern gleich den sichere(re)n Weg eingeschlagen hat.

3. Das beliebteste Ziel - zumindest sagen das meine Logs - ist noch immer wordpress. Das gibt es schon so lange, ist so bekannt und so oft eingesetzt, dass man der Meinung sein müsste, dass die Jungs und Mädels das absolut sicher bekommen haben. Doch wenn das so wäre, gäbe es wohl kaum so viele Angriffsversuche auf das System.

4. Eigentlich sollte es keine Diskussion bedürfen, ob man eine sichere oder eine einfache Variante verwendet. Aber jeder wie er mag.
 
Der Tenor Eurer Statements, so habe ich es zumindest verstanden, ist der, dass Usereingaben niemals ungeprüft an die Datenbank weitergereicht werden sollten, d.h., sie sollten nicht in Querys übernommen werden. Bezogen auf das Query:
PHP:
$sql = 'DELETE FROM temperaturs WHERE id=' . $_POST["anzahlItems"];
Wie wäre die Injection sichere Vorgehensweise? Da ich überwiegend mit dem Framework yii2 programmiere, habe ich mir bisher darüber keinerlei Gedanken gemacht, da Datenbankabfragen nicht mehr über die Formulierung von Querys durchgeführt werden. Da ginge da so:
PHP:
$this->findModel($id)->delete($modelView->anzahlItems);
 
Da ich überwiegend mit dem Framework yii2 programmiere, habe ich mir bisher darüber keinerlei Gedanken gemacht, da Datenbankabfragen nicht mehr über die Formulierung von Querys durchgeführt werden. Da ginge da so:
Bei solchen MVC-Frameworks sollte das eigentlich schon intern abgesichert werden.

Gruss
cwriter
 
Genau so ist es. Eine Applikation, die mit dem MVC Framework yii2 entwickelt wurde ist SQL Injection safe. Dennoch verbleibt die Frage im Raum, wie ich obiges Query auf Basis der PDO Klasse ohne Verwendung von yii2 Injection safe codiere?
 
Eine Applikation, die mit dem MVC Framework yii2 entwickelt wurde ist SQL Injection safe.
So allgemein würde ich das nicht unterschreiben. Es gibt immer Methoden, ein rohes SQL Query mit Frameworks abzusetzen. Eben weil man manchmal explizit ORM umgehen möchte. Außerdem, selbst wenn du ORM benutzt, könnten z. B. LIKE-Anfragen gefährlich sein. Denn bei LIKE musst du selbst bei Prepared Statements den ganzen String übergeben, z.B.:

PHP:
// Eine Art Pseudocode, ich kenn die genaue API nicht auswendig
$preparedStatement = prepare("SELECT * FROM table WHERE x LIKE :str");
$preparedStatement->bind(":str", "%" . $_GET['username'] . "%")->run();
Hier könnte es trotzdem noch zu einer Sicherheitslücke kommen, wenn $_GET['username'] Prozentzeichen enthält. (Beachte: Auch Verletzungen von Businessregeln können Sicherheitslücken darstellen. Auch wenn du an sich keine Tabellen löschen kannst, so könntest du bestimmte Businessregeln umgehen!)

Dennoch verbleibt die Frage im Raum, wie ich obiges Query auf Basis der PDO Klasse ohne Verwendung von yii2 Injection safe codiere?
PHP: Prepared Statements und Stored Procedures - Manual
 
Zurück