Repository: vuejs/eslint-plugin-vue
Pull request #435 (2018-03-18 22:48:06)

⭐️New: Add `vue/no-v-html` rule
This PR adds vue/no-v-html rule.
This implements rule proposed in #434 

n-zeplo: Thanks @michalsnik! Made the change you have requested.

Patch:
diff --git a/docs/rules/no-v-html.md b/docs/rules/no-v-html.md
new file mode 100644
index 00000000..fc77d5f9
--- /dev/null
+++ b/docs/rules/no-v-html.md
@@ -0,0 +1,37 @@
+# disallow use of v-html to prevent XSS attack (no-v-html)
+
+This rule reports use of `v-html` directive in order to reduce the risk of injecting potentially unsafe / unescaped html into the browser leading to Cross Side Scripting (XSS) attacks.
+
+## :book: Rule Details
+
+This rule reports all uses of `v-html` to help prevent XSS attacks.
+
+This rule does not check syntax errors in directives because it's checked by no-parsing-error rule.
+
+:-1: Examples of **incorrect** code for this rule:
+
+```html
+<template>
+    <div v-html="someHTML"></div>
+</template>
+```
+
+:+1: Examples of **correct** code for this rule:
+
+```html
+<template>
+    <div>{{someHTML}}</div>
+</template>
+```
+
+## :wrench: Options
+
+Nothing.
+
+## When Not To Use It
+
+If you are certain the content passed `to v-html` is sanitized HTML you can disable this rule.
+
+## Further Reading
+
+* (XSS in Vue.js)[https://blog.sqreen.io/xss-in-vue-js/]
diff --git a/lib/rules/no-v-html.js b/lib/rules/no-v-html.js
new file mode 100644
index 00000000..be8a1c35
--- /dev/null
+++ b/lib/rules/no-v-html.js
@@ -0,0 +1,33 @@
+/**
+ * @fileoverview Restrict or warn use of v-html to prevent XSS attack
+ * @author Nathan Zeplowitz
+ */
+'use strict'
+const utils = require('../utils')
+
+// ------------------------------------------------------------------------------
+// Rule Definitionutilu
+// ------------------------------------------------------------------------------
+
+module.exports = {
+  meta: {
+    docs: {
+      description: 'disallow use of v-html to prevent XSS attack',
+      category: undefined,
+      url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.6.0/docs/rules/no-v-html.md'
+    },
+    fixable: null,
+    schema: []
+  },
+  create (context) {
+    return utils.defineTemplateBodyVisitor(context, {
+      "VAttribute[directive=true][key.name='html']" (node) {
+        context.report({
+          node,
+          loc: node.loc,
+          message: "'v-html' directive can lead to XSS attack."
+        })
+      }
+    })
+  }
+}


Test patch:
diff --git a/tests/lib/rules/no-v-html.js b/tests/lib/rules/no-v-html.js
new file mode 100644
index 00000000..8ac49a14
--- /dev/null
+++ b/tests/lib/rules/no-v-html.js
@@ -0,0 +1,58 @@
+/**
+ * @fileoverview Restrict or warn use of v-html to prevent XSS attack
+ * @author Nathan Zeplowitz
+ */
+'use strict'
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+const RuleTester = require('eslint').RuleTester
+const rule = require('../../../lib/rules/no-v-html')
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+const ruleTester = new RuleTester({
+  parser: 'vue-eslint-parser',
+  parserOptions: { ecmaVersion: 2015 }
+})
+
+ruleTester.run('no-v-html', rule, {
+  valid: [
+    {
+      filename: 'test.vue',
+      code: ''
+    },
+    {
+      filename: 'test.vue',
+      code: '<template></template>'
+    },
+    {
+      filename: 'test.vue',
+      code: '<template><div v-if="foo"></div></template>'
+    },
+    {
+      filename: 'test.vue',
+      code: '<template><div v-if="foo" v-bind="bar"></div></template>'
+    }
+  ],
+  invalid: [
+    {
+      filename: 'test.vue',
+      code: '<template><div v-html="foo"></div></template>',
+      errors: ["'v-html' directive can lead to XSS attack."]
+    },
+    {
+      filename: 'test.vue',
+      code: '<template><ul v-html:aaa="userHTML"></ul></template>',
+      errors: ["'v-html' directive can lead to XSS attack."]
+    },
+    {
+      filename: 'test.vue',
+      code: '<template><section v-html/></template>',
+      errors: ["'v-html' directive can lead to XSS attack."]
+    }
+  ]
+})