
Inline adoc files when they are included exactly once. Also fix language tags because this inlining gives us better information on what language the code is written in.
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
|
|
|
|
* https://owasp.org/Top10/A03_2021-Injection/[OWASP Top 10 2021 Category A3] - Injection
|
|
* https://owasp.org/www-project-top-ten/2017/A7_2017-Cross-Site_Scripting_(XSS)[OWASP Top 10 2017 Category A7] - Cross-Site Scripting (XSS)
|
|
* https://cwe.mitre.org/data/definitions/79[MITRE, 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]
|
|
|