blaschi: mysql_real_escape_string + htmlspecialchars

Hallo,
ich hoffe ihr könnt mir mal wieder weiter helfen.

Wenn ich einen Text wie diesen:
___________________________________________
Dies sind „Sonderzeichen“
<?php echo 'Dies ist PHP Code'; ?>
___________________________________________

in eine Datenbank (MySQL) einpflegen will, fange ich ihn als erstes mit
htmlspecialchars ab.
Wenn ich ihn aber daraufhin nochmal mit mysql_real_escape_string abfange,
werden meine Anführungszeichen doppelt "entschärft", so dass ich bei der ausgabe des datensatzes folgendes bekomme:

___________________________________________
Dies sind &#8222;Sonderzeichen&#8220;
<?php echo 'Dies ist PHP Code'; ?>
___________________________________________

Nutze ich aber htmlspecialchars nicht, so wird der eingegebene php-code bei der ausgabe ausgeführt.
Ich hoffe ich konnte mich verständlich ausdrücken...

lG
Björn

  1. Hi blaschi,

    […] in eine Datenbank (MySQL) einpflegen will, fange ich ihn als erstes mit
    htmlspecialchars ab.

    Du kannst einen Text nicht „abfangen”, was du hier machst ist ein Escapen des Textes für einen HTML-Kontext.

    Wenn ich ihn aber daraufhin nochmal mit mysql_real_escape_string abfange,
    werden meine Anführungszeichen doppelt "entschärft", so dass ich bei der ausgabe des datensatzes folgendes bekomme:

    ___________________________________________
    Dies sind &#8222;Sonderzeichen&#8220;
    <?php echo 'Dies ist PHP Code'; ?>
    ___________________________________________

    Nein, das ist sicherlich nicht die Ausgabe von mysql_real_escape_string(htmlspecialchars($text)), zumindest nicht dann, wenn du es so gemacht hast, wie du es hier dargestellt hast. Dann müsste die Ausgabe (in den Quelltext gucken!) so aussehen:

    Dies sind „Sonderzeichen”
    &lt;?php echo 'Dies ist PHP Code'; ?&gt;

    Die Funktion htmlspecialchars() wandelt standardmäßig Größer- und Kleiner-Zeichen, sowie doppelte Anführungszeichen (die hier: ") in ihre entsprechenden HTML Entities um. mysql_real_escape_string() escaped Anführungszeichen, damit diese im SQL-Query korrekt maskiert sind.

    Du solltest htmlspecialchars() *nicht* benutzen, wenn du Daten in die Datenbank speicherst (sehr wohl jedoch mysql_real_escape_string()). Du sollst htmlspecialchars() bei der Ausgabe der Daten (als HTML) nutzen.

    Nutze ich aber htmlspecialchars nicht, so wird der eingegebene php-code bei der ausgabe ausgeführt.

    Nein, warum sollte der PHP-Code ausgeführt werden? Dazu gibt es keine Veranlassung… Du nutzt doch hoffentlich nirgendwo eval() oder?

    Viele Grüße,
      ~ Dennis.

    1. Also so sieht der Code aus:

        
      $text = htmlspecialchars($_GET['text']);  
        
        
      $sql = sprintf("INSERT INTO artikel (titel, inhalt, autor, datum, kategorie, aufrufe, tags) VALUES ('%s', '%s', '%s', '%s', '%s', 1, '%s')" ,   mysql_real_escape_string(checkPost($titel), $db),  
             mysql_real_escape_string(htmlspecialchars(checkPost($dummy)), $db),  
             mysql_real_escape_string(checkPost($autor), $db),  
             mysql_real_escape_string(checkPost($datum), $db),  
             mysql_real_escape_string(checkPost($kategorie), $db),  
             mysql_real_escape_string(checkPost($tags), $db));  
      
      
      1. Hi blaschi,

        $text = htmlspecialchars($_GET['text']);

        Wie ich bereits schrieb, möchtest du genau das nicht machen. Stell dir mal vor, du möchtest irgendwann mal die Daten aus der Datenbank per E-Mail verschicken. Jetzt hast du in der Datenbank die Daten aber so abgespeichert, dass diese bereits für die Ausgabe in einem HTML-Kontext korrekt maskiert sind. Das heißt aber gleichzeitig auch, dass die Daten für den Versand in einer Textmail *falsch* maskiert sind. In einer Textmail besteht kein Bedarf z.B. < als &lt; zu maskieren!

        Um die Daten jetzt trotzdem per Mail verschicken zu können, müsstest du sie erst wieder umwandeln - wenn die Daten allerdings von einem anderen Programmierer in die Datenbank gespeichert wurden, weißt du vielleicht gar nicht, wie die Daten kodiert wurden, folglich weißt du auch nicht, wie du diese korrekt dekodieren kannst.

        Aus diesem Grund solltest du dir folgendes angewöhnen: Speichere grundsätzlich Rohdaten in der Datenbank. In diesem konkreten Fall: Verwende *nicht* htmlspecialchars() vor dem Abspeichern der Daten.

        Bei der Ausgabe der Daten kodierst du diese dann natürlich korrekt, für HTML also beispielsweise:
        echo '<p>' . htmlspecialchars($data['inhalt']) . '</p>';

        $sql = sprintf("INSERT INTO artikel (titel, inhalt, autor, datum, kategorie, aufrufe, tags) VALUES ('%s', '%s', '%s', '%s', '%s', 1, '%s')" ,   mysql_real_escape_string(checkPost($titel), $db),
               mysql_real_escape_string(htmlspecialchars(checkPost($dummy)), $db),
               mysql_real_escape_string(checkPost($autor), $db),
               mysql_real_escape_string(checkPost($datum), $db),
               mysql_real_escape_string(checkPost($kategorie), $db),
               mysql_real_escape_string(checkPost($tags), $db));
        [/code]

        Was macht die mysteriöse Funktion checkPost()?

        Viele Grüße,
          ~ Dennis.

        1. Hallo Dennis,
          danke für deine Tipps.
          Ich werd mich mal weiter daran versuchen und gebe daraufhin ein Feedback.

          Was macht die mysteriöse Funktion checkPost()?

            
          function checkPost($wert)  
          {  
           if(get_magic_quotes_gpc())  
           {  
            return stripslashes($wert);  
           }  
           else  
           {  
            return $wert;  
           }  
          }  
          
          

          liebe Grüße
          Björn

          1. Das ist ja mal Interessant.

            hier mein Formular

              
            <form name="formular" method="post" action="<?php echo $PHP_SELF;?>">  
            <input type="text" name="eingabe" >  
            </form>  
            
            

            und hier meine Testabfrage:

              
            $dummy = $_POST["eingabe"];  
            if(file_put_contents('666.txt',$dummy))  
             die('Testdatei geschrieben');  
            
            

            Ratet mal, was bei dem Testtext
            -------------------------------------
            DIESE DOOFEN „“ und …  SONDERZEICHEN
            -------------------------------------
            in der Testdatei steht?

            ------------------------------------------------------
            DIESE DOOFEN &#8222;&#8220; und &#8230; SONDERZEICHEN
            ------------------------------------------------------

            Wo und wie wird das formatiert?
            Ich geb doch nirgens die Anweisung dazu?
            Hat das was mit dem Charset im HTML-Header zu tun ?

            liebe Grüße
            blaschi

            1. ok ich habs!

              Das Formular wurde in eine index.php included.
              Diese index.php hatte im Header iso-8859-15 als Charset.

              Dadurch wurde jede POST-Mitteilung automatisch in den iso-8859-15 Charset codiert.

              Gebe ich im Header Charset UTF8 ein, so funktioniert alles.

              liebe Grüße
              Björn