TinyMCE - Code parsen

  • Hallo!
    Ich nutze auf meiner Seite den "TinyMCE" (WYSIWYG-Editor). Der Editor selbst funktioniert zu meiner vollsten Zufriedenheit.

    Allerdings gibt es nun 2 Dinge die mich doch etwas stören:
    1. Ein etwas erfahrener Besucher kann spätestens durch das klicken des HTML-Tags beliebige Klassen/Id's zu den Tags hinzufügen und sogar Stylesheets und Javacscript-Dateien einbinden. Das möchte ich allerdings verhindern. So sollen Stylesheets, Javascript und bestimmte Klassen/Id's verboten sein, außerdem sollen die Style-Angaben bei Tags gefiltert werden und nur bestimmte erlaubt sein. Der Code den ich gemacht habe funktioniert aber leider nicht so ganz wie erwünscht, deswegen bin ich seit längeren auf der Suche nach einem Parser o.ä. der HTML-Code parsen und nach gegebenen Regeln filtern kann.

    2. Wenn ein Besucher kein JS hat gibts auch kein TinyMCE, heißt er kann wirklich JEDEN Code in die Textarea schreiben. Gerade hier ist das filtern von großer Bedeutung. Wie aber damit umgehen ? Ich kann ja via PHP schlecht erkennen ob eine Person JS (de-)aktiviert hat. Gerade hier ist ein Parser ja extrem wichtig.

    Kennt ihr dazu evtl. eine Lösung ? Nutzt ihr den TinyMCE und wie schützt ihr euch vor solchen HTML-"Hacks" (kann ja immerhin das Layout erheblich zerstören und durch JS geht ja noch viiiel mehr)

  • Das ist mir schon klar, ich habe auch bereits einen Code, allerdings funktioniert der nicht so ganz wie gewünscht, weswegen ich wissen wollte, ob es schon etwas "fertiges" gibt bzw. wie das z.B. hier oder bei anderen großen Communitys mit WYSIWYG-Editoren gemacht wird.

    Probleme habe ich z.B. dabei, dass nur gewissen Klassen/ID's erlaubt sind. Mein bisheriger Ansatz war folgender:

    PHP
    $string = preg_replace('/<(.*?)(id|class).*?=.*?".*?(beispiel|klasse|oder|id).*?".*?>(.*?)<\/.*?>/i', '<$1 $2="$3">$4</$1>', $string);


    Leider wird bei diesem Code dann mein kompletter abgesendeter Code zerstört. Vielleicht hab ich aber auch das mit den Regulären Ausdrücken noch nicht ganz "gerafft" ?

  • veruch mal HTMLTidy, wenn du in php nicht ganz unbewandert bist.
    IMO die beste Bibliothek, um sauberes html zu erzeugen

    Ich bin zwar durchaus etwas in PHP bewandert, allerdings liegt das Problem eher darin, dass ich nur Webspace und habe und keinen Server. Dadurch wird die Verwendung von HTMLTidy etwas schwierig.

    Ich werde mich dann aber mal ransetzen und den Parser selbst zusammenbasteln.

  • Öhm, wenn du kein PHP hast, wie willst du das eingegebene HTML verarbeiten?!? Versteh mich nicht falsch, aber hast du jetzt Webspace mit PHP under Webspace ohne PHP?
    Und man KANN mit PHP herausfinden, ob der benutzer HTML hat.
    http://de2.php.net/get_browser

    Der, der weiß dass er nichts weiß, weiß mehr als der, der nicht weiß, dass er nichts weiß.

    Wer nach etwas fragt, geht grundsätzlich das Risiko ein, es auch zu bekommen!

  • Öhm, wenn du kein PHP hast, wie willst du das eingegebene HTML verarbeiten?!? Versteh mich nicht falsch, aber hast du jetzt Webspace mit PHP under Webspace ohne PHP?
    Und man KANN mit PHP herausfinden, ob der benutzer HTML hat.
    http://de2.php.net/get_browser

    :D

    Ich hab Webspace mit PHP, allerdings eben keinen Server wo ich HTMLTidy installieren könnte (für mich klingt es auf der Seite nämlich so, als ob man sich das ganze erst auf dem Server installieren muss um es nutzen zu können)

    Und ob der Benutzer HTML hat setze ich einfach mal vorraus, da ansonsten mein ganzes Unterfangen ja sinnlos wäre, denn was sollte ich dann großartig verarbeiten ?
    Es geht ja eher darum, ob der Nutzer JS hat bzw. aktiviert hat. Dazu ist mir allerdings schon ein Weg eingefallen. Ich lasse einfach zu der Textarea noch einen hidden-Input mit JS erstellen. Existiert der hidden-input läuft Javascript, d.h. der Code muss detailliert durchgelaufen werden, gibt es den Input nicht wird der Code "hart" behandelt, also alles mehr oder weniger "gnadenlos" entfernt.

  • Ah, ok.
    Ich würde das aufm Server aber so machen, mit dem vorteil nur einen parser schreiben zu müssen:

    PHP
    $info=get_browser(null, true);
    if ($info['javascript']) {
        // Formular für TinyMCE
    } else echo "Du brauchst JS"


    Aber sich auf das Feld zu verlassen ist sowieso n bills unsicher, ich kann die Seite ja aufrufen, des Feld wird erstellt und dann JS ausmachen. Dann kann ich in die Textarea auch schreiben wass ich will.
    Das man HTML-Tidy installieren muss denke ich auch, zumindest gibts nur EXE Files. Und da es Für mehrere OS´s verfügbar ist, sagt alles.
    Aber nun zurück zum Parser, man könnte ja auch

    PHP
    "/<(.*?) style=([\'|'].*[\'|'])(.*?)>/"
    // Ungetestet


    Schreiben und dann die Styles einzeln parsen

    PHP
    "/(.*?):(.*?);/"

    Der, der weiß dass er nichts weiß, weiß mehr als der, der nicht weiß, dass er nichts weiß.

    Wer nach etwas fragt, geht grundsätzlich das Risiko ein, es auch zu bekommen!

  • Aber sich auf das Feld zu verlassen ist sowieso n bills unsicher, ich kann die Seite ja aufrufen, des Feld wird erstellt und dann JS ausmachen. Dann kann ich in die Textarea auch schreiben wass ich will.


    Dann wird ja aber ALLES mehr oder weniger entfernt (strip_tags). Dadurch sind letztendlich nur p-Tags übrig (ohne Style/Class/Id). Dadurch ist es ja nicht mehr unsicher. Oder irre ich mich da jetzt ?

    Ich habe mal den "HTML Purifier" getestet. Scheint das zu sein, was ich gesucht habe. Muss mich nur noch etwas mit der Konfiguration rumschlagen, die gerade noch nicht so zu funktionieren scheint.
    Kennt sich jemand damit aus ?

  • ich habs noch nicht produktiv eingesetzt. Aber weisste was, ich hab Bock :D
    poste mal nen Beispieldatensatz rein und was am Ende rauskommen soll, dann setz ich mich mit ran, sobald ich morgen Zeit finde.
    Wollte damit eh längst mal was machen


  • ich habs noch nicht produktiv eingesetzt. Aber weisste was, ich hab Bock :D

    Das lass ich mir nicht zweimal sagen :P

    Eine Eingabe die per $_POST reinkommen könnte wäre z.B.:

    HTML
    <p style='width:2000px;'>Beliebiger Text. <span style='color:red'>Wichtig in Farbe</span></p>

    Nun sollen die Tags "p" und "span" erlaubt sein. Das Style-Tag darf auch vorkommen, allerdings darf eben kein "width" drin vorkommen. Der Code am Ende sollte also folgender sein:

    HTML
    <p>Beliebiger Text. <span  style='color:red'>Wichtig in Farbe</span></p>

    Ich habe auch schon einen Ansatz, allerdings scheint sich da irgendein Fehler zu befinden, der mir immer folgenden Code liefert:

    HTML
    <p>Beliebiger Text. <span>Wichtig in Farbe</span></p>

    Mein PHP-Code sieht so aus:

    PHP
    $allowedTags = array('p', 'span');
    $config = HTMLPurifier_Config::createDefault();
    $config->set('HTML.Allowed', implode(',', $allowedTags));
    $config->set('CSS.AllowedProperties', array('text-align', 'color', 'background-color'));
    $config->set('AutoFormat.RemoveSpansWithoutAttributes', true);
    $config->set('AutoFormat.RemoveEmpty.RemoveNbsp', true);
    $purifier = new HTMLPurifier($config);
    echo $purifier->purify($string);

    Ich muss auch sagen, dass ich die Dokumentation von Purifier irgendwie nicht so ganz verstehe (Was heißt "Lookup array (or null)" ganz genau ? Ich mein Array klar, aber ist "Lookup" was besonderes ?^^). Scheint wohl so als hätte ich bei "CSS.AllowedProperties" einen Fehler reingebaut. Weil "HTML.Allowed" und die beiden "AutoFormat" funktionieren auch.
    Das ganze ist natürlich erst der Anfang und ich möchte es noch ausbauen aber wie gesagt stecke ich eben schon hier fest.

  • Dein Fehler liegt in HTML.Allowed
    Hier musst du explizit angeben, welche Attribute im Tag erlaubt sind, derart

    PHP
    $allowedTags = array('p[style]', 'span[style]');

    Prinzipiell kannst du dich an dieses "white-list"-Verfahren schon mal gewöhnen ;)
    HTMLPurifier arbeitet nur damit...


  • Dein Fehler liegt in HTML.Allowed
    Hier musst du explizit angeben, welche Attribute im Tag erlaubt sind, derart

    PHP
    $allowedTags = array('p[style]', 'span[style]');


    Ich habe das mal so reingemacht, allerdings ändert sich am Ergebnis nichts. Ich habe im Internet dazu 2 Ergebnisse gefunden, die etwas mit magic_quotes zu tun hatten. Dort wurde gemeint, man sollte vorher den String noch durch stripslashes() laufen lassen(, hat am Ergebnis aber leider auch nichts geändert.) Hat am Ergebnis sehr wohl etwas geändert, jetzt funktioniert es. Keine Ahnung was ich da beim letzten mal falsch gemacht habe weil ichs schonmal so probiert habe.

    Prinzipiell kannst du dich an dieses "white-list"-Verfahren schon mal gewöhnen ;)
    HTMLPurifier arbeitet nur damit...


    Das ist mir gerade recht, so wird einem nämlich viel Arbeit abgenommen.

    Einmal editiert, zuletzt von shikari (14. Mai 2010 um 13:02)

  • Ich habe mal damit etwas rumgespielt und bin jetzt eigentlich fertig. Krass. Da bekommt man einfach innerhalb kürzester Zeit nen echt guten Parser!

    Hier ist mal der Code, vielleicht gibts ja noch irgendwas zu verbessern ?


    Als Testcode habe ich mal den eingegeben (durch Tiny):


    Das ganze scheint soweit zu funktionieren, Ergebnis ist folgendes:


    Jetzt muss ich durch preg_replace (oder ne ähnliche Funktion) nur noch

    Code
    <span style='text-decoration:line-through;'></span>


    durch

    Code
    <strike></strike>


    ersetzen und das "text-align:center|left|right|block;" durch ne jeweilige Klasse.

  • Das mit den RegExp sollte ja nicht das problem sein. Oder wie ist das zu verstehen?

    Der, der weiß dass er nichts weiß, weiß mehr als der, der nicht weiß, dass er nichts weiß.

    Wer nach etwas fragt, geht grundsätzlich das Risiko ein, es auch zu bekommen!

  • Das mit den RegExp sollte ja nicht das problem sein. Oder wie ist das zu verstehen?


    Nein, ich hoffe nicht :D
    Solche Ersetzungen sind mit dem HTMLPurifier aber nicht direkt möglich oder ? Also irgendwie Style-Attribut -> Klasse. Hab dafür zumindest nichts in der Doku gefunden ... Und wäre ja auch zu schön :D

    Ich wollte mit meinem Post im Prinzip auch nur eine Lösung zeigen wie man es machen könnte falls irgendjemand so wie ich auch mal in Google nach ner Lösung sucht (vorausgesetzt er kommt auf diesen Thread :D)


  • Jetzt muss ich durch preg_replace (oder ne ähnliche Funktion) nur noch

    Code
    <span style='text-decoration:line-through;'></span>


    durch

    Code
    <strike></strike>


    ersetzen und das "text-align:center|left|right|block;" durch ne jeweilige Klasse.

    Öhm... ich dachte, man solle das gerade so rum nicht machen? <strike> ist doch deprecated?

    Information will frei verfügbar sein.

    Don't eat unpeeled hedgehogs.

  • Öhm... ich dachte, man solle das gerade so rum nicht machen? <strike> ist doch deprecated?

    Äh ja das stimmt, grade nochmal nachgeschaut, in HTML 4.01 deprecated und in HTML5 garnichtmehr enthalten.
    Ich hab in meinem Script schon als Kommentar "<del>" reingeschrieben, was ich auch eigentlich statt <strike> verwenden wollte, hab nur beim reinschreiben hier nicht drangedacht.

    Einmal editiert, zuletzt von shikari (19. Mai 2010 um 17:09)