DEV Community

Should you care about XSS in Vue.js?

Nando Delgado on November 20, 2018

Let’s get the obvious part of this article out of the way first: if you don’t sanitize your data you’ll always be vulnerable to cross-site script...
Collapse
 
steeve profile image
Steeve

I came to this article because I need to display raw HTML into a component in my app. The raw HTML is coming from vue-quill-editor and I display it with v-html. Unfortunately with the latest version of eslint, I'm getting the error: warning 'v-html' directive can lead to XSS attack vue/no-v-html.
Is there a better practice to render HTML without v-html with vuejs?
By the way, good article 👏

Collapse
 
nandod1707 profile image
Nando Delgado

Hey Steeve! If you absolutely need to use v-html (which I understand you do), then you should look into sanitizing user input when it gets to the server. I can recommend this library I've been working with recently, if you're using Node server side then it might help! npmjs.com/package/sanitize-html

Collapse
 
steeve profile image
Steeve

I will take a look, thanks Nando :)

Collapse
 
phillygogo profile image
phillygogo

Hey Steeve. If you trust the data then you can happily use v-html. E.g. your data is coming from your own CMS

Collapse
 
narviktribe profile image
EJ Santoemma • Edited

This article is wrong, @nandod1707 you should change or remove it.

You thought that

{{ constructor.constructor("alert('xss')")() }}

is the same of

s = `constructor.constructor("alert('xss')")()`
{{ s }}

But the first opens the alert, the second outputs the string
With the first you are hacking yourself.

In a real app you are in the second scenario, where s is taken from the server, and Vue correctly shows it as a string.

Anyone can try, though: (spoiler: it show's the string)

<template>
  <div>{{ s }}</div>
</template>

<script>
export default {
  data() {
    return {
      s: `constructor.constructor("alert('xss')")()`
    }
  },
}
</script>
Collapse
 
nandod1707 profile image
Nando Delgado

Hi EJ! Thanks for your comment. Sure, what you're saying is similar to what we suggest in the article of putting server side variables inside a global variable. The goal of the article is to point out how to avoid making an app vulnerable through bad practices, and your example seems to be in line with that :)

Collapse
 
narviktribe profile image
EJ Santoemma

Hi Nando. The standard (and only) way to show a value coming from outside is to put it into a property (data, props, vuex, ...) and then show it in the template via the mustaches, v-text or v-html.

That global variable trick is a solution to a non problem.
Your "constructor" example had been discussed and should be a thing of the past.

I'm replying here because I found your article on Hacker News last week, and thought that it can generate FUD to those learning any reactive framework.

Like your hint to limit the use of Vue...

Peace :)

Collapse
 
joeschr profile image
JoeSchr

important article, thanks!