Sebastian: & MySQL: Seltsam abgeschnittene DB-Einträge

Hallo liebe Forumler,

ich habe ein längeres Formular gebastelt, das auch zwei <textarea>'s enthält. Den gesamten Formularinhalt lasse ich von php in eine MySQL-Datenbank schreiben. Die <textarea>-Inhalte lasse ich als My-SQL-Typ "text" abspeichern, nachdem ich sie mittels strip_tags gereinigt habe.

Nun kommt es in meiner DB bei manchen Einträgen vor, dass sie plötzlich unvermittelt abgeschnitten werden, obwohl ich die Zeichenanzahl in der Eingabe nicht limitiert habe und afaik auch der MySQL-Typ "text" kein Limit hat. dass es an der DB liegt, schließe ich auch deshalb aus, weil bei anderen Einträgen in diesem Feld sehr viel mehr Text gespeichert wird, ohne abgeschnitten zu werden.
Auch seltsam: Wo der betroffene Text abgeschnitten wird, setzt entweder php oder MySQL das Zeichen "" als letztes Zeichen ein.

Ich habe keine Ahnung, wer da warum zaubert. Kann mir jemand auf die Sprünge helfen?

Danke und Gruß -
Sebastian

  1. hi,

    Auch seltsam: Wo der betroffene Text abgeschnitten wird, setzt entweder php oder MySQL das Zeichen "" als letztes Zeichen ein.

    dann ist zu vermuten, dass du die daten vor der übergabe an die DB nicht korrekt behandelt hast, so das irgendein sonderzeichen für das "abschneiden" der daten sorgt.

    oder, dass bei der ausgabe als HTML ein sonderzeichen das HTML-element/-attribut vorzeitig beendet.

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. Hallo wahsaga,

      dann ist zu vermuten, dass du die daten vor der übergabe an die DB nicht korrekt behandelt hast, so das irgendein sonderzeichen für das "abschneiden" der daten sorgt.

      Ok. Und welche Behandlung soll ich den Daten zuteil werden lassen, damit sie wohlgeformt in die DB geschrieben werden?

      Danke im Voraus -
      Sebastian

  2. Hi!

    Neben dem, was dir bereits wahsaga gesagt hat, solltest du noch folgendes beachten:

    ich habe ein längeres Formular gebastelt, das auch zwei <textarea>'s enthält. Den gesamten Formularinhalt lasse ich von php in eine MySQL-Datenbank schreiben. Die <textarea>-Inhalte lasse ich als My-SQL-Typ "text" abspeichern, nachdem ich sie mittels strip_tags gereinigt habe.

    In die Datenbank sollte wirklich nur der in das Formular eingegebene Wert eingetragen werden, d.h. Funktionen wie strip_tags() oder htmlentities() sollten erst bei der _Ausgabe_ angewandt werden. Dadurch fällt es dir anschließend einerseits leichter, die Einträge für verschiedene Ausgabeformate aufzubereiten und andererseits kannst du z.B. gleich in PHPMyAdmin die Datensätze bearbeiten, ohne dort ein «ä» als &auml; schreiben zu müssen. Dazu gehört übrigens auch die Entfernung eventueller Maskierungs-Backslashes (bedingt durch magic_quotes).

    Stattdessen solltest du beim Eintragen auf Funktionen wie mysql_real_escape_string() zurückgreifen, die alle diejenigen Zeichen maskieren, die beim Eintragen Probleme machen könnten. Gleichzeitig schützt du dich dadurch vor SQL-Injections.

    Grüße,
    Fabian St.

    1. Hallo Fabian,

      In die Datenbank sollte wirklich nur der in das Formular eingegebene Wert eingetragen werden, d.h. Funktionen wie strip_tags() oder htmlentities() sollten erst bei der _Ausgabe_ angewandt werden.

      ich habe irgendwo gelesen, dass strip_tags unbedingt angewandt werden soll, damit man keinen php-Code einschleusen kann, der evtl. bösen Schaden anrichtet?! htmlentities erst bei der Ausgabe ist ja logisch.

      Dazu gehört übrigens auch die Entfernung eventueller Maskierungs-Backslashes (bedingt durch magic_quotes).

      Heißt das, mein Problem beruht auf magic_quotes? Aber außer strip_tags verwende ich doch nichts vor der Übergabe!?

      Stattdessen solltest du beim Eintragen auf Funktionen wie mysql_real_escape_string() zurückgreifen, die alle diejenigen Zeichen maskieren, die beim Eintragen Probleme machen könnten.

      Ist das die "korrekte Behandlung", die wahsaga von mir fordert?

      Gleichzeitig schützt du dich dadurch vor SQL-Injections.

      Sind Injections die von mir o.g. Code-Einschleusungen, die ich per strip_tags zu entfernen trachte?

      Vielen Dank für deine wie so oft sehr ausführliche Antwort!
      Gruß -
      Sebastian

      1. hi,

        ich habe irgendwo gelesen, dass strip_tags unbedingt angewandt werden soll, damit man keinen php-Code einschleusen kann, der evtl. bösen Schaden anrichtet?!

        nein, diese gefahr ist nicht gegeben, so lange du den text nicht als PHP auswerten lässt.

        htmlentities erst bei der Ausgabe ist ja logisch.

        strip_tags() kann dann u.U. sogar entfallen.
        evtl. eingegebene tags werden dann halt einfach als text angezeigt.

        Gleichzeitig schützt du dich dadurch vor SQL-Injections.
        Sind Injections die von mir o.g. Code-Einschleusungen, die ich per strip_tags zu entfernen trachte?

        nein.
        aber warum folgst du dem link nicht einfach mal, wenn du nicht weißt, was das stichwort bedeutet?

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
      2. Hi!

        In die Datenbank sollte wirklich nur der in das Formular eingegebene Wert eingetragen werden, d.h. Funktionen wie strip_tags() oder htmlentities() sollten erst bei der _Ausgabe_ angewandt werden.
        ich habe irgendwo gelesen, dass strip_tags unbedingt angewandt werden soll, damit man keinen php-Code einschleusen kann, der evtl. bösen Schaden anrichtet?! htmlentities erst bei der Ausgabe ist ja logisch.

        Nein, zum Eintragen von Daten in eine DB sollte strip_tags() nicht verwendet werden. Darüber hinaus macht strip_tags() oftmals mehr als einem lieb ist: Stell dir vor jemand gibt 4 < 5 in dein Textfeld ein - anschließend ist von dieser Gleichung nichts mehr zu sehen ;-) Wenn du deine Daten immer folgendermaßen einträgst und beim Ausgeben mit htmlentities() behandelst, solltest du keine Probleme bekommen:

          
          
        $sql = "INSERT INTO  
                            tabelle  
                            (feld1, feld2)  
                VALUES  
                            ('".mysql_real_escape_string($_POST['feld1'])."',  
                             '".mysql_real_escape_string($_POST['feld2'])."'  
                            )";  
        
        

        Beachte hierbei insbesondere die Folge der einfachen und doppelten Anführungszeichen!

        Dazu gehört übrigens auch die Entfernung eventueller Maskierungs-Backslashes (bedingt durch magic_quotes).
        Heißt das, mein Problem beruht auf magic_quotes? Aber außer strip_tags verwende ich doch nichts vor der Übergabe!?

        magic_quotes macht - ebenso wie strip_tags() - oftmals mehr Probleme als es lösen soll. Aus diesem Grund könntest du magic_quotes in der php.ini auf Off stellen oder du verwendest jedesmal nach $_POST oder $_GET eine Funktion, wie du sie auf php.net findest (stripslashes_deep() für Arrays, ansonsten einfaches stripslashes()).

        Stattdessen solltest du beim Eintragen auf Funktionen wie mysql_real_escape_string() zurückgreifen, die alle diejenigen Zeichen maskieren, die beim Eintragen Probleme machen könnten.
        Ist das die "korrekte Behandlung", die wahsaga von mir fordert?

        Ja, das wäre eine Möglichkeit.

        Grüße,
        Fabian St.

        1. Hallo Fabian,

          kann ich mysql_real_escape_string() auch außerhalb einer MySQL-Anweisung verwenden?
          Konkret ist es nämlich ein mehrseitiges Formular, bei dem ich die Angaben von der ersten Seite ersteinmal in einzelnen <form type="hidden"> des Formulars auf der zweiten Seite ablege, bevor ich sie nach Absenden dieser zweiten Seite gemeinsam in die DB schreibe.
          Könnte ich also auf der zweiten Seite die einzelnen Variablen der ersten Seite nach der Methode

          $foo1=mysql_real_escape_string($_POST['foo1']);
          $foo2=mysql_real_escape_string($_POST['foo2']);

          initialisieren, sie danach mit

          <input type="hidden" name="foo1" value="<?php echo $foo1 ?>">
          <input type="hidden" name="foo2" value="<?php echo $foo2 ?>">

          in das zweite Formular packen und sie nach Absenden gemeinsam mit den frisch eingegebenen Daten in die DB schreiben lassen, ohne in der MySQL-Anweisung mysql_real_escape_string() verwenden zu müssen?

          Danke und Gruß -
          Sebastian

          1. hi,

            Konkret ist es nämlich ein mehrseitiges Formular, bei dem ich die Angaben von der ersten Seite ersteinmal in einzelnen <form type="hidden"> des Formulars auf der zweiten Seite ablege, bevor ich sie nach Absenden dieser zweiten Seite gemeinsam in die DB schreibe.

            dafür bieten sich sessions oftmals eher an.

            Könnte ich also auf der zweiten Seite die einzelnen Variablen der ersten Seite nach der Methode [...] mysql_real_escape_string [...]
            in das zweite Formular packen und sie nach Absenden gemeinsam mit den frisch eingegebenen Daten in die DB schreiben lassen, ohne in der MySQL-Anweisung mysql_real_escape_string() verwenden zu müssen?

            nein, selbstverständlich nicht.

            diese daten würden dir ja dann wieder vom client geschickt werden, könnten also nach belieben manipuliert sein - und schon ist die gefahr der SQL Injection wieder da.

            grundsatz: never trust incomming data.

            gruß,
            wahsaga

            --
            /voodoo.css:
            #GeorgeWBush { position:absolute; bottom:-6ft; }
            1. ok - Danke! Gruß -
              Sebastian

  3. Hi Sebastian,

    oder es liegt daran, dass du die Daten per GET verschickst.
    Und da gibt es die Zeichenbegrenzung von 1024 Zeichen insgesamt.

    1. Hallo mark,

      ich nutze post und es liegt wohl eher bei wahsagas/Fabians Tipp. Trotzdem Danke und

      Gruß -
      Sebastian

    2. Moin!

      oder es liegt daran, dass du die Daten per GET verschickst.
      Und da gibt es die Zeichenbegrenzung von 1024 Zeichen insgesamt.

      Nein, gibt es nicht. Eine URL kann grundsätzlich unbegrenzt lang sein - einzig die technische Umsetzung in Browsern, Proxys und Servern kann zu Einschränkungen führen. Die daraus resultierende Grenze kann bei 1024 liegen, muß sie aber nicht. Es ist genausogut auch wesentlich mehr (z.B. 8 KB) oder weniger (256 Byte) schon in der Praxis vorgekommen.

      • Sven Rautenberg
  4. Hallo,

    Eingabe nicht limitiert habe und afaik auch der MySQL-Typ "text" kein Limit hat.

    huch, das lese ich aber zum ersten mal.

    im gegensatz dazu:
        BLOB, TEXT    L+2 bytes, where L < 2^16
      aus: RTFM

    gruss

    --
    no strict;
    no warnings;
    Ich weiss es nicht, aber ich bin mir nicht sicher.
    Craptastic.
    Wenn ich groß bin, werde ich eine nervige künstliche Intelligenz.