91 lines
3.1 KiB
Plaintext
91 lines
3.1 KiB
Plaintext
Vue.js framework prevents XSS vulnerabilities by automatically escaping HTML contents with the use of native API browsers like ``++innerText++`` instead of ``++innerHtml++``.
|
|
|
|
It's still possible to explicity use ``++innerHtml++`` and similar APIs to render HTML. Accidentally rendering malicious HTML data will introduce an XSS vulnerability in the application and enable a wide range of serious attacks like accessing/modifying sensitive information or impersonating other users.
|
|
|
|
|
|
== Ask Yourself Whether
|
|
|
|
The application needs to render HTML content which:
|
|
|
|
* could be user-controlled and not previously sanitized.
|
|
* is difficult to understand how it was constructed.
|
|
|
|
There is a risk if you answered yes to any of those questions.
|
|
|
|
|
|
== Recommended Secure Coding Practices
|
|
|
|
* Avoid injecting HTML content with ``++v-html++`` directive unless the content can be considered 100% safe, instead try to rely as much as possible on built-in auto-escaping Vue.js features.
|
|
* Take care when using the ``++v-bind:href++`` directive to set URLs which can contain malicious Javascript (``++javascript:onClick(...)++``).
|
|
* Event directives like ``++:onmouseover++`` are also prone to Javascript injection and should not be used with unsafe values.
|
|
|
|
|
|
|
|
== Sensitive Code Example
|
|
|
|
When using Vue.js templates, the ``++v-html++`` directive enables HTML rendering without any sanitization:
|
|
----
|
|
<div v-html="htmlContent"></div> <!-- Noncompliant -->
|
|
----
|
|
|
|
When using a rendering function, the ``++innerHTML++`` attribute enables HTML rendering without any sanitization:
|
|
----
|
|
Vue.component('element', {
|
|
render: function (createElement) {
|
|
return createElement(
|
|
'div',
|
|
{
|
|
domProps: {
|
|
innerHTML: this.htmlContent, // Noncompliant
|
|
}
|
|
}
|
|
);
|
|
},
|
|
});
|
|
----
|
|
|
|
When using JSX, the ``++domPropsInnerHTML++`` attribute enables HTML rendering without any sanitization:
|
|
----
|
|
<div domPropsInnerHTML={this.htmlContent}></div> <!-- Noncompliant -->
|
|
----
|
|
|
|
== Compliant Solution
|
|
|
|
When using Vue.js templates, putting the content as a child node of the element is safe:
|
|
[source,javascript]
|
|
----
|
|
<div>{{ htmlContent }}</div>
|
|
----
|
|
|
|
When using a rendering function, using the ``++innerText++`` attribute or putting the content as a child node of the element is safe:
|
|
[source,javascript]
|
|
----
|
|
Vue.component('element', {
|
|
render: function (createElement) {
|
|
return createElement(
|
|
'div',
|
|
{
|
|
domProps: {
|
|
innerText: this.htmlContent,
|
|
}
|
|
},
|
|
this.htmlContent // Child node
|
|
);
|
|
},
|
|
});
|
|
----
|
|
|
|
When using JSX, putting the content as a child node of the element is safe:
|
|
[source,javascript]
|
|
----
|
|
<div>{this.htmlContent}</div>
|
|
----
|
|
|
|
== See
|
|
|
|
* OWASP - https://owasp.org/Top10/A03_2021-Injection/[Top 10 2021 Category A3 - Injection]
|
|
* OWASP - https://owasp.org/www-project-top-ten/2017/A7_2017-Cross-Site_Scripting_(XSS)[Top 10 2017 Category A7 - Cross-Site Scripting (XSS)]
|
|
* CWE - https://cwe.mitre.org/data/definitions/79[CWE-79 - Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')]
|
|
* https://vuejs.org/v2/guide/security.html#Injecting-HTML[Vue.js - Security - Injecting HTML]
|
|
|