Ankündigung

Einklappen
Keine Ankündigung bisher.

Datenbankeinträge, Ein- und Ausgabesicherheit - Basic

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Datenbankeinträge, Ein- und Ausgabesicherheit - Basic

    Hallo liebe Forengemeinde!

    Ich vor Jahren ein kleines CMS geschrieben in welchem die Textarea mit dem Inhalt mittels TinyMCE WYSIWYG als Editor befüllt wird.

    Damals hatte ich die Datenbankeinträge sowohl bei Ein- als auch Ausgabe noch nicht gesichert.

    Meine Frage nun an die Community, reicht es, als Basismassnahmen folgende Schritte durchzuführen?:

    PHP-Code:
    // Einträge vor Eingabe codieren
    function encode_data_b4_entry($textarea_input) {
      
    // Encode html code, even " and '
      
    $textarea_input htmlentities($textarea_inputENT_QUOTES);
      return 
    $textarea_input;
    }


    // Einträge nach Auslesen aus der Datenbank encoden
    function decode_data_b4_output($text_output) {
      
    // Decode html code
      
    $text_output html_entity_decode($text_outputENT_QUOTES);
      return 
    $text_output;

    Das müsste als Basisschutz reichen oder liege ich da komplett falsch? Mir ist bewusst dass es sicherlich noch sehr viel umfassendere Sicherheitsaspekte gibt, jedoch bin ich kein Profi.

    Ich wäre Euch für konstruktive Hinweise, Anregungen oder ähnliches sehr dankbar.
    mfg Alex

  • #2
    Wie genau sollen diese Funktionen benutzt werden? Wenn du PDO mit Parametern verwendest, musst du garnichts dergleichen machen, vielleicht ne Idee wert.
    [URL="http://goo.gl/6Biyf"]Lerne Grundlagen[/URL] | [URL="http://sscce.org/"]Schreibe gute Beispiele[/URL] | [URL="http://goo.gl/f2jR7"]PDO > mysqli > mysql[/URL] | [URL="http://goo.gl/jvfSZ"]Versuch nicht, das Rad neu zu erfinden[/URL] | [URL="http://goo.gl/T2PU5"]Warum $foo[bar] böse ist[/URL] | [URL="http://goo.gl/rrfzO"]SQL Injections[/URL] | [URL="http://goo.gl/Q81WJ"]Hashes sind keine Verschlüsselungen![/URL] | [URL="http://goo.gl/2x0e2"]Dein E-Mail Regex ist falsch[/URL]

    Kommentar


    • #3
      htmlentities vor Eintragen in die Datenbank? Kanns sein, dass du den Unterschied zwischen escapen für ein HTML-Dokument und escapen für ein SQL-Statement nicht kennst? Wenn das CMS älter ist, wie ich dem Text entnehme, dann steht einer Generalüberholung wohl nichts im Wege, und wenn du sowieso auf Sicherheit aus bist, dann rüste doch gleich auf PDO's um.

      Kommentar


      • #4
        Vielen Dank für Eure Antworten!

        Komplett umrüsten möchte ich eigentlich nicht, bin auch wie gesagt kein Profi und das CMS ist prozedural programmiert.

        Das CMS ist in der Tat älter, funktioniert aber einwandfrei. Der Inhalt der CMS-Seite wird in der Datenbank gespeichert. HTML-Formatierungen durch den WYSIWYG Editor sind vorhanden. Vielleicht habe ich mich zuvor mit der Benennung der Variablen nicht glücklich ausgedrückt. Um die Einträge zu "schützen", sprich um Injections mittels '-Zeichen in der Eingabe der Textarea zu vermeiden dachte ich, es wäre ausreichend für den INHALT der Textarea diese Methode anzuwenden. Selbstverständlich könnte ich auch (zusätzlich?) escapen (addslashes) und wieder deescapen (stripslashes), ich dachte jedoch dass ich mir dies aufgrund oben beschriebener Funktion sparen kann.

        Wie gesagt... ich bin kein Profi und über Tipps bzw. Hinweise sehr dankbar, komplett umstellen, bzw. umrüsten möchte ich jedoch, auch aufgrund meiner mangelnden Erfahrung, nicht.
        mfg Alex

        Kommentar


        • #5
          Du verwechselst da zwei Sachen, die nichts miteinander zu tun haben. HTML-Escaping mit slashes, tags, entity etc. hat nichts mit SQL Injection Sicherheit zu tun. Das sind zwei separate Themen, die du mit deinem Ausschnitt da in keiner Weise behebst.
          [URL="http://goo.gl/6Biyf"]Lerne Grundlagen[/URL] | [URL="http://sscce.org/"]Schreibe gute Beispiele[/URL] | [URL="http://goo.gl/f2jR7"]PDO > mysqli > mysql[/URL] | [URL="http://goo.gl/jvfSZ"]Versuch nicht, das Rad neu zu erfinden[/URL] | [URL="http://goo.gl/T2PU5"]Warum $foo[bar] böse ist[/URL] | [URL="http://goo.gl/rrfzO"]SQL Injections[/URL] | [URL="http://goo.gl/Q81WJ"]Hashes sind keine Verschlüsselungen![/URL] | [URL="http://goo.gl/2x0e2"]Dein E-Mail Regex ist falsch[/URL]

          Kommentar


          • #6
            Vielen Dank nochmal für deine Antwort. Wie gesagt... ich bin kein Profi wie du meinem Profil und meinem Beitrag entnehmen kannst.

            Da ich es noch nicht wirklich verstehe was du meinst, bzw. ich mir nicht erklären kann was bei meiner Sichtweise schief gehen kann habe ich eine simple Testdatei erstellt:
            PHP-Code:
            <?php

            // FUNKTIONEN
                // Einträge vor Eingabe codieren
                
            function encode_data_b4_entry($textarea_input) {
                    
            $textarea_input htmlentities($textarea_inputENT_QUOTES);
                    return 
            $textarea_input;
                }

                
            // Einträge nach Auslesen aus der Datenbank encoden
                
            function decode_data_b4_output($db_output) {
                    
            $db_output html_entity_decode($db_outputENT_QUOTES);
                    return 
            $db_output;
                }

            // GEÄNDERTE DATEN SPEICHERN
                
            if($_POST['submit']) {
                    
            $sql "UPDATE ".TABLE_CMS_DATA."
                                    SET text = '"
            .encode_data_b4_input($_POST['textarea'], ENT_QUOTES)."';";
                    
            mysql_query($sql);
                }

            // DERZEITG GESPEICHERTE DATEN AUSGEBEN
                
            $sql "SELECT text FROM tabelle";
                
            $query mysql_query($sql);
                
            $data mysql_fetch_assoc($query);
                echo 
            decode_data_b4_output($data['text']); 

            // FORMULAR ZUM ÄNDERN DER DATEN
            ?>
            <form method="post">
                <textarea name="textarea"></textarea><br />
                <input type="submit" name="submit" value="Abschicken">
            </form>
            Warum ist diese Eingabe nun unsicher? Denn damit kann ja eigentlich nichts passieren, da sämtliche Zeichen vor Eingabe in HTML-Code umgewandelt werden oder? Bitte verzeih meine vielleicht dumme Frage, aber ich kann es mir einfach nicht erklären und möchte es verstehen.
            mfg Alex

            Kommentar


            • #7
              Hallöchen,

              vielleicht liest du dir einfach mal ein paar Artikel zu den Themen SQL Injection und Cross-Side-Scripting durch. Anschließend führst du dir mal die Funktionsweise von mysqli_real_escape_string und htmlentites/ htmlspecialchars zu Gemüte (die genannten Funktionen sind übrigens gut dokumentiert). Nach der Lektüre sollte klar sein, wann welche der Funktionen zu verwenden ist. Kontextwechsel ist in diesem Zusammenhang ebenfalls ein nennenswertes Stichwort.

              Viele Grüße,
              lotti
              [SIZE="1"]Atwood's Law: any application that can be written in JavaScript, will eventually be written in JavaScript.[/SIZE]

              Kommentar


              • #8
                Du solltest dir wahrscheinlich erstmal klar machen, was HTML Entities überhaupt sind. Wenn man nun Zeichen zu HTML Entities umwandelt, bringt dies garnichts hinsichtlich SQL Injections. An SQL Injections muss man seperat gehen. Vielleicht sollte dich auch das Thema Kontextwechsel noch strapazieren, um HTML von SQL gänzlich trennen zu können.

                Auch ist anzumerken, dass man keine Daten mit HTML Entities versieht und diese dann in der Datenbank speichert. HTML Entities sind schließlich für HTML da und die Daten in der Datenbank nicht zwangsläufig nur für eine HTML Datei. Man trennt also auch hier wieder HTML von SQL.

                Um Daten nun auszugeben, verwendet man sicherlich nicht html_entity_decode. Das würde ja im gegenteiligen Effekt zu unserer Intention, gegen Cross Site Scripting vorzugehen, resultieren. Daher wie bereits angemerkt, auch dieses Thema nochmals studieren.

                Kommentar


                • #9
                  Ist das wirklich alles was Du mit den Daten in der DB anfängst?
                  Keine Suche, keine Abfragen?
                  Wenn ja, wozu dann das Speichern in einer DB?

                  Gruß
                  joergy

                  Kommentar


                  • #10
                    @lottikarotti und Chris: Ich werde mir das alles durchlesen, wie empfohlen. Seitens SQL-Injections habe ich mir schon einiges durchgelesen, jedoch ist mir trotzdem noch nicht klar wie maligne Eingaben in der Textarea hier zu Schaden in meiner Datenbank führen können. Mir ist bewusst dass ich das auch mit mysql_real_escape() bewerkstelligen kann, jedoch dachte ich, wenn ich htmlentities verwende, so werden sowieso jegliche single- und double-Quotes unschädlich gemacht oder nicht?! Es kommt ja somit nie dazu dass ein sql-Befehl mittels eines Quotes durch eine Usereingabe verändert werden kann? Vielleicht habe ich genau DA den Denkfehler?

                    Bezüglich Kontextwechsel, diesen habe ich bei meinem SQL-String ja beachtet?! Deshalb habe ich zur Begrenzung ja double-Quotes verwendet um nicht escapen zu müssen. Ich denke dass dieser SQL-String sehr wohl korrekt ist?! Mir ist auch bewusst, dass ich den sql-String mit mysql_real_escape "schützen" und escapen kann, dachte mir aber dass dies aufgrund oben genanntem Grund nicht nötig sei.

                    @joergy: das ist ja nur eine Testdatei die ich schnell erstellt habe um zu veranschaulichen und testen wie sich diese Funktionen auswirken.

                    Früher hatte ich mysql_real_escape_string (XSS und Injections, JS) UND htmlspecialchars (jetzt wie oben beschrieben htmlentities), las dann aber in dem Tutorial von ApoY2k (MySqlInjections: http://de.slideshare.net/billkarwin/...-and-fallacies) dass man nur 1 Methode wählen solle, weniger ist mehr, so wird dort geschrieben.
                    mfg Alex

                    Kommentar


                    • #11
                      Einfach erklärt: Escaping ist Kontext bezogen, SQL Injection Prevention hat einen anderen Kontext und andere Sicherheitsregeln die man Befolgen muss als Cross Site Scripting Prevention.

                      Im Detail:

                      Wann immer du etwas in die Datenbank speichern willst solltest du es mit Datenbankmittel behandeln und nicht Maskierungsmöglichkeiten die für einen anderen Kontext gedacht sind nutzen. PHP 5.5/5.6 bietet bei beiden Interfaces ( MySQLi / PDO ) die möglichkeit manuell zu escapen oder Prepared Statements zu nutzen ( die automatisch escapen solange man Werte an einen Platzhalter bindet ). Es ist also entscheidend wo du etwas verwenden willst, wenn du etwas escapen musst.

                      Generell verwendest du HTML-Escaping nur in Views ( also beim rendern der Darstellung ), alternativ kannst du den String auch mit HTMLPurifier bereinigen statt ihn zu escapen. Es hat keinen Vorteil schon beim Speichern eines Datensatzes den zu speichernden String für die Ausgabe zu behandeln ( ausgenommen hier die Bereinigung mit HTMLPurifier, da du damit sicherstellst das erst kein kompromitierender Quellcode in der Datenbank landet ).

                      Generell verwendest du SQL-Escaping immer wenn du Userland-Werte in die Datenbank bringst. Das solideste Prinzip SQL-Injection Prevention überhaupt und einfach umzusetzen ist die konsequente Verwendung von Prepared Statements.
                      [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

                      Kommentar


                      • #12
                        Deshalb habe ich zur Begrenzung ja double-Quotes verwendet um nicht escapen zu müssen.
                        String-Begrenzer und Escapen sind zwei paar Schuhe. Beim einen zeigst du dem Query, dass hier ein String startet und hier endet, beim anderen markierst du Zeichen, dass diese keinen Einfluss auf den Query nehmen. Begrenzt und escaped werden muss also immer - beides!

                        wenn ich htmlentities verwende, so werden sowieso jegliche single- und double-Quotes unschädlich gemacht oder nicht
                        Mag sein, aber viele andere Zeichen werden auch bearbeitet und das wollen wir nicht. Und wer sagt dir, dass im HTML Entity nicht auch noch ein schädliches Zeichen liegt?

                        Es kommt ja somit nie dazu dass ein sql-Befehl mittels eines Quotes durch eine Usereingabe verändert werden kann?
                        SQL Injections sind nicht nur mit Single- bzw. Double-Quotes möglich.

                        Kommentar


                        • #13
                          Zitat von tr0y Beitrag anzeigen
                          Das solideste Prinzip SQL-Injection überhaupt und einfach zu verhindern ist die konsequente Verwendung von Prepared Statements.
                          fixed
                          liebe Grüße
                          Fräulein Dingsda

                          Kommentar


                          • #14
                            Mein Fix gefällt mir besser.
                            [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

                            Kommentar


                            • #15
                              Vielen Dank tr0y, danke auch allen anderen noch einmal!

                              Das mit dem escapen mittels mysql_real_escape_string ist mir klar. Somit kann ich die Injections verhindern indem der "zusammengebastelte" SQL-String nicht manipuliert werden kann. Mein Problem bei der ganzen Sache ist aber wohl doch noch mangelndes Verständnis... denn wenn ich mein oben genanntes Beispiel mit meinen (bitte verzeih die immer wiederkehrende Frage) htmlentities($str, ENT_QUOTES) versehe, so kann ja dem SQL-String auch nichts passieren oder? Jedes Single-Quote würde ja dann in "'" umgewandelt und könnte dem String bzw. der Datenbankabfrage nicht mehr schaden oder?

                              Meine Überlegung diesbezüglich ist, dass die Textarea mittels TinyMCE bearbeitet wird. Wenn ich nun den Eingabewert mittels oben genannter Funktionen htmlentities codiere und dann mittels html_entity_decode() wieder zurückwandle, so habe ich das ursprüngliche Ergebnis. Mache ich dies aber mit mysql_real_escape_string, so habe ich danach immer bei jedem "gewollten" Single-Quote (beispielsweise bei enthaltenem JavaScript im gespeicherten HTML-Code) einen Backslash davor.

                              Weisst du, bzw. wisst ihr nun was ich meine? Es tut mir leid wenn ich mich da etwas umständlich ausdrücke, aber ich bin wie gesagt Laie. Ich kann eure Knochen ohne Probleme zusammenflicken oder Euer Leben retten (meist), aber das hier ist wirklich schwer für mich zu verstehen und ich bin Euch für Eure Ausführungen dankbar da ich es gerne verstehen würde.

                              EDIT: Sorry Chris, habe zwischenzeitlich, während du schon gepostet hast, schon geschrieben. Ich habe nun wirklich gar keinen Plan mehr wie ich oben beschriebenen Code nun korrekt umsetzen sollte/würde um dann auch wieder dasselbe Ergebnis für den TinyMCE auszugeben ohne alle Single-Quotes zu "zerstören".
                              mfg Alex

                              Kommentar

                              Lädt...
                              X