Berlinn: Frage wegen htmlspecialchars, ENT_QUOTES

Hallo Experten,

habe eine frage zu htmlspecialchars, ENT_QUOTES.

Ich erstelle gerade ein Affenformular und jetzt ist mir folgendes aufgefallen bei der Eingabe von bestimmten Zeichen!

Beispiel:

Das:
<

wird in dieses umgewandelt:
&lt;

Die Umwandlung ist richtig, nur es könnte ja mal sein das ein User noch irgendetwas vergessen hat zu schreiben und das Formular hat ihn darauf mit einer Fehlermeldung aufmerksam gemacht wie z.B.: Bitte geben Sie auch  Ihren Namen ein. Wenn der User jetzt besoffen ist ;-) und tippt in seinen Namen zahlen rein, lädt sich das Formular wieder mit einer neuen angezeigten Fehlermeldung wie: Bitte nur Buchstaben etc. pp.

Jetzt wurde aber aus dem &lt; das hier: &amp;lt; und wenn man es wiederholt dann kommt das: &amp;amp;lt;

Im Internet habe ich leider nichts darüber gefunden obwohl ich schon einiges in Google an Suchbegriffen eingegeben habe!

Ist die Erweiterung normal oder liegt es daran das ich die Usereingaben noch nicht in einem Array gespeichert habe?

Danke für eure antwort!

MfG,

Berlinn

  1. Hi Berlinn,

    und wieso verwendest Du bei der Vorschauausgabe als vordefinierte Werte in Deinem Formular nicht einfach das $_POST['foo']? Es reicht ja, wenn Du htmlspecialchars für die Ausgabe verwendest. Für die Wertbelegung Deiner Formularfelder ist das irrelevant.

    Mit lieben Grüßen aus Wien

    Michi

    --
    Self-Code: ie:{ fl:| br:> va:} ls:# fo:| rl:° n4:# ss:| de:> js:{ ch:? mo:) zu:}
    Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    It is nice to be important - but it is more important to be nice.
    1. Moin!

      und wieso verwendest Du bei der Vorschauausgabe als vordefinierte Werte in Deinem Formular nicht einfach das $_POST['foo']? Es reicht ja, wenn Du htmlspecialchars für die Ausgabe verwendest. Für die Wertbelegung Deiner Formularfelder ist das irrelevant.

      Das ist falsch!

      Nehmen wir mal eine einfache Textarea.

      <textarea cols="20" rows="5" name="nachricht"></textarea>

      Wenn das als Affenformular genutzt werden soll, dann gehört es sich, dass der eingegebene Text durch htmlspecialchars() durchgejagt wird, andernfalls ist das die Einladung, um das HTML der Seite kaputtmachen zu können.

      echo '<textarea cols="20" rows="5" name="nachricht">'.htmlspecialchars($_POST['nachricht'].'</textarea>';

      Wenn man das nicht tut, hat man ein Problem. Innerhalb der Textarea gelten bekanntlich keine HTML-Tags, deshalb wirken beispielsweise die Zeichen < und > nicht - bis auf dann, wenn man den String "</textarea>" in der Nachricht geschrieben hat.

      Die Nichtwirkung der HTML-Tags ist nur freundliche Fehlerkorrektur des Browsers. In Wirklichkeit dürfen sie dort gar nicht auftauchen. Deshalb die Umwandlung in Entities.

      Dem Affenformular macht das gar nichts. Die Entities im HTML-Quelltext werden vom Browser zurück in die damit gemeinten Originalzeichen gewandelt, wenn er den Quelltext geparst und dargestellt hat. Im Formular sind also keine Entities mehr gespeichert und werden auch nicht abgesendet.

      Deshalb wird es niemals zu Entity-Verkettungen der Art &amp;amp;amp;lt; kommen, wenn man das Affenformular mehrfach falsch absendet.

      Für <input>-Elemente gilt sinngemäß dasselbe, hier ist das Anführungszeichen das böse Zeichen, und man kann selbstverständlich ebenfalls beliebig HTML und Javascript hinzufügen, wenn das Escaping unterbleibt.

      - Sven Rautenberg

      1. Hi Sven,

        Du hast selbstverständlich uneingeschränkt Recht! Ich hab wegen der ursprünglichen Problembeschreibung in die völlig falsche Richtung gedacht. Mea culpa!

        Ein auf die schnelle geschriebenes Affenformular belegt dies.

        Mit lieben Grüßen aus Wien

        Michi

        --
        Self-Code: ie:{ fl:| br:> va:} ls:# fo:| rl:° n4:# ss:| de:> js:{ ch:? mo:) zu:}
        Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        It is nice to be important - but it is more important to be nice.
        1. Hallo dedlfix, MichiN und Sven Rautenberg,

          verspätet bedanke ich mich bei euch für eure Infos!

          Gruß,

          Berlinn

          1. Nehmen wir mal eine einfache Textarea.

            <textarea cols="20" rows="5" name="nachricht"></textarea>

            Wenn das als Affenformular genutzt werden soll, dann gehört es sich, dass der eingegebene Text durch htmlspecialchars() durchgejagt wird, andernfalls ist das die Einladung, um das HTML der Seite kaputtmachen zu können.

            echo '<textarea cols="20" rows="5" name="nachricht">'.htmlspecialchars($_POST['nachricht'].'</textarea>';

            Wenn man das nicht tut, hat man ein Problem. Innerhalb der Textarea gelten bekanntlich keine HTML-Tags, deshalb wirken beispielsweise die Zeichen < und > nicht - bis auf dann, wenn man den String "</textarea>" in der Nachricht geschrieben hat.

            Die Nichtwirkung der HTML-Tags ist nur freundliche Fehlerkorrektur des Browsers. In Wirklichkeit dürfen sie dort gar nicht auftauchen. Deshalb die Umwandlung in Entities.

            Dem Affenformular macht das gar nichts. Die Entities im HTML-Quelltext werden vom Browser zurück in die damit gemeinten Originalzeichen gewandelt, wenn er den Quelltext geparst und dargestellt hat. Im Formular sind also keine Entities mehr gespeichert und werden auch nicht abgesendet.

            Deshalb wird es niemals zu Entity-Verkettungen der Art &amp;amp;amp;lt; kommen, wenn man das Affenformular mehrfach falsch absendet.

            Für <input>-Elemente gilt sinngemäß dasselbe, hier ist das Anführungszeichen das böse Zeichen, und man kann selbstverständlich ebenfalls beliebig HTML und Javascript hinzufügen, wenn das Escaping unterbleibt.

            • Sven Rautenberg

            Hallo Sven Rautenberg,

            zu deiner Erklärung hätte ich noch zwei kleine fragen.

            1. Verstehe ich das richtig wenn jemand solch einen Code:

            <script>alert('document.cookie')</script>

            ins Textfenster schreibt und das wird in der Textarea durch:

            .htmlspecialchars($_POST['nachricht'].

            sowie in der eigentlichen Prüfung mit:

            if (isset($_POST['nachricht']) && !empty($_POST['nachricht']))
              {
               $neuenachricht = trim(htmlspecialchars($_POST['nachricht']));
                 }

            durchgejagt, dann wird das alert Script zwar nicht ausgeführt aber behält immer noch seine eigentliche Form, also ausgegeben wird es Entschärft in der gesendeten E-Mail so?

            <script>alert('document.cookie')</script>

            2. Ist es Sinnvoll hier noch ENT_QUOTES zu setzen?
            Fast vergessen, bei mir ist Magic Quotes deaktiviert!

            Danke und Gruß,

            Berlinn

            1. Moin!

              »» Nehmen wir mal eine einfache Textarea.
              »»
              »» <textarea cols="20" rows="5" name="nachricht"></textarea>
              »»
              »» Wenn das als Affenformular genutzt werden soll, dann gehört es sich, dass der eingegebene Text durch htmlspecialchars() durchgejagt wird, andernfalls ist das die Einladung, um das HTML der Seite kaputtmachen zu können.
              »»
              »» echo '<textarea cols="20" rows="5" name="nachricht">'.htmlspecialchars($_POST['nachricht'].'</textarea>';

              1. Verstehe ich das richtig wenn jemand solch einen Code:

              <script>alert('document.cookie')</script>

              Das ist genau der Code, den man als Demo für "bösen" Code annehmen kann. Wenn sowas ungefiltert durchgereicht wird, und man das Alert-Fenster sieht, hat man (als Seitenbesucher bzw. als Programmierer der Seite) verloren.

              ins Textfenster schreibt und das wird in der Textarea durch:

              .htmlspecialchars($_POST['nachricht'].

              In der Textarea erscheint, ohne dass der Code wirksam würde, einfach der oben genannte String. Der sieht als "Text" seltsam aus für das uninformierte Publikum, aber so ist das Leben. Der String "jkghjkgsd786sbjhl" sieht auch seltsam aus.

              sowie in der eigentlichen Prüfung mit:

              if (isset($_POST['nachricht']) && !empty($_POST['nachricht']))
                {
                 $neuenachricht = trim(htmlspecialchars($_POST['nachricht']));
                }

              Ich bin immer ein großer Freund von Escaping im letzten Augenblick. Also direkt bei der Ausgabe bzw. der Integration in einen qualitativ anderen String (z.B. den fertigen SQL-Query).

              Der Grund ist relativ leicht: Wenn ich ALLE Ausgaben mit Escaping versehe, dann fällt es mir sehr deutlich auf, wenn an einer Stelle mal KEIN Escaping existiert, und ich werde diese Stelle genauer betrachten müssen.

              durchgejagt, dann wird das alert Script zwar nicht ausgeführt aber behält immer noch seine eigentliche Form, also ausgegeben wird es Entschärft in der gesendeten E-Mail so?

              Das ist ja gerade der gewünschte Effekt: Wenn der Benutzer den Text "<script>" eingibt, dann soll dieser Text grundsätzlich identisch erhalten bleiben, wenn er wieder ausgegeben wird. Genau das geschieht ja.

              <script>alert('document.cookie')</script>

              Mission erfüllt.

              Wobei ich in Bezug auf EMail meine Hand für nichts ins Feuer legen würde. Mailclients sind Meister im Interpretieren. Einerseits hat man heutzutage wohl nirgendwo mehr Mailclients, die ungefragt Javascript in Mails ausführen, andererseits ist EMail inhaltlich so ein Wildwuchs, dass da alle möglichen Konstruktionen bzw. nachgeschalteten Textformatierer zuschlagen könnten.

              Außerdem könnte es ja sein, dass du absichtlich gewisse Teilstrings aus dem eingegebenen Text herausfiltern willst, einfach weil du diese Strings nicht im Text stehen haben willst. Das ist aber eine andere Aufgabe und hat mit Escaping erstmal nichts zu tun. Filterung ersetzt kein Escaping! Selbst dann, wenn die Filterung eigentlich sicherstellen sollte, dass keine bösen Zeichen entstehen können, würde ich nie auf Escaping verzichten wollen, weil es die einfachste Methode ist, die Sicherheit zu erhöhen. Und wenn grundsätzlich jede Ausgabe escaped wird, fallen die Stellen ins Auge, wo das Escaping fehlt - und der Fehler kann behoben werden.

              1. Ist es Sinnvoll hier noch ENT_QUOTES zu setzen?
                Fast vergessen, bei mir ist Magic Quotes deaktiviert!

              Magic_quotes_gpc sind ein ekliges Feature, welches mal erfunden wurde, um "Sicherheit" zu produzieren, wenn man Datenbanken benutzt. Dummerweise ist das automatische Escaping von magic_quotes_gpc nicht ausreichend: Es zielt ausschließlich auf MySQL ab (bzw. andere Datenbanken, die den Backslash als Escape-Zeichen nutzen - das ist aber nicht überall so), es werden aber nicht alle Zeichen behandelt, die MySQL gefährlich werden könnten, und es stört in vielen anderen Anwendungsfällen, in denen man tatsächlich den reinen Text benötigt, ohne Escapes.

              Wegen dieses sehr zweifelhaften Nutzens ist magic_quotes_gpc() seit PHP Version 5.3.0 deprecated, in PHP 6 wird es komplett entfernt werden, und es ist in der empfohlenen PHP-Konfiguration deaktiviert.

              Was ENT_QUOTES angeht: Hängt von deinen konkreten Anforderungen ab. Wenn du Attributwerte in einfachen Anführungszeichen einschließt, darf der escapte String diese natürlich nicht mehr enthalten. Da wäre ENT_QUOTES also notwendig. Stehen die Attributwerte in doppelten Anführungszeichen, ist ENT_QUOTES nicht zwingend notwendig, stört aber auch nicht.

              - Sven Rautenberg

              1. Hallo Sven Rautenberg,

                danke, danke und nochmals danke! :-)

                Freundliche Grüße,

                Berlinn

  2. echo $begrüßung;

    Jetzt wurde aber aus dem &lt; das hier: &amp;lt; und wenn man es wiederholt dann kommt das: &amp;amp;lt;

    Dann hast du eine doppelte HTML-Maskierung eingebaut oder eine an einer Stelle, an der du einen anderen Kontext vorliegen hast. Wenn du konsequent das EVA-Prinzip beachtest, dann kann das nicht passieren. Eingabedaten werden gegebenenfalls in Rohform umgewandelt, verarbeitet wird die Rohform und erst direkt bei der Ausgabe wird kontextgerecht kodiert.

    Unter PHP sind normalerweise die Eingabedaten in $_GET und $_POST bereits dekodiert. Nur das Feature Magic Quotes kann hier querschießen, aber dessen Symptome beschreibst du nicht.

    echo "$verabschiedung $name";