adammark/Markup.js

Markup does not automatically escape input from context

rbu opened this issue · 3 comments

rbu commented

Markup does not automatically escape content that is injected into the DOM from the context. When the content is controlled by a user, this can lead to Cross-Site-Scripting attacks, as demonstrated by this change in the example.html:

diff --git a/examples/examples.html b/examples/examples.html
index 8fefb32..d525da6 100644
--- a/examples/examples.html
+++ b/examples/examples.html
@@ -38,7 +38,7 @@ pre      { }
 <script>
 function init() {
     var context = {
-        name: { first: "John", last: "Doe", middle: null },
+        name: { first: "John <a href='/' onmouseover='alert(\"bad\")'>link</a>", last: "Doe", middle: null },
         age: 21,
         birthday: "Thu Aug 01 1991 00:00:00 GMT-0400 (EDT)",
         motto: "Lorem ipsum dolor sit amet",

An exploit scenario would usually include user-controlled content that is visible by other users, such as comments, or about me areas / user names. Please ensure that input from the context is always HTML-escaped.

Thanks rbu. Markup doesn't make assumptions about where the input comes from, and it can run either in the browser or the server. I'd say it's up to the developer to scrub user-generated content before doing anything with it.

rbu commented

You can, of course, assume the developer will always sanitize all user-controlled correctly before passing it into the template. However, I want to point out I strongly disagree with that notion and it is a reason for us not consider the library.

Since templating engines encapsulate generation of HTML content, they should make it hard to use insecurely, not hard to use securely. Auto-escaping is common practice in most templating engines. Not doing it may create XSS security vulnerabilities in all products using it.

I see your point but I think the view layer is the wrong place to implement such security measures.

I've written a custom pipe that should do the trick for you. You can use it like this:

{{user_comment|sanitize}}

Hope this helps!