Good Practices
Learn how you can make your app even more secure.
Only return what is necessary
If you just need a certain field of an object, you should only return the specific fields required. In other words, if you only need to list names of the users available, you are not returning their email addresses or credit card numbers in addition to their full names.
You can read more about this recommendation here
Fortunately, in Nuxt 3, you can utilize pick
or use interceptors
concepts for both useAsyncData
and useFetch
to sanitize what you get from the server without leaking confidential data.
const { data, pending, error, refresh } = await useFetch('https://api.nuxtjs.dev/mountains',{
pick: ['title']
})
Handling State with Care in Nuxt SSR
When developing applications with Nuxt.js in SSR mode, it's crucial to handle reactive state with care to avoid Cross-Request State Pollution. This issue arises when state is shared unintentionally between requests, leading to potential data leaks and inconsistent application behavior. Nuxt's documentation here provides best practices for state management in such scenarios.
Consider the issue with global ref in a composable.
const unsafeGlobal = ref<number>(1);
export function useSafeRef() {
const safeRef = ref<number>(2);
return {
unsafeGlobal,
safeRef
}
}
For enhanced safety and to adhere to Nuxt's best practices, it's recommended to manage state using abstractions with useState
. This utility function is specifically designed for Nuxt applications to ensure state is isolated per request, effectively preventing cross-request state pollution:
const safeGlobal = useState<number>('safeGlobal', () => 5);
export function useSafeRef() {
const safeRef = useState<number>('safeRef', () => 2);
return {
safeGlobal,
safeRef
}
}
Note: useState is global across components. Use a unique key if you want to keep them separate.
Use access control lists
Authorization prevents users from acting outside of their intended permissions. In order to do so, users and their roles should be determined with consideration of the principle of least privilege. Each user role should only have access to the resources they must use.
You can use the acl
module to provide ACL (access control list) implementation. With this module, you can create roles and assign users to these roles.
Install the module:
npm install acl # or yarn
Add use it in your code:
var acl = require('acl');
acl = new acl(new acl.memoryBackend())
// guest is allowed to view blogs
acl.allow('guest', 'blogs', 'view')
Perform Application Activity Logging
Logging application activity is an encouraged good practice. It makes it easier to debug any errors encountered during application runtime. It is also useful for security concerns, since it can be used during incident response. In addition, these logs can be used to feed Intrusion Detection/Prevention Systems (IDS/IPS).
Install the module:
npm i winston # or yarn
Add then use it in your application like this:
const logger = new (Winston.Logger) ({
transports: [
new (winston.transports.Console)(),
new (winston.transports.File)({ filename: 'application.log' })
],
level: 'verbose'
});
Use eslint security plugins
eslint-plugin-security-node
ESLint plugin containing Node.js security rules. This plugin will help to identify potential threats and prevent attacks.
Install the module:
npm install --save-dev eslint-plugin-security-node # or yarn
Add the following configuration to .eslintrc
:
"plugins": [
"security-node"
],
"extends": [
"plugin:security-node/recommended"
]
eslint-plugin-anti-trojan-source
ESLint plugin to detect and stop Trojan Source attacks from entering your codebase.
Install the module:
npm install --save-dev eslint-plugin-anti-trojan-source # or yarn
Add the following configuration to .eslintrc
:
"plugins": [
"anti-trojan-source"
],
"extends": [
"plugin:anti-trojan-source/recommended"
]
Use Snyk
Snyk allows you to find and automatically fix vulnerabilities in your code, open source dependencies, containers, and infrastructure as code — all powered by Snyk’s industry-leading security intelligence.
For development, especially useful are two Snyk products; Snyk Code and Snyk Open Source. The first is responsible for securing the code you write, while the second helps avoid vulnerable dependencies. Apart from that, Snyk CLI finds hardcoded secrets so that you won't push them to your repository.
Lint Lockfile
Lockfiles are used as trusted whitelist of resources manifest to fetch packages from. However, keeping track of the changes introduced to lockfiles is not an easy task as they are designed to be consumed by machines 🤖.
Usage:
npx lockfile-lint --path yarn.lock --allowed-hosts npm yarn --validate-https
Check Awesome Node Security
There are many ways that you can make you app more secure and apart from OWASP and Helmet, there are sources like Awesome Node.js Security by Liran Tal.
Check it out to learn about other tools that you can use.
Use Security Checklists
There are few useful checklists that tackle the topic of security in web applications that you can check out to develop more secure applications:
- https://html5sec.org/
- https://developer.mozilla.org/en-US/docs/Learn/Server-side/First_steps/Website_security
- https://vuejs.org/guide/best-practices/security.html
- https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html
- https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html
- https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html