Richten Sie die Vorschau HTML-Code der WMD-Editor mit serverseitigen HTML-Validierung (zum Beispiel keine eingebetteten JavaScript-Code)

StackOverflow https://stackoverflow.com/questions/2837593

Frage

Es gibt viele Stack-Überlauf Fragen (zB Whitelist, verhindert XSS mit WMD Kontrolle in C # und WMD Abschlags und serverseitige ), wie Server-Seite tun von Abschlags Schrubben produziert von der WMD-Editor die HTML, um sicherzustellen, generiert enthält keine schädliche Skript, wie folgt aus:

<img onload="alert('haha');" 
   src="http://www.google.com/intl/en_ALL/images/srpr/logo1w.png" />

Aber ich habe keinen guten Weg finden, um das Loch auf der Clientseite zu stecken. Client-Validierung ist kein Ersatz für die Wäsche Validierung auf dem Server natürlich, da jemand ein Client und POST Sie böse Markdown sein vorgeben. Und wenn Sie den HTML-Code auf dem Server sind Schrubben, kann ein Angreifer nicht speichert die schlechten HTML so sonst niemand in der Lage sein, es zu sehen, später und haben ihre Cookies gestohlen oder Sitzungen, die von dem schlechten Skript entführt. So gibt es einen gültigen Fall gemacht wird, dass es nicht wert sein kann, in dem WMD Vorschaufenster zu no-script Regeln durchzusetzen.

Aber stellt ein Angreifer einen Weg gefunden, bösartigen Abschlag auf den Server zu erhalten (zum Beispiel eines kompromittierter Futter von einem anderen Standort oder Inhalt vor einem XSS Fehler hinzu fixiert wurde). Ihre serverseitigen weißen Liste angewendet, wenn Abschlags zu HTML übersetzen normalerweise so schlecht Markdown verhindern würde den Nutzern angezeigt wird. Aber wenn der Angreifer jemand zu bearbeiten die Seite bekommen könnte (zum Beispiel durch einen weiteren Eintrag Entsendung der bösartigen Eintrag zu sagen hatte einen defekten Link und fragen jemanden, um es zu beheben), dann jeder, der die Seite bearbeitet wird ihre Cookies entführt. Dies ist zwar eine Ecke Fall, aber es kann immer noch sein Wert zu verteidigen gegen.

Außerdem ist es wahrscheinlich eine schlechte Idee des Client-Vorschaufenster zu ermöglichen, verschiedene HTML zu ermöglichen, als der Server ermöglicht.

Das Stack-Überlauf-Team hat dieses Loch gesteckt durch Änderungen an WMD machen. Wie haben sie es tun?

[ANMERKUNG: Ich habe diesen aus schon gedacht, aber es erforderlich, einige knifflige JavaScript Debugging, so dass ich meine eigene Frage zu beantworten bin hier um zu helfen anderen, die ths Gleiche tun möchten].

War es hilfreich?

Lösung

Eine mögliche Lösung ist in wmd.js im pushPreviewHtml() Verfahren. Hier ist der ursprüngliche Code aus der Stack-Überlauf-Version von WMD auf GitHub :

if (wmd.panels.preview) {
    wmd.panels.preview.innerHTML = text; 
}

Sie können es mit etwas Wäsche Code ersetzen. Hier ist eine Anpassung des Codes, Stapelüberlauf als Antwort auf diesen Beitrag verwendet , die einengt zu einer weißen Liste von Tags und für IMG und A-Elemente, engt auf eine weiße Liste von Attributen (und in einer bestimmten Reihenfolge zu!). Siehe die Meta Stack Overflow Post Was HTML-Tags erlaubt sind auf Stack-Überlauf, Server Fehler und Super User? für weitere Informationen auf der weißen Liste.

Hinweis: dieser Code sicherlich verbessert werden kann, z.B. zu ermöglichen weiße Liste in beliebiger Reihenfolge Attribute. Es ist auch Verbietet mailto:. URLs, die wahrscheinlich eine gute Sache auf Internetseiten, sondern auf Ihrem eigenen Intranet-Seite es nicht der beste Ansatz sein kann

if (wmd.panels.preview) {

    // Original WMD code allowed JavaScript injection, like this:
    //    <img src="http://www.google.com/intl/en_ALL/images/srpr/logo1w.png" onload="alert('haha');"/>
    // Now, we first ensure elements (and attributes of IMG and A elements) are in a whitelist,
    // and if not in whitelist, replace with blanks in preview to prevent XSS attacks 
    // when editing malicious Markdown.
    var okTags = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i;
    var okLinks = /^(<a\shref="(\#\d+|(https?|ftp):\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+)"(\stitle="[^"<>]+")?\s?>|<\/a>)$/i;
    var okImg = /^(<img\ssrc="https?:(\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+)"(\swidth="\d{1,3}")?(\sheight="\d{1,3}")?(\salt="[^"<>]*")?(\stitle="[^"<>]*")?\s?\/?>)$/i;
    text = text.replace(/<[^<>]*>?/gi, function (tag) {
        return (tag.match(okTags) || tag.match(okLinks) || tag.match(okImg)) ? tag : ""
    })

    wmd.panels.preview.innerHTML = text;  // Original code 
}

Beachten Sie auch, dass dieses Update ist nicht in der Stack-Überlauf-Version von WMD auf GitHub - klar die Änderung wurde später und nicht überprüft wieder in GitHub gemacht.

UPDATE: um die Funktion zu vermeiden brechen, wo Hyperlinks automatisch erstellt werden, wenn Sie in einer URL eingeben, müssen Sie auch Änderungen an showdown.js machen, wie unten:

Originalcode:

var _DoAutoLinks = function(text) {

    text = text.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"<a href=\"$1\">$1</a>");

    // Email addresses: <address@domain.foo>

    /*
        text = text.replace(/
            <
            (?:mailto:)?
            (
                [-.\w]+
                \@
                [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
            )
            >
        /gi, _DoAutoLinks_callback());
    */
    text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
        function(wholeMatch,m1) {
            return _EncodeEmailAddress( _UnescapeSpecialChars(m1) );
        }
    );

    return text;
}

Fixed Code:

var _DoAutoLinks = function(text) {
    // use simplified format for links, to enable whitelisting link attributes
    text = text.replace(/(^|\s)(https?|ftp)(:\/\/[-A-Z0-9+&@#\/%?=~_|\[\]\(\)!:,\.;]*[-A-Z0-9+&@#\/%=~_|\[\]])($|\W)/gi, "$1<$2$3>$4");
    text = text.replace(/<((https?|ftp):[^'">\s]+)>/gi, '<a href="$1">$1</a>');
    return text;
}

Andere Tipps

Es ist kein Sicherheitsproblem der lokale Benutzer zu ermöglichen, Skripte im Seitenkontext auszuführen, solange es unmöglich ist, für eine dritte Partei das Skript zur Verfügung zu stellen. Ohne den Editor, es zu tun, könnte der Benutzer immer eine javascript: URL eingeben, während auf Ihrer Seite oder Verwendung Firebug oder etwas ähnliches.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top