Ankündigung

Einklappen
Keine Ankündigung bisher.

Tipp: gefährliche Attribute aus Tags entschärfen (XSS verhindern)

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

  • Scriptangebot Tipp: gefährliche Attribute aus Tags entschärfen (XSS verhindern)

    Hallo,

    man kann eine auszugebende HTML Menge ja recht gut mit striptags() säubern. Aber manchmal geht das eben nicht gut, weil man einige Tags durchaus gut findet. Natürlich kann man die guten Tags stehen lassen, aber was passiert, wenn ein <img>-Tag nebenbei das macht:

    Code:
    <img src="notknown.jpg" onerror="alert(1);">
    Dann kann das Bild nicht geladen werden und das onerror-Attribut wird getriggert. Schon läuft JavaScript...

    Das selbe gilt theoretisch für alle Attribute in allen Tags. Daher hab ich eine Filter-Routine gemacht, welche hier mehr Sicherheit schafft.

    ACHTUNG: Das bietet keine alleinige Sicherheit! Man muss Tags wie zB <script> noch selbst entfernen (Tipp: striptags() Funktion von PHP). Es macht dann Sinn, wenn man bestimmte Tags (zB <form>, <input >, <img > etc.) behalten möchte. In dem Fall kann man mit dieser Funktion die verbliebenen Tags ganz einfach unschädlich machen.

    Will das nicht vorenthalten, also bitte:

    PHP-Code:
    /**
    * Replaces all dangerous attributes from the html-tags in this document.
    * Example:
    * <img src="a.jpg" onerror="alert(1)" onload="alert(1)"> will get
    * <img src="a.jpg" s5T38IwgH="alert(1)" s5T38IwgH="alert(1)">
    *
    * @param string $input document to clean
    * @return string clean document
    */
    function secureHTMLAttributes($input) {
        
    // this attributes will get neutralized
        
    $Attributes = Array("onabort""onblur","onchange","onclick""ondblclick","onerror","onfocus""onkeydown",
                            
    "onkeypress","onkeyup","onload","onmousedown","onmousemove","onmouseout","onmouseover",
                            
    "onmouseup","onreset","onselect","onsubmit","onunload","javascript:","javascript :",
                            
    "eval""script:""script :");

        
    $output "";
        for (
    $i=0;$i<=strlen($input);$i++){
            
    $char substr($input$i1);

            if (
    $char == ">") { $inside $inside 1; }

            if (
    $inside 1) {
                if (
    $found != "") {
                    
    // check the content of the tag
                    
    $found str_ireplace($Attributes"s".GenerateCode(6), $found);
                }
                
    $output .= $found $char;
                
    $found "";
            } else {
                
    $found .= $char;
            }

            if (
    $char == "<") { $inside $inside 1; }
        }

        return 
    $output;

    Und hier noch der Code für den verwendeten Zufallsgenerator:
    PHP-Code:
    function GenerateCode($Length) {
        
    $Code "";
        for (
    $x 1$x <= $Length$x++) {
            if (
    rand(1,100) < 51 ){
                
    // number
                
    $Code $Code rand(0,9);
            } else {
                
    // char
                
    if (rand(1,100) < 50) {
                    
    // lowercase
                    
    $Zeichen strtolower(chr(rand(65,90)));
                    
    $Code $Code $Zeichen;
                } else {
                    
    // uppercase
                    
    $Zeichen chr(rand(65,90));
                    
    $Code $Code $Zeichen;
                }
            }
        }
        return 
    $Code;


    Die folgenden Attribute werden innerhalb von beliebigen Tags entschärft, indem sie durch Zufallsbezeichner ersetzt werden:
    onabort (bei Abbruch)
    onblur (beim Verlassen)
    onchange (bei erfolgter Änderung)
    onclick (beim Anklicken)
    ondblclick (bei doppeltem Anklicken)
    onerror (im Fehlerfall)
    onfocus (beim Aktivieren)
    onkeydown (bei gedrückter Taste)
    onkeypress (bei gedrückt gehaltener Taste)
    onkeyup (bei losgelassener Taste)
    onload (beim Laden einer Datei)
    onmousedown (bei gedrückter Maustaste)
    onmousemove (bei weiterbewegter Maus)
    onmouseout (beim Verlassen des Elements mit der Maus)
    onmouseover (beim Überfahren des Elements mit der Maus)
    onmouseup (bei losgelassener Maustaste)
    onreset (beim Zurücksetzen des Formulars)
    onselect (beim Selektieren von Text)
    onsubmit (beim Absenden des Formulars)
    onunload (beim Verlassen der Datei)
    javascript: (bei Verweisen)
    script:
    eval


    Achtung, das arbeitet auch innerhalb von HTML Kommentaren etc. Das sollte bei der Ausgabe aber ja nicht stören...

    Wenn es jemand erweitern oder verbessern möchte, dann gerne Bitte hier untendran posten.

    Donald


  • #2
    Ehöö, wenn ich das richtig verstehe, wird aus <img src="" onblur="" /> ein <img src="" fdwef="" /> ... aua, das tut doch jeden Validator weh... Wieso dann nicht gleich entfernen.

    Außerdem gibt es doch schon weitaus komplexere Filterklassen: http://htmlpurifier.org/

    Kommentar


    • #3
      Achso außerdem wirft das Script bei mir haufen Notices und was bringt es mir, wenn Sachen, die direkt JS einbinden, z.B. '<script>...</script>' drinnen lässt?

      Kommentar


      • #4
        Man sollte ganz einfach kein HTML erlauben! Wenn du bestimmte Formatierungen oder ähnliches ermöglichen willst dann nutz BBCodes. Ansonsten wäre mir das Risiko viel zu groß dass irgendwo eine XSS Lücke entstehen könnte. Bei deinem Skript würd ich auch nicht 100% sagen das es sicher ist ...

        Kommentar


        • #5
          Hallo,

          es soll ja nicht die Tags entfernen (das können andere Funktionen besser). Das ist nicht Sinn der Routine, deshalb ist der Name auch secureHTMLAttributes(). Und ja, das macht Tags draus, die ein Validator nicht mag (weil er die nicht kennt). Allerdings führt die auch kein Browser aus, und damit werden diese unschädlich. Das Validator-Thema ist der Preis dafür.

          Den htmlpurifier kenne ich, aber das ist mit Kanonen auf Spatzen geschossen. Ich wollte nur die gefährlichen Attribute entschärfen. Und das macht die Routine. striptags kann doch jeder nach eigenem Gusto selbst verwenden...

          Es ist nur ein Teil eines Sicherheits-Konzeptes, keine AllesInAllem Lösung (hab ich aber auch nicht so verkauft)!

          [EDIT] Vielleicht nochmal zum Verständnis: Das ist keine Funktion, die man alleine zur Absicherung nutzen kann. Es ist ein Bestandteil, der XSS aus Tag-Attributen verhindern soll!

          Zweite Anmerkung: Das ist ja nicht für regulären HTML-Code gedacht, sondern für Fälle in denen Daten von Usern ausgegeben werden sollen. Und um hier einen Schutz einzubauen sollte man Tags filtern und, für den Fall dass man manche Tags beibehalten möchte, diese Routine von mir verwenden.

          Hab jetzt oben einen Hinweis eingefügt![/EDIT]

          Donald

          Kommentar


          • #6
            Ja das stimmt ja, aber was für einen Sinn hat es, das Attribut zu maskieren? Da kann es doch auch gleich entfernt werden.

            Außerdem würde ich immer eine Whitelist anstatt einer Blacklist verwenden. Was ist, wenn in 2 Jahren ein neues Attribut Namens onSomethingNew dazukommt?

            Desweiteren ist es, wie gesagt, trotz allem nicht sicher: <script> und ähnliche "Javascripteinleiter" kann verwendet werden. Und auch das href Attribut kann Javascript ausführen.

            Kommentar


            • #7
              Warum sollte man den seinen Benutzern ein paar wenige HTML Tags zulassen? Wieso dann nicht gleich BBCode nutzen und somit nicht mehr die Probleme zu haben.

              Kommentar


              • #8
                Zitat von Donald Beitrag anzeigen
                Und ja, das macht Tags draus, die ein Validator nicht mag (weil er die nicht kennt). Allerdings führt die auch kein Browser aus, und damit werden diese unschädlich. Das Validator-Thema ist der Preis dafür.
                Schon allein damit - absolutes fail.
                Fehlerhaftes HTML erstellen, um die Sicherheit zu erhöhen - absoluter Unfug.
                Zumal theoretisch nicht ausgeschlossen ist, dass deine „Zufallsfunktion“ wiederum Attribute erstellt, die es in HTML tatsächlich gibt - und damit sogar den Sinn des HTML-Codes entscheidend verändern könnte.

                Wenn es jemand erweitern oder verbessern möchte, dann gerne
                Das ist schon vom Konzept her totaler Quark.
                Daher, die einzig angebrachte „Verbesserung“: Tonne auf, Script rein, Tonne zu.

                Kommentar


                • #9
                  Code:
                  <a title=">" href="javascript:alert('XSS');">Klick</a>
                  Geht unbeschadet durch deine Sicherung durch...

                  Code:
                  <img title=">"  alt="" src="gibtsnet.png" onerror="alert('XSS')" />
                  Das Ganze geht auch ohne das der User was machen muss...

                  Fazit: Dein Code ist suboptimal...
                  Signatur:
                  PHP-Code:
                  $s '0048656c6c6f20576f726c64';
                  while(
                  $i=substr($s=substr($s,2),0,2))echo"&#x00$i;"

                  Kommentar


                  • #10
                    Schau mal: In diesem Forum kann man ganz schlimme Sachen posten, und dennoch passiert nichts:

                    <script alert('XSS')>

                    Und dabei kannte der Programmierer deine Funktion noch gar nicht...
                    PHP-Code:
                    if ($var != 0) {
                      
                    $var 0;

                    Kommentar


                    • #11
                      Wie oft wolllt ihr eigentlich das Anti-XSS Rad noch neu erfinden ?

                      Dein Script lässt javascript over included css, javascript over linked css aus, deine methode ist sinnlos.
                      [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
                        Probier mal
                        PHP-Code:
                        echo htmlspecialchar($gefaehrliches_zeuchs); 
                        PHP-Code:
                        if ($var != 0) {
                          
                        $var 0;

                        Kommentar


                        • #13
                          Zitat von Wolla Beitrag anzeigen
                          Probier mal
                          PHP-Code:
                          echo htmlspecialchar($gefaehrliches_zeuchs); 
                          Hast du seinen Beitrag gelesen? Für mich kam das so rüber, dass er HTML zulassen will, aber die gefährlichen Sachen rausfiltern will und da kommt er mit einem fetten htmlspecialchars nicht weit...
                          Signatur:
                          PHP-Code:
                          $s '0048656c6c6f20576f726c64';
                          while(
                          $i=substr($s=substr($s,2),0,2))echo"&#x00$i;"

                          Kommentar


                          • #14
                            Hallo,

                            ich verschiebe den Beitrag mal in die Skriptbörse.
                            "Mein Name ist Lohse, ich kaufe hier ein."

                            Kommentar


                            • #15
                              Ich hab schon vor 10 Jahren mit Zeugs herumexperimentiert mit postings wie
                              HTML-Code:
                              <img src="http://example.org/img/tits.jpg">
                              um dann nach ein paar tagen im img-Ordner per htaccess die jpgs zu verbiegen:
                              Code:
                              RewriteEngine On 
                              RewriteRule ^(.*).jpg$ jpg.php?seite=$1
                              Die jpg.php hat dann den Aufruf gezählt und danach das an den Browser ausgegeben, was ich wollte.
                              Insofern halte ich jede HTML-Möglichkeit, die man einem user auf der eigenen Seite einräumt für potentiell gefährlich.
                              PHP-Code:
                              if ($var != 0) {
                                
                              $var 0;

                              Kommentar

                              Lädt...
                              X