question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Disable interpolation (mustache-style directives). Vue unusable for apps with user content.

See original GitHub issue

Vue.js version

2.0.5

Reproduction Link

http://codepen.io/anon/pen/pNbQeY

Steps to reproduce

  1. An app built around user content
  2. Vue instance bound to app container
  3. User content contains curly braces ({{ and }})

What is Expected?

Curly braces in non-app, user content are ignored. Especially when encoded.

What is actually happening?

User can crash Vue and thus the application by simply using the curly braces syntax anywhere their input is rendered, i.e. {{ myvalue }} and {{ myvalue }}.

Solutions that did not work

  • Encoding the curly braces; {{ myvalue }}
  • Creating several Vue instances and binding them only to non-user content. Whenever a Vue component needs to render user content, use v-html.
    • This is not a viable solution as it would require a developer to create a Vue instance per Vue component seperately. Each component would then also have to use the v-html syntax, which prevents using third-party, non-Vue code they have no access to.
  • Changing delimiters
    • The problem remains and the user can still crash the app.
  • Disabling delimiters (interpolation)
    • Not supported. Tried delimiters: ['', ''] which causes Vue to render every single element.

Propositions

  • Bring back Vue.config({ interpolate: false }) (https://github.com/vuejs/vue/issues/147#issuecomment-36372431) or a non-global option per Vue instance.
  • A new tag, e.g. v-ignore-delimiters or v-disable-interpolation, to disable {{ myvalue }} rendering inside that HTML tag, but still allow it to be altered using Vue or act as a Vue component.

Related issues

Perhaps I’m completely missing the point, but at the moment, this prevents me from using Vue in my app. I didn’t think this would be a major issue, yet it’s proven itself to be quite cumbersome to fix or bypass. Not sure how others handle this situation. Would love to get some feedback on this and be able to continue development using Vue.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

18reactions
yyx990803commented, Nov 16, 2016
15reactions
IlyaSemenovcommented, Jul 26, 2017

Clearly, v-pre doesn’t really answer the original question (which was “Disable interpolation” and not “Disable parsing”).

More importantly, v-pre doesn’t allow to use Vue.js on pages where there is user content and Vue.js components at the same time

See, if one uses v-pre on the root element, the entire root element is not parsed, including all Vue.js components, basically making it useless. To allow components to work, v-pre must be used on all user input separately.

But this will not work (in the long run). Template authors will forget to do that. This is a time bomb, very similar to the old times when we used raw PHP3 and had to call htmlspecialchars() on all user input to prevent XSS, but this time it’s even worse since we now have “smart” server-side frameworks which emit supposedly “safe” HTML for us (which turns out to be unsafe with Vue.js!)

For example, let’s say we use Django forms framework and have Edit User Profile page template:

<form method="post">
  {{ user_form.name }}
  <button>Save</button>
</form>

It will emit <input type="text" value="(escaped user name)">. This works very well until this code runs inside a Vue app.

If a user submits “{{ var }}” (literally) for his name, just for lulz, the HTML code will become <input ... value="{{ var }}">, and the entire page will crash and become empty (with “Interpolation inside attributes has been removed” error).

At the same time, it’s very inconvenient to guard each and every surrounding element with v-pre. Sometimes it’s not even possible: for example, I might like the button caption to be rendered with Vue depending on the app state.

And of course, if the user’s new funny name is saved into the database and then rendered somewhere else with {{ user.name }} (Django code) without explicit v-pre, it will crash Vue.js and show empty page for all other users (with "avoid using JavaScript keyword as property name: “var” error). Bummer!

The real solution is to disable delimiters but keep parsing components

Below is a quick hack that I came up with:

const noDelimiter = {replace: () => '(?!x)x'}; // return a non-matching regexp.

const app = new Vue({
	el: '#vue-app',
	delimiters: [noDelimiter, noDelimiter],
	components: {
		MyComponent,
	},
});

Just in case, pulling app vars will still be possible with v-text.

Read more comments on GitHub >

github_iconTop Results From Across the Web

vue/no-textarea-mustache
Enter to Rename, Shift+Enter to Preview. Note. Interpolation on textareas ( <textarea>{{text}}</textarea> ) won't work. Use v-model instead.
Read more >
User Generated Content - Play Console Help - Google Support
User -generated content (UGC) is content that users contribute to an app, and which is visible to or accessible by at least a...
Read more >
How can I solve "Interpolation inside attributes has been ...
Vue template syntax error: id="purchase-{{ item.id }}": Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead.
Read more >
Ionic & Vue.js - Full Tutorial (Build a Complete App) - YouTube
Learn how to build a complete native mobile app with forward-backward navigation, various Ionic components and the native device camera with ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found