NodeJS Cybersecurity 2022 Best Practices Summarized
Attack Demonstrations
Cross Site Request Forgery — — — — — — — — — — — — Cross Site Scripting
Denial of Service — — — — — — — — — — — — — — — — — Cookie Theft
Code Injection — — — — — — — — — — — — — — — — — — Malware Upload
Application security
Use flat promise chains — Increase readability to reduce errors by avoiding deep promise chains. Use async await to keep promises flat and avoid callback hell. You are less likely to make security errors if you know what is going on in the code.
Set Request Size limits — If there is no limit on the size of requests, attackers can send requests with large request bodies that can exhaust server memory and/or fill disk space.
Related tool: raw-body package
Do not block the event loop — When CPU intensive operations occur, they block the event loop. To prevent blocking the event loop make CPU intensive operations asynchronous. To prevent operations that rely on each other from occurring in the wrong order write these in a single callback function, within the async operation relied upon.
Perform input validation — Validate input server-side using a whitelist, when possible, to prevent a variety of attacks. If this is not possible, normalize the data to an expected format and have a blacklist check for dangerous values. With file uploads, validate the file size, target path, and compress size to prevent zipbombs. Change the filename server-side as well. For more on protecting when working with emails, files, images, etc see Input Validation — OWASP Cheat Sheet Series.
Related tool: validator and mongo-express-sanitize package
Perform output escaping — Escape HTML and JavaScript shown to users by using NPM packages.
Related tool: escape-html or node-esapi packages
Perform application activity logging — Log activity using packages for debugging and incident response.
Related tool: Winston, Bunyan, or Pino packages
Monitor the event loop — Use toobusy-js to prevent denial of service informing you of activity when the server is under heavy traffic so you can determine if you need more resources or need to respond to a DoS attack.
Related tool: toobusy-js package
Take precautions against brute forcing — Use Express-bouncer or express-brute to increase delay with each failed request. You also use recaptcha or deny requests after a set number of attempts. Allow them to use 2FA to validate.
Related tool: Express-bouncer or express-brute
Use anti-CSRF tokens — You can create tokens using Csurf if your framework doesn't have built-in protection against CRSF.
Related package: Csurf
Cross-Site Request Forgery Prevention — OWASP Cheat Sheet Series
Cross Site Scripting Prevention — OWASP Cheat Sheet Series
Remove unnecessary routes — When using frameworks that generate routes for you make sure you disable ones you are not using.
Prevent HTTP Parameter Pollution — To prevent HPP use hpp to ignore all values except the last in req.body and req.query.
Related tool: hpp package
Only return what is necessary — Do not return unnecessary information such as an email or credit card number if it is not needed for the single purpose of the route.
Use object property descriptors — Describe properties so that new properties cannot be added to the object. Use Schemas such as from mongoose to define structure.
Use access control lists — Use acl to determine what a user is authorized to access.
Related tool: acl package
Error and Exception handling
Handle uncaughtException — Provide custom uncaught exception handing. Cleanup resources before closing.
Listen to errors when using EventEmitter — Always listen for error events to ensure the application doesn’t crash.
Handle errors in asynchronous calls — Express handles sync errors but not async so you should handle these yourselves making error the first arguement.
Server security
Set cookie flags appropriately — Set the cookie HttpOnly, SameSite, and Secure to true.
Use appropriate security headers — A good tool for setting meta data such as headers is Helmet. Some headers to consider are Strict-Transport-Security, X-Frame-Options, X-XSS-Protection, X-Content-Type-Options, Content-Security-Policy, Cache-Control, Expect-CT, Public-Key-Pins.
Nodejs Security — OWASP Cheat Sheet Series
Platform Security
Keep your packages up-to-date — Use a tool like Snyk to check a package before you install it and Retire.js for checking for new vulnerabilities in the packages you are already using.
Related tool: Retire.js package
Do not use dangerous functions — Some built-in JavaScript functions are known to be dangerous to use and alternatives should be used where possible such as eval and child_proces.exec. In other cases like vm and fs packages, you should still exercise caution.
BlueClosure — Javascript Security: JavaScript Dangerous Functions (Part 1) — HTML Manipulation
Stay away from evil regexes — Avoid ReDoS attacks by setting an input limit for regular expressions.
Related tool: vuln-regex-detector package
Run security linters — Use ESLint or JSHint as Static Analysis Security Testing tools to find security vulnerabilities you may have missed when going through best practices.
Related tool: nodesecurity/eslint-plugin-security: ESLint rules for Node Security (github.com)
Use strict mode — “use strict” at the top of your JavaScript file can help warn you of dangerous legacy features and hidden errors.
Design security into your design from the start by utilizing a security framework, security checklist, and threat modeling before you start writing your code. Continue to use and maintain these during the development lifecycle. Always use a cybersecurity expert to check your application rather than hoping you covered all angles. Provide a standard of security you are using to the users so they know their privacy and safety of data while using your application.
References
Nodejs Security — OWASP Cheat Sheet Series
Top 10 Node.js Security Best Practices — Risks & Prevention (snyk.io)
Best Security Practices in Node.js — GeeksforGeeks
(2) A Node.js Security Roadmap — Mike Samuel — JSConf EU 2018 — YouTube
lirantal/awesome-nodejs-security: Awesome Node.js Security resources (github.com)