Ankündigung

Einklappen
Keine Ankündigung bisher.

BBCode - HTML-Umwandlung und XSS-Protection

Einklappen

Neue Werbung 2019

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

  • BBCode - HTML-Umwandlung und XSS-Protection

    Hallo,

    aktuell arbeite ich für meine Issue-Tracker-Applikation an den Eingabeformularen für Benutzer. Um XSS grundsätzlich zu vermeiden habe ich bereits von Anfang an auf BBCodes gesetzt. Nun habe ich aber festgestelllt, dass meine Klasse trotz allem nicht 100% sicher ist, kann den Fehler jedoch selbst nicht finden.

    Es geht mir darum, dass aus dem BBCode HTML generiert wird und das es keine Angriffe durch XSS geben kann.

    PHP-Code:
    <?php
    class bbcode
    {
        public static function 
    parseToHTML($input)
        {
            
    $input htmlentities($inputENT_QUOTES);
            
    $input strip_tags($input);
            
    $input str_replace("[b]""<b>"$input);
            
    $input str_replace("[/b]""</b>"$input);
            
    $input str_replace("[i]""<i>"$input);
            
    $input str_replace("[/i]""<i>"$input);
            
    $input str_replace("[u]""<u>"$input);
            
    $input str_replace("[/u]""</u>"$input);
            
    $input str_replace('\r\n',"<br>",$input);
            
    $input str_replace('\r',"<br>",$input);
            
    $input str_replace("[img]../../js/""[img]/js/"$input);
            
    $input preg_replace('/\[url=([^() ]+).*\]([^\]].*)\[\/url\]/''<a href="$1">$2</a>'$input);
            
    $input preg_replace('/\[color=([^ ]+).*\]([^\]].*)\[\/color\]/''<font color="$1">$2</font>'$input);
            
    $input preg_replace('/\[img\]([^\]].*)\[\/img\]/''<img src="$1" />'$input);
            
    $input preg_replace('/\[quote\]([^\]].*)\[\/quote\]/''<div class="quote">$1</div>'$input);
            
    $input preg_replace('/\[code\]([^\]].*)\[\/code\]/''<div class="code">$1</div>'$input);
            
    $input str_replace("[img]"'<img src="'$input);
            
    $input str_replace("[/img]"'" />'$input);
            
    $input str_replace("]<img"'"><img'$input);
            
    $input str_replace('[/img">''" />'$input);
            
    $input str_replace('javascript:'''$input);
            return 
    $input;
        }
    }
    Danke im Voraus,
    Simon Strasser

  • #2
    Zitat von DerApfel Beitrag anzeigen
    Nun habe ich aber festgestelllt, dass meine Klasse trotz allem nicht 100% sicher ist, kann den Fehler jedoch selbst nicht finden.
    Und wie hast du das festgestellt? Irgendeinen Anhaltspunkt musst du doch selber haben.
    [IMG]https://g.twimg.com/twitter-bird-16x16.png[/IMG][URL="https://twitter.com/fschmengler"]@fschmengler[/URL] - [IMG]https://i.stack.imgur.com/qh235.png[/IMG][URL="https://stackoverflow.com/users/664108/fschmengler"]@fschmengler[/URL] - [IMG]http://i.imgur.com/ZEqflLv.png[/IMG] [URL="https://github.com/schmengler/"]@schmengler[/URL]
    [URL="http://www.schmengler-se.de/"]PHP Blog[/URL] - [URL="http://www.schmengler-se.de/magento-entwicklung/"]Magento Entwicklung[/URL] - [URL="http://www.css3d.net/"]CSS Ribbon Generator[/URL]

    Kommentar


    • #3
      Es ist z.B. nach wie vor möglich onclick="" zu setzen. Natürlich könnte ich jetzt onclick="" rausfiltern, was jedoch auch nur begrenzt helfen würde, da es ja noch mehr von der Sorte gibt.

      Des Weiteren habe ich irgendetwas über Encoding-Zeugs gehört, welches meine Abfragen umgehen würde, jedoch im Browser des Users wieder korrekt angezeigt werden würde. - Da ich jedoch nicht mehr weiß, wo ich das gelesen hatte, habe ich die Hoffnung das jemand aus dem Forum es wissen könnte.

      Kommentar


      • #4
        Eine Sammlung möglicher Angriffsvektoren findet sich z.B. hier XSS (Cross Site Scripting) Cheat Sheet. Aber die Frage von fab bleibt natürlich: Welcher Vektor ist dir denn aufgefallen, der nicht verhindert wird?

        Kommentar


        • #5
          Kritisch sind da deine URL, COLOR und IMG Codes. Z.B. lassen sich hier

          Code:
          ([^() ]+)
          Tabulatoren oder Zeilenumbrüche als Whitespace einschmuggeln (Den Sinn von .* hinter dem geklammerten Ausdruck bezweifle ich auch aber das verarbeitest du zumindest nicht)

          Um sämtliche Whitespaces zu verbieten, ändere es so:

          Code:
          (\S+)
          (warum eigentlich keine Klammern in der URL?)

          Edit: Anführungszeichen musst du natürlich auch ausschließen, allerdings filterst du die ja schon vorab mit htmlentities, eine Ahnung, wie sie trotzdem hindurchkommen konnten?
          [IMG]https://g.twimg.com/twitter-bird-16x16.png[/IMG][URL="https://twitter.com/fschmengler"]@fschmengler[/URL] - [IMG]https://i.stack.imgur.com/qh235.png[/IMG][URL="https://stackoverflow.com/users/664108/fschmengler"]@fschmengler[/URL] - [IMG]http://i.imgur.com/ZEqflLv.png[/IMG] [URL="https://github.com/schmengler/"]@schmengler[/URL]
          [URL="http://www.schmengler-se.de/"]PHP Blog[/URL] - [URL="http://www.schmengler-se.de/magento-entwicklung/"]Magento Entwicklung[/URL] - [URL="http://www.css3d.net/"]CSS Ribbon Generator[/URL]

          Kommentar


          • #6
            Klammern habe ich verboten, um folgende Konstrukte zu verhindern:
            Code:
            <a href="javascript:alert('hi');">Blub</a>
            Auch wenn das Javascript herausgefiltert wird, gäbe es ja z.B. noch hundert andere schreibweisen oder eben diesen encoding-zeugs? (Kennt sich jemand damit aus? )

            Kommentar


            • #7
              Ich würde genau umgekehrt vorgehen. Also statt einer Blacklist eine Whitelist benutzen, das ist sicherlich der sicherere Weg.

              Kommentar


              • #8
                Wie genau sollte so eine Whitelist aussehen? ô0 Effektiv möchte ich ja im Text selbst alle Sonderzeichen erlauben, nur hald niemals so, dass dabei HTML-Tags entstehen könnten oder das bei BBCodes XSS betrieben werden kann.

                Kommentar


                • #9
                  Ersteres machst du ja schon mit htmlentities. Also brauchst du nur für Tags wie URL eine Whitelist, also z.B. dass URLs nur mit (https?|ftp|mailto) beginnen dürfen. Damit hast du javascript:... ausgeschlossen und valide URLs mit Klammern funktionieren trotzdem wie sie sollen. Das selbe gilt für IMG. Und COLOR braucht eigentlich nur [#a-z0-9]
                  [IMG]https://g.twimg.com/twitter-bird-16x16.png[/IMG][URL="https://twitter.com/fschmengler"]@fschmengler[/URL] - [IMG]https://i.stack.imgur.com/qh235.png[/IMG][URL="https://stackoverflow.com/users/664108/fschmengler"]@fschmengler[/URL] - [IMG]http://i.imgur.com/ZEqflLv.png[/IMG] [URL="https://github.com/schmengler/"]@schmengler[/URL]
                  [URL="http://www.schmengler-se.de/"]PHP Blog[/URL] - [URL="http://www.schmengler-se.de/magento-entwicklung/"]Magento Entwicklung[/URL] - [URL="http://www.css3d.net/"]CSS Ribbon Generator[/URL]

                  Kommentar


                  • #10
                    Wenn du eine Whitelist für Tags und eine Whitelist für Attribute anlegst, begrenzt du die Angriffsmöglichkeiten enorm. Zum Beispiel solche Sachen wie onclick, onload etc. würden von vornherein nicht in deinen HTML Code landen.

                    Wenn du dann noch Attribute brauchst die als Inhalt schädliche Sachen enthalten können, zum Beispiel "href", dann kannst du den Inhalt noch entsprechend validieren und dann solltest du eigentlich alles abgefrühstückt haben.

                    Kommentar


                    • #11
                      Warum nimmst du nicht einen fertigen BBCode-Parser, dann werden auch Tags korrekt geschlossen.
                      Bei dir wäre soetwas möglich:
                      Code:
                      [ b][ i][ /b][ /i]

                      was nachher kein valides HTML mehr ist.
                      Oder du macht es anders, du lässt HTML zu und nimmst den HTMLPurifier.
                      Außerdem würde ich nicht den font-Tag verwenden der ist veraltet.

                      Grüße
                      Signatur:
                      PHP-Code:
                      $s '0048656c6c6f20576f726c64';
                      while(
                      $i=substr($s=substr($s,2),0,2))echo"&#x00$i;"

                      Kommentar

                      Lädt...
                      X