The global influx of digital transformation is creating pressure on infrastructure. All the while, threat actors are continually improving their attack techniques. If there is a vulnerability to be found, it will be exploited. This is why many teams are shifting security to the left, even going as far as evolving their development methodology from DevOps to DevSecOps.
Developers still have remaining concerns, most of which focus on release time. However, you should not need to compromise fast releases in favor of security.
In this article, you will learn about four methods that can enable you to secure your Vue apps quickly. These are simple security practices that should not interrupt your workflow.
Vue is a progressive framework for building web user interfaces. It’s an adoptable, non-monolithic framework that integrates with other frameworks, such as React and Angular. While Vue is only focused on the view layer, it can quickly build Single-Page Applications (SPAs).
With Vue 3, it is now written in and has full support for TypeScript. There’s no need to worry about including any additional tooling and assisting to prevent potential runtime errors as our applications grow.
Review the following best practices to learn how to secure applications running on Vue. These best practices will help you prevent attacks like cross-site scripting (XSS) and cross-site request forgery (CSRF), which can be a low-profile, automated attack or part of an advanced persistent threat used as the first step in a more extensive attack campaign.
Cross-Site Scripting (XSS) attacks are a type of code injection, and one of the most common types of XSS attacks is a DOM-based attack. The attacker aims to inject hostile code into a DOM element on your website to perform malicious attacks when users land on the web page, such as stealing user data. To prevent this, developers need to sanitize untrusted inputs in several places:
- HTML (Binding inner HTML)
- Style (CSS)
- Attributes (Binding values)
- Resources (Referring files)
Sanitizing data is done best before displaying the data to the user screen. It cleanses the original data to prevent exploiting any security holes in your application.
You always want to convert untrusted values provided by external users into trusted values. The vue-sanitize library, available on NPM, makes it easy to whitelist and sanitize user input values on your server.
It sanitizes HTML and prevents XSS attacks by consuming a string of dirty HTML. It then removes anything considered dangerous HTML, while allowing any HTML tags you’ve whitelisted.
import VueSanitize from "vue-sanitize"; Vue.use(VueSanitize);
If you’d like to whitelist tags and options, it’s effortless to accomplish (see below):
defaultOptions = allowedTags: ['a', 'b'], allowedAttributes: 'a': ['href'] Vue.use(VueSanitize, defaultOptions);
VueSanitize will then take the values that users pass along and sanitize the HTML—keeping anything that we’ve whitelisted, preventing code injection, and XSS attacks.
As tempting as it may be to customize Vue libraries to fit your needs, doing so will make you reliant on the current version of Vue that you’re using. You will find it challenging to upgrade to later versions of Vue and may miss out on critical security fixes and features.
The best way to make improvements and fixes to Vue libraries is to share your changes with the community via a pull request. This will allow other developers to review your changes and consider adding them to the next Vue version.
You should also keep any NPM packages that you’re using in your Vue application up-to-date. This action will ensure that any security issues that have been addressed or improvements that have been made are included in your application.
A key advantage of Vue is that it can save developers the need to edit the browser’s DOM to render components manually; however, that doesn’t mean that there won’t be times where developers need direct access to DOM elements. In these cases, Vue provides users with escape hatches, such as findDOMNode and ref.
Using something like the ref to gain access to a DOM element is very simple (see below):
<template> <div id="account"> <user-component ref="user" /> </div> <template> <script> import UserComponent from "/components/UserComponent"; export default name: "user-component", components: UserComponent , mounted() this.$refs.user.$refs.userName.focus(); ; </script>
We now have a reference to the DOM element of our user component and its API, which we can use the application to manipulate the DOM elements directly, instead of going through Vue to do so. However, this can leave your application open to XSS vulnerabilities. To prevent malicious agents from taking advantage of your application, there are a few steps that you can take to secure it.
- Avoid directly outputting the HTML code, instead of outputting text
- Sanitize your data by using the VueSanitize library
- Use proper APIs to generate HTML nodes safely
CSRF is an attack where a user trusted by an application sends unauthorized, malicious commands. One example of a CSRF would be when a user wants to delete their account on your website. To delete their account, they need to be signed in to your website.
To validate the authentication of the delete request, the session is stored in the browser via a cookie. However, this leaves a CSRF vulnerability on your site. Users need to send a delete request to the server with the cookie present in the browser.
A common way to mitigate this threat is to have the application server send a random authentication token included in a cookie. The client reads the cookie and adds a custom request header with the same token in all subsequent requests. This makes it possible to reject a request made by an attacker who does not possess the authentication token.
It can then provide an API URL using a script tag, meaning that you are including someone else’s code in your program. You don’t have any control over what is in that code and you don’t have any control over the server’s security on which it is hosted.
The server can mitigate this attack by making all JSON responses non-executable. For example, this can be done by prefixing them with the string “)]}’,n” and then using code to remove it before parsing the data. An attacker cannot do so since script inclusion is always the entire script.
Security is a crucial concern that should be addressed, not only by security professionals, but also by developers. The simple practice of writing secure code can help prevent the exploitation of bugs and errors.
While there’s no such thing as “perfect”, and there will always be more fixes to make, patches to release, and urgent matters to respond to, adopting a secure code mindset can help you avoid unnecessary risks.