Volker: Frage zu htmlentities in href-Attributen

Hallo!

Bei den Kommentaren zur PHP-Dokumentation von htmlentities() steht als erstes
„The 'ENT_QUOTES' option doesn't protect you against javascript evaluation in certain tag's attributes, like the 'href' attribute of the 'a' tag. When clicked on the link below, the given JavaScript will get executed:“

<?php  
$_GET['a'] = 'javascript:alert(document.cookie)';  
$href = htmlEntities($_GET['a'], ENT_QUOTES);  
print "<a href='$href'>link</a>"; # results in: <a href='javascript:alert(document.cookie)'>link</a>  
?>

Jetzt stellt sich mir die Frage wie ich das verhindern kann.
Wie kodiere ich einen String so, dass er als URL (href) in einem Link nicht verstümmelt wird aber auch kein Schaden angerichtet werden kann?

Vielen Dank!

  1. Om nah hoo pez nyeetz, Volker!

    <?php

    $_GET['a'] = 'javascript:alert(document.cookie)';
    $href = htmlEntities($_GET['a'], ENT_QUOTES);
    print "<a href='$href'>link</a>"; # results in: <a href='javascript:alert(document.cookie)'>link</a>
    ?>

    
    >   
    > Jetzt stellt sich mir die Frage wie ich das verhindern kann.  
    > Wie kodiere ich einen String so, dass er als URL (href) in einem Link nicht verstümmelt wird aber auch kein Schaden angerichtet werden kann?  
      
    Das geht nicht. Wenn du die Ausführung von JavaScript mittels href-Attribut verhindern möchtest, musst du "javascript" aus dem Attribut entfernen, es also verstümmeln. Du könntest allerdings auch den Link überhaupt nicht ausgeben, wenn er "javascript" enthält. Dann hast du ndas Attribut ebenfalls verstümmelt, und zwar so doll, dass nichts mehr von ihm übrig ist.  
      
    Matthias
    
    -- 
    Der Unterschied zwischen Java und JavaScript ist größer als der zwischen [Bache und Bachelor](http://selfhtml.apsel-mv.de/java-javascript/index.php?buchstabe=B#bache).  
    ![](http://www.billiger-im-urlaub.de/kreis_sw.gif)  
    
    
  2. Bei den Kommentaren zur PHP-Dokumentation von htmlentities() steht als erstes
    „The 'ENT_QUOTES' option doesn't protect you against javascript evaluation in certain tag's attributes, like the 'href' attribute of the 'a' tag. When clicked on the link below, the given JavaScript will get executed:“

    htmlEntities('javascript:alert(document.cookie)', ENT_QUOTES);

    results in: 'javascript:alert(document.cookie)'

    Da frage ich mich schon, ob derjenige, der diesen Kommentar geschrieben hat, überhaupt verstanden hat, was htmlentities() macht, geschweige denn die ENT_QUOTES-Option.

    htmlentities() ersetzt, mit wenigen Ausnahmen, alle Zeichen, für die es eine HTML-Umschreibung gibt (&bla;) durch eben jene Umschreibung. ENT_QUOTES erweitert die Tabelle ersetzter Zeichen um einfache Anführungszeichen.

    Die Grundfunktion hat schon offenkundig rein gar nichts mit Javascript-URLs zu tun. Dann auch noch speziell ENT_QUOTES in diesem Zusammenhang zu nennen, ist sowas von abwegig, zeugt von so wenig Sachverstand, da fehlen mir die Worte.

    Wie kodiere ich einen String so, dass er als URL (href) in einem Link nicht verstümmelt wird aber auch kein Schaden angerichtet werden kann?

    Du kodierst, genauer: du maskierst, um zu verhindern, dass Benutzereingaben den HTML-Code der Seite selbst verändern. Sowas passiert, wenn die Eingabe Anführungszeichen oder spitze Klammern (Kleiner-als-Zeichen) enthält. (Für diese Funktion reicht übrigens htmlspecialchars(), htmlentities() bringt keine weitere Sicherheit.)

    Diese Maskierung ist etwas anderes als zu verhindern, dass falsche Benutzereingaben den Besucher in die Irre führen.
    Javascript-URLs sind ein Zwischending, sie brechen zwar nicht den HTML-Code auf (lassen sich nicht durch eine Maskierung verhindern), verändern aber die Funktion der Seite.

    Möchtest du keine Javascript-URLs, dann lasse einfach keine URLs zu, die als Javascript-URLs daherkommen: Das sind alle, die mit javascript: beginnen. Fertig.

    Möchtest du ganz sicher gehen (und man kann nie sicher genug sein), dann lasse stattdessen nur URLs zu, von denen du weisst, dass sie den geringsten Schaden zufügen. Beschränke die zulässigen URLs auf absolute URLs, jene, die mit http:// oder https:// beginnen.
    Eventuell kannst du noch relative URLs hinzufügen, die sich auf die URL der Seite beziehen. Allerdings wäre das schon blöd, sobald jemand die Seite von irgendwo anders lädt als von ihrem ursprünglichen Ort.