Security Measures
The number 1 rule to make your application secure is never to use non-trusted content as your component template. Using non-trusted content is equivalent to executing a random javascript in your application. This can also lead to server violation if the script is executed at the server-side rendering.
For example:
Vue.createApp({
template: `<div>` + userInputString + `</div>` // Do not do this
}).mount('#app')
Expressions inside Vue templates are compiled into JavaScript and executed throughout the rendering process. Although expressions are evaluated against a specific rendering context, it is impractical for a framework like Vue to completely protect you from potentially malicious code execution without incurring unrealistic performance overhead due to the complexity of global execution environments.
The simplest method to avoid this category of issues is to ensure that the contents of your Vue templates are always trusted and under your complete control.
If we are not careful enough, third-party software may attack our application.
There are various potential security hazards. Let us have a look at them one by one.
Potential dangers in security
Allowing unsanitized, user-provided content to be performed as HTML, CSS, or JavaScript in any web application is potentially harmful and should be avoided wherever feasible. However, there are situations when taking a risk is justified.
User-provided material can be performed on sites like CodePen and JSFiddle, but only in an environment where this is already expected and sandboxed to some extent inside iframes. When a key feature necessitates some level of vulnerability, it's up to your team to balance the component's importance against the worst-case scenarios that the exposure allows.
Injection attacks are considered one of the most dangerous web attacks. In injection attacks, the attacker may provide malicious input to the application, injection, which may trigger executing other malicious scripts.
Let's see what the different types of injection attacks on web applications are:
1. HTML injection
HTML injection is an injection vulnerability when a user can control an input point and inject arbitrary HTML code into a vulnerable web page. This vulnerability occurs when user input is not correctly sanitized, and the output is not encoded.
You can explicitly output HTML content in circumstances when you know the HTML is safe:
- Using a template:
<div v-html="userInputHtml"></div>
2. Using a render function:
h('div', {
innerHTML: this.userInputHtml
})
3. Using a render function with JSX:
<div innerHTML={this.userInputHtml}></div>
Note: Person-provided HTML may never be deemed completely safe unless it's in a sandboxed iframe or in a portion of the app where only the user who created it can ever be exposed to it. Allowing users to develop their Vue templates also poses comparable risks.
2. URLs Injection
URL Injection occurs when a hacker has created/injected new pages on an existing website. These pages often contain code that redirects users to other sites or involves the business in attacks against other sites.
For example:
<a :href="userInputUrl">
click me
</a>
There may be a security risk if the URL has not been "sanitized" to prevent JavaScript execution using javascript. Some libraries can aid with this, such as sanitize-URL; however, keep in mind:
You already have a security issue if you're ever doing URL sanitization on the front end. Your backend should always sanitize User-provided URLs before saving them to a database. This way, the problem is avoided for every client connecting to your API, including native mobile apps. Also, keep in mind that Vue can't ensure that they'll take you to safe places even with clean URLs.
3. Styles injection
Looking at this example:
<a
:href="sanitizedUrl"
:style="userInputStyles"
>
click me
</a>
Assume that sanitizedUrl has been sanitized to be an actual URL rather than JavaScript. Malicious users might still utilize userProvidedStyles to "click jack".
For example, by styling the link into an invisible box over the "Login" button. If https://user-controlled-website.com/ is designed to look like your application's login screen, they may have just captured a user's login credentials.
We may be able to imagine how allowing user-provided content for an <style> element would create an even greater vulnerability, giving that complete user control over how to style the entire page. That's why Vue prevents the rendering of style tags inside templates, such as:
<style>{{ userInputStyles }}</style>
We advocate only giving complete control over CSS inside a sandboxed iframe to keep your users completely protected from clickjacking. When offering user control via a style binding, we advocate using its object syntax and only enabling users to provide values for properties that are safe for them to control, such as this:
<a
:href="sanitizedUrl"
:style="{
color: userInputColor,
background: userProvidedBackground
}"
>
click me
</a>
JavaScript injection
Because templates and render methods should never have side effects, we highly advise against rendering a <script> element with Vue. However, this isn't the only option to incorporate strings that are evaluated as JavaScript at runtime.
Every HTML element contains attributes like onclick, onfocus, and onmouseenter that accept JavaScript strings as values. Binding user-supplied JavaScript to any of these event attributes can be dangerous; thus, it should be avoided.
We occasionally receive vulnerability reports describing how cross-site scripting (XSS) can be performed in Vue templates. We don't consider such circumstances to be true vulnerabilities in general because there's no practical method to prevent developers from the two scenarios that allow XSS:
- Vue is specifically asked to render user-provided, unsanitized material as Vue templates by the developer. This is fundamentally dangerous, and Vue has no way of knowing where it came from.
- According to the developer, Vue is being mounted to a whole HTML page containing server-rendered and user-provided content. This is essentially the same issue as #1, except coders may do it unknowingly at times. This could lead to vulnerabilities if the attacker offers HTML that is safe as ordinary HTML but dangerous as a Vue template. Vue should never be mounted on nodes that include server-rendered and user-provided content.
Security Measures Taken by Vue
Vue takes a variety of security precautions. Some of them are mentioned below.
1. HTML Content
Content is automatically escaped when utilizing templates or render functions. In this template, that means:
<h1>{{ userInputString }}</h1>
if userInputString contained:
'<script>alert("hi")</script>'
then it would be escaped to the following HTML:
<script>alert("hi")</script>
This way, Vue prevents the script injection. This escaping is done using native browser APIs, like textContent, so a vulnerability can only exist if the browser itself is vulnerable.
2. Attribute bindings
Dynamic attribute bindings, likewise, are automatically escaped. In this template, that means:
<h1 :title="userInputString">
hello
</h1>
if userInputString contained:
'" onclick="alert(\'hi\')'
Then it would be escaped to the following HTML:
" onclick="alert('hi')
Vue prevents the closing of the title element from being used to insert new, arbitrary HTML. Because this escape is done through native browser APIs such as setAttribute, a vulnerability can only exist if the browser is vulnerable.
Vue prevents the closing of the title element from being used to insert new, arbitrary HTML. Because this escape is done through native browser APIs such as setAttribute, a vulnerability can only exist if the browser is vulnerable.
Best Practices
The general idea is that allowing unprocessed, user-supplied content to be executed (like HTML, JavaScript, or even CSS) exposes you to assaults. This advice applies whether you're using Vue, another framework, or none at all.
It is also recommended to familiarize oneself with the following resources in addition to the ones mentioned above for Potential Dangers:
If any of your dependencies involve 3rd-party components or otherwise influence what's rendered to the DOM, utilize what you've learned to evaluate the source code for potentially problematic patterns.
Backend Coordination
Cross-site request forgery (CSRF/XSRF) and cross-site script inclusion (XSSI) are mainly dealt with on the backend. Therefore they aren't a worry of Vue's. However, it is still a brilliant idea to communicate with your backend team to discover how to best interface with their API, such as submitting CSRF tokens with form submissions.
FAQs
-
What are the types of injection attacks?
The different types of injection attacks are:
HTML injection
Styles injection
JavaScript injection
URLs injection
-
Is vue secure?
Vue can be as secure as possible if we use the latest version.
-
Does vue protect against XSS?
Everything is converted to a string before being rendered. This helps prevent XSS (cross-site-scripting) attacks.
Key takeaways
Security has become an essential aspect of application development. If we are not careful enough, a malicious third party can attack our system. Several types of attacks are HTML injection, URL injection, Script injection, etc. Vue takes several measures to protect against such attacks.
To know more about Vue.js, you can visit this amazing article Reactivity in Vue.
Happy Learning!!