I'm currently working on making a blog using the WordPress REST API as the back end. The API returns the article with HTML markup in it. I'm taking that JSON response and using v-html
to render it into my Vue app. I understand there are cross-site scripting security risks here.
It would be great if v-html
automatically sanitized the string to remove any <script>
tags. For those needing script tags, for whatever reason, maybe v-html-unsafe
can accomplish that.
I was recently made aware Angular 4 is doing this and think Vue.js would greatly benefit from this feature.
That would be a breaking change, what can be done instead is adding a ~.safe
~ .sanitize
modifier that strips off the <script>
tags.
This can be easily handled in a computed property or with a utility function
Just to clarify, are you saying that changing the default behavior of v-html
would be the breaking change?
I guess ideally it would be nice if v-html
was sanitized by default, but your suggestion using a .safe
modifier sounds great too. So would that look like v-html.safe="data"
?
Hi. Just my two cents, but I would be -1 on this. It seems unnecessary for Vue to maintain its own html sanitizer, given that there are other libraries that already do this well. I'd argue that there are more appropriate places to perform sanitization and that also allow for better developer control. A few ideas:
Also, worth mentioning that the docs have appropriate warnings in both the guide and reference sections.
@rpkilby sanitize-html seems great and will work for me and my use case. I still think it would be nice if Vue did this automatically as an added security measure, but I absolutely hear your concerns.
Thanks for your input and that link.
I don't think it's a good idea for Vue to add a built-in html-sanitizer either.
How about introducing a new config (e.g. Vue.config.htmlSanitizer = (html) => safeHtml
) as a compromised way?
I agree with @rpkilby - shipping a built-in sanitizer would add extra bundle weight for a rare use case (when most use cases of v-html
are for trusted content); it is also trivial to add sanitize-html
by setting Vue.prototype.$sanitize = sanitizeHTML
and then do v-html="$sanitize(html)"
.
@yyx990803 I know this is an older thread but setting Vue.prototype.$sanitize = sanitizeHTML
it throws Uncaught ReferenceError: sanitizeHTML is not defined`. I know sanitizeHTML is defined as I've previously imported it and used it (before Vue is called)
@Braunson
Vue.prototype.$sanitize = sanitizeHTML
Work fine for me (I am using Vue build SPA with Vuex and vue-router)
Version: "vue": "^2.5.17"
Here is how I do it:
npm install sanitize-html
src/main.js
import sanitizeHTML from 'sanitize-html';
Vue.prototype.$sanitize = sanitizeHTML
src/pages/Topic.vue
div(v-html='$sanitize(topic.content_html)')
sanitize-html
would remove <img>
How to fix this: (https://github.com/punkave/sanitize-html#readme)
clean = sanitizeHtml(dirty, {
allowedTags: sanitizeHtml.defaults.allowedTags.concat([ 'img' ])
});
I ended up using https://www.npmjs.com/package/vue-dompurify-html
I agree with @rpkilby - shipping a built-in sanitizer would add extra bundle weight for a rare use case (when most use cases of
v-html
are for trusted content); it is also trivial to addsanitize-html
by settingVue.prototype.$sanitize = sanitizeHTML
and then dov-html="$sanitize(html)"
.
Im wondered that most popular libraries to sanitize HTML string are extremely huge (each one is bigger that my whole Vue.js app bundle)...
https://www.npmjs.com/package/sanitize-html
https://www.npmjs.com/package/dompurify
https://www.npmjs.com/package/xss
https://www.npmjs.com/package/string-strip-html
I have created simple & fast solution without regex, but I know that it is more secure to use popular well-tested libs. But I would like to know your opinion to this solution https://jsfiddle.net/n10L6a5u/ It is Vue.js plugin for custom directive v-html-safe
which removes just insecure XSS things like attributes starting "on" (e.g.: onload, onerror, ...) and also attribute values starting "javascript:" (e.g. href="javascript:alert(1)"). Do you see some potential issues there?
Most helpful comment
I agree with @rpkilby - shipping a built-in sanitizer would add extra bundle weight for a rare use case (when most use cases of
v-html
are for trusted content); it is also trivial to addsanitize-html
by settingVue.prototype.$sanitize = sanitizeHTML
and then dov-html="$sanitize(html)"
.