I’m using backbone, and the general way for passing the collections when the page load is
window.router = new Routers.ManageRouter({store: #{@store.to_json});
which is fine and works well, until someone decides to add the text “<script>alert("owned")</script>” to one of the store fields. the last </script> obviously closes the javascript. How can this be circumvented?
:javascript
$(function() {
window.router = new Dotz.Routers.ManageRouter({store: #{@store.to_json}});
Backbone.history.start();
});
The above outputs:
<script>
//<![CDATA[
$(function() {
window.router = new Dotz.Routers.ManageRouter({store: '{"_id":"4f3300e19c2ee41d9a00001c", "points_text":"<script>alert(\"hey\");</script>"'});
Backbone.history.start();
});
//]]>
</script>
Inside a
<script>block it is syntactically illegal to have any</followed by a name—not just</script>—so you need to escape that anywhere it may appear. For example:This will create the sequence
<\/inside your JS strings, which is interpreted to be the same as</. Ensure that you use single quotes in your gsub replacement string, or else usegsub( "</", "<\\/" )due to the difference between single and double quotes in Ruby.Shown in action:
If you are using Rails (or ActiveSupport) you can enable JSON escaping:
Seen in action:
It produces JSON that is more verbose than you need to solve this particular problem, but it is effective.