DEV Community

Artur Balsam
Artur Balsam

Posted on

Secure by default, unsafe by you

Post originally created on github.io on October 2020

Disclaimer

This post is the presentation of how to make code UNSAFE. Please, do not use these code snippets in your application, unless you fancy to have a XSS. Read that, for extra protection: https://owasp.org/www-community/xss-filter-evasion-cheatsheet

Intro

In this small repo/blog will show you how to make modern, secure JS Frameworks, unsafe in nice way. Using purely these frameworks, we are going to end up with XSS. Following examples might be useful during code review or making a new version of DVWA, it’s up to you. Yes, you can find all these informations in the docs, but let's be honest - RTFM is not for everyone.

The Overview: Brave New World of JavaScript

Using this marvellous blog post Top JS Frameworks 2019 and followed by this awesome research State of JS 2019 it’s naturally that that I’ve did research on following ones:

  • The most popular, the king: The ReactJS;
  • The third, mr. lightweight Vue.js;
  • I’ve also added Mithril, because why not.

I am planning do something similar to others also. Stay tunned

ReactJS

Along with other possiblities of 'standard' XSS, this one using React DOM. Attribute called dangerouslySetInnerHTML can be used to set HTMLdirectly form REACT. dangerously part should suggest the user, that she/he doing something risky. In princple the DOM node will be updated with the object with key _html, the HTML. And yes, I've seen this in the wild, with data suppiled by user.

<div dangerouslySetInnerHTML={{__html: 'Not safe at all <img src=x onerror=alert(1)>'}} />
Enter fullscreen mode Exit fullscreen mode

Documentation

VueJS

Remember, the Client side template injection with AngularJS? If not, I encourage you to do it right here, right now. In Angular 1.6.x, they removed whole sandbox thigh altogether, but last payload, from Sir Mario Heiderich

{{constructor.constructor('alert(1)')()}}

should bring our attention. Elegant, isn't it? And right now, it works on VueJS because of template possibility and mixing clientside and serverside rendering Great post with PoC on that

<a>Not great, not terrible{{constructor.constructor('alert(1)')()}}<a>
Enter fullscreen mode Exit fullscreen mode

Documentation

Mithril

Starting from the middle the m.trust should be avoidable, but if not, it can be dangerous, especially with user supplied data. Especially unsanitized data.

m("div", [
    m.trust("<h1>Here's some <img src=x onerror=alert(1)></h1>")
])
Enter fullscreen mode Exit fullscreen mode

Documentation

Discussion (0)