Hitzering: PHP Textarea - prüfen und pharsen

Hallo,

kurz zum aushohlen. Ich habe ein Array mit "Wörtern" und möchte bei einem vom Nutzer übergebenen Text (via Textarea), diesen anzeigen und die im Array genannten Wörter als Fett markieren.

In jedem PHP Buch, dass ich zu GET & POST gelesen habe steht, "vertraue niemals Daten von außen". Daher dachte ich

$data_html = filter_input(INPUT_GET, 'text', FILTER_SANITIZE_SPECIAL_CHARS);

$data_intern = filter_input(INPUT_GET, 'text', FILTER_SANITIZE_ENCODED);

müsste reichen, kann ich hier mehr tun?

  1. Tach!

    In jedem PHP Buch, dass ich zu GET & POST gelesen habe steht, "vertraue niemals Daten von außen". Daher dachte ich `$data_html = filter_input(INPUT_GET, 'text', FILTER_SANITIZE_SPECIAL_CHARS);

    Das ist meiner Ansicht nach der falsche Ansatz. Probleme entsteht nicht anhand der Herkunft von Daten, sondern dass sie am Zielort unpassend zusammengebaut werden. Zudem hat jeder Kontext seine eigenen Regeln, welche Zeichen in welcher Weise zu beachten / behandeln sind. Woher die Daten kommen, spielt dabei keine Rolle. Wenn du bereits am Eingang "saubere" Daten haben möchtest, bleiben quasi nur noch Buchstaben und Ziffern übrig, die meistens nicht behandelt werden müssen, weil sie nicht in dem einen oder anderen Kontext eine Sonderbedeutung haben.

    Mein Ansatz ist daher, am Eingang nur fachliche Prüfungen vorzunehmen, beispielsweise dass Wertebereiche eingehalten werden. Und wann immer Daten nach außen gehen, bekommen sie genau dann die für das Ziel passende Behandlung. Nicht eher. Für HTML ist das htmlspecialchars(), für SQL das, was die verwendete Datenbankschnittstelle vorsieht.

    $data_intern = filter_input(INPUT_GET, 'text', FILTER_SANITIZE_ENCODED);` müsste reichen, kann ich hier mehr tun?

    Die Frage ist: "wofür reichen?" Du kannst das am Eingang nicht wissen, wo überall die Daten landen werden. Es sei denn, dein Script besteht nur aus drei Zeilen, sozusagen.

    Mehr zum Thema: Kontextwechsel.

    dedlfix.

  2. $data_html = filter_input(INPUT_GET, 'text', FILTER_SANITIZE_SPECIAL_CHARS);
    

    Den "gesamten" Input auf diese generöse Weise zu filtern führt dazu, dass man sich hernach beim Programmieren grundlos "sicher" fühlt… Ich würde statt dessen zur individuellen Verwendung filter_var() raten. Oder, wie mein Vorredner ausführt die für den jeweiligen Kontext passenden Funktionen bzw. Methoden anwenden.

  3. Hallo Hitzering,

    der User gibt also irgendwas ein und du gibst es wieder aus. Was der User eingegeben hat, kann Dir eigentlich egal sein und du musst da auch nicht zwingend was ausfiltern. Du musst nur

    • beim Speichern in einer DB dafür sorgen, dass der Text korrekt für die DB escaped wird (oder mit einem Prepared Statement gespeichert wird)
    • beim Ausgeben auf den Browser dafür sorgen, dass der Text rein als Text dargestellt wird und im Browser keine Effekte auslöst (htmlspecialchars).

    Allerdings beißt sich Punkt 2 mit deinem Wunsch, etwas fett darzustellen. Wenn Du den eingegebenen Text durchsuchst und die gefundenen Wörter HTML Elementen einrahmst, würden die von Dir vergebenen HTML Tags ebenfalls von htmlspecialchars maskiert. Du musst also zuerst htmlspecialchars anwenden, und dann die gewünschten Wörter durch Fettschrift-Elemente einrahmen. Ob Du dafür b, em, strong oder mark nimmst, hängt von der semantischen Aussage ab - siehe die entsprechenden Texte im Selfwiki.

    Rolf

    --
    sumpsi - posui - clusi
    1. Hello Bernd,

      der User gibt also irgendwas ein und du gibst es wieder aus. Was der User eingegeben hat, kann Dir eigentlich egal sein und du musst da auch nicht zwingend was ausfiltern. Du musst nur

      • beim Speichern in einer DB dafür sorgen, dass der Text korrekt für die DB escaped wird (oder mit einem Prepared Statement gespeichert wird)
      • beim Ausgeben auf den Browser dafür sorgen, dass der Text rein als Text dargestellt wird und im Browser keine Effekte auslöst (htmlspecialchars).

      Allerdings beißt sich Punkt 2 mit deinem Wunsch, etwas fett darzustellen. Wenn Du den eingegebenen Text durchsuchst und die gefundenen Wörter HTML Elementen einrahmst, würden die von Dir vergebenen HTML Tags ebenfalls von htmlspecialchars maskiert. Du musst also zuerst htmlspecialchars anwenden, und dann die gewünschten Wörter durch Fettschrift-Elemente einrahmen. Ob Du dafür b, em, strong oder mark nimmst, hängt von der semantischen Aussage ab - siehe die entsprechenden Texte im Selfwiki.

      Grundsätzlich muss vor jeder Interpretation von Daten, die zu aktiven Handlungen bzw. Einfluss auf aktive Systeme führen kann, der Text geprüft und gefiltert werden.

      Das Problem hätte man nicht, wenn man von Anfang an Befehls- und Datenstrom getrennt gehalten hätte und dort nicht "Umschaltmöglichkeiten" geschaffen hätte. Ein Hauptverursacher hierfür ist C mit allen seinen Folgeentwicklungen. Bei Pascal und TurboPascal und seinen Folgeentwicklungen war die Vermischung nicht ohne aktive Programmierung möglich.

      Glück Auf
      Tom vom Berg

      --
      Es gibt nichts Gutes, außer man tut es!
      Das Leben selbst ist der Sinn.
      1. Hallo Tom,

        Das Problem hätte man nicht, wenn man von Anfang an Befehls- und Datenstrom getrennt gehalten hätte und dort nicht "Umschaltmöglichkeiten" geschaffen hätte. Ein Hauptverursacher hierfür ist C mit allen seinen Folgeentwicklungen. Bei Pascal und TurboPascal und seinen Folgeentwicklungen war die Vermischung nicht ohne aktive Programmierung möglich.

        jetzt erklär mir doch bitte mal, was hier aus deiner Sicht der entscheidende Unterschied zwischen C und Pascal ist. Ich kenne beide Sprachen (habe aber etwa 20 Jahre keinen Pascal-Code mehr geschrieben), und betrachte sie gerade im Bezug auf das Handling von Daten als weitgehend gleichwertig.

        Ja, Pascal hat eine strengere Syntax und erzwingt klarere Strukturen, aber den wichtigen Unterschied, den du hier anteaserst, sehe ich nicht.

        Ciao,
         Martin

        --
        Ein Tag, an dem du nicht wenigstens einmal gelacht hast, ist ein verlorener Tag.
        1. Hello Martin,

          Das Problem hätte man nicht, wenn man von Anfang an Befehls- und Datenstrom getrennt gehalten hätte und dort nicht "Umschaltmöglichkeiten" geschaffen hätte. Ein Hauptverursacher hierfür ist C mit allen seinen Folgeentwicklungen. Bei Pascal und TurboPascal und seinen Folgeentwicklungen war die Vermischung nicht ohne aktive Programmierung möglich.

          jetzt erklär mir doch bitte mal, was hier aus deiner Sicht der entscheidende Unterschied zwischen C und Pascal ist. Ich kenne beide Sprachen (habe aber etwa 20 Jahre keinen Pascal-Code mehr geschrieben), und betrachte sie gerade im Bezug auf das Handling von Daten als weitgehend gleichwertig.

          Ja, Pascal hat eine strengere Syntax und erzwingt klarere Strukturen, aber den wichtigen Unterschied, den du hier anteaserst, sehe ich nicht.

          Pascal kennt von Haus aus keine Escapesequenzen in seinen Datenströmen. Das könnte man vielleicht auch mit dem Unterschied von Harvard- zu von-Neumann-Architektur vergleichen.

          Abgesehen von Fehlern, wie Stackoverflow, Rangebreak, usw. ist es bei Pascal daher nicht möglich, "Nutzdaten" als Code einzuschleusen. Programmiererwahnsinn mal außen vor gelassen ;-)

          Speziell alle Interpretersprachen (wie z. B. eine SQL-Textschnittstelle) sind hingegen anfällig dafür.

          Die Geister die man für mehr Bequemlichkeit rief, rächen sich nun.

          Glück Auf
          Tom vom Berg

          --
          Es gibt nichts Gutes, außer man tut es!
          Das Leben selbst ist der Sinn.
          1. Hallo,

            Ja, Pascal hat eine strengere Syntax und erzwingt klarere Strukturen, aber den wichtigen Unterschied, den du hier anteaserst, sehe ich nicht.

            Pascal kennt von Haus aus keine Escapesequenzen in seinen Datenströmen.

            was genau meinst du damit? Steuerzeichen als Escape-Sequenzen in Strings? Ja, die gibt's in C. Aber damit ist noch lange keine Vermischung von Daten und Programmcode gegeben.

            Oder verstehe ich deinen Punkt immer noch nicht?

            Speziell alle Interpretersprachen (wie z. B. eine SQL-Textschnittstelle) sind hingegen anfällig dafür.

            Da fällt C aber nicht darunter.

            Bye,
             Martin

            --
            Ein Tag, an dem du nicht wenigstens einmal gelacht hast, ist ein verlorener Tag.
            1. Hallo Martin,

              Ja, Pascal hat eine strengere Syntax und erzwingt klarere Strukturen, aber den wichtigen Unterschied, den du hier anteaserst, sehe ich nicht.

              Pascal kennt von Haus aus keine Escapesequenzen in seinen Datenströmen.

              was genau meinst du damit? Steuerzeichen als Escape-Sequenzen in Strings? Ja, die gibt's in C. Aber damit ist noch lange keine Vermischung von Daten und Programmcode gegeben.

              Ich glaube, TS unterliegt der (irrigen) Annahme, dass weil es keine Escape-Sequenzen gibt, man dem Programm keinen Mist vor die Füße werfen kann.

              Das ist natürlich nicht wahr. Ob ich die Bytes mit Escape-Sequenzen erzeuge oder ob ich sie mit CHR() erzeuge ist irrelevant – natürlich kann ich auch einem Pascal-Programm eine falsche Rücksprungadresse oder sogar x86-Maschinencode unterjubeln, wenn ein entsprechender Fehler (z.B. ein Out-Of-Bounds-Write) vorliegt. Das ist ein Problem der Rechner-Architektur, nicht der Programmiersprache.

              Speziell alle Interpretersprachen (wie z. B. eine SQL-Textschnittstelle) sind hingegen anfällig dafür.

              Da fällt C aber nicht darunter.

              Es hat vor allem mit „Interpretersprache“ nichts zu tun. Das ist eine konzeptionelle Frage. Wenn ich den SQL-String mit String-Konkatenation zusammenbaue, bin ich potentiell immer anfällig für SQL-Injections. Ob interpretiert oder kompiliert ist dabei irrelevant.

              LG,
              CK