GEDEV
Ten foundations of Node.js security Web security

Ten foundations of Node.js security

Security is an ongoing process

A Node.js application receives information from outside its own code and often communicates with storage or other services. Security work follows those boundaries. It is a continuing process of understanding the application, reducing unnecessary exposure and checking how it behaves when an input or dependency does not match expectations.

1. Review dependencies

Keep an inventory of the packages the application uses and review security notices. Tools such as npm audit can identify known issues, but a report does not tell you everything about a particular deployment. Review proposed upgrades and test the application after a change. Avoid applying a breaking update without understanding its effect on the code that depends on it.

2. Configure response headers

HTTP headers can restrict framing, reduce MIME interpretation problems and define where page resources may load. Express applications can use middleware to manage appropriate headers. A content security policy needs to fit the application’s actual scripts, styles and integrations. Headers support other controls; they do not replace safe handling of user content or server-side validation.

3. Validate at the server boundary

Check the type, length and allowed values of incoming information before using it. Browser validation improves the form experience, but requests can reach a server without using that form. Treat query parameters, headers and request bodies as untrusted inputs. Prefer an explicit schema and reject values the application does not understand instead of silently turning them into privileged instructions.

4. Handle displayed content safely

Use context-appropriate escaping when placing data into HTML and avoid constructing executable code from user input. If the product intentionally accepts rich HTML, use a suitable sanitisation process and a defined set of permitted elements. A plain-text field should stay plain text. Review every path that moves submitted information into another user’s page.

5. Limit repeated requests

Request limits can reduce abusive repetition on sensitive endpoints, but the configuration must reflect the actual hosting setup. A server behind a proxy needs a trustworthy way to identify the client. Shared addresses and legitimate bursts also matter. Combine appropriate application limits with hosting or CDN controls, monitor the effect and avoid presenting rate limiting as complete protection against denial of service.

6. Keep secrets out of public files

API credentials, database connection details and signing keys belong in protected configuration. Do not place them in browser JavaScript, publish them in an archive or include them in an error message. Limit their permissions and rotate exposed credentials. Configuration examples should contain placeholders, while the deployment supplies the real values through an appropriate protected mechanism.

7. Protect authenticated actions

When cookies identify an authenticated visitor, review whether another website can cause an unwanted state-changing request. Use the protection appropriate to the application, such as validated anti-CSRF tokens and careful origin checks. Session and cookie settings need to work together with the authentication flow. Do not assume that a single cookie attribute covers every interaction.

8. Return controlled errors

A visitor needs a useful message when an action fails, while the operator needs enough information to investigate. Separate those outputs. Do not publish stack traces, credentials or detailed storage errors in a public response. Record relevant events with sensible limits and avoid placing personal or secret information into a log merely because it is available.

9. Review session cookies

Use HTTPS and review Secure, HttpOnly and SameSite attributes for session cookies. These settings affect how cookies are transmitted and accessed. Select them in the context of the application’s login and integration requirements, and test the resulting flow. Session lifetime, invalidation and changes in privileges are also part of the review.

10. Use structured database operations

Use parameterised SQL queries rather than joining user input into a query string. For other databases, validate the structure and permitted operations before passing data to a driver. An ORM or ODM can simplify an implementation, but it still requires correct use. Database permissions should reflect the operations the application actually needs.

Review the deployed system

Code review, dependency review and deployment checks complement one another. A correct local setting may behave differently behind a proxy or on a shared host. Document the important boundaries and the controls applied to each one. Return to the review when the application gains a new integration, authentication flow or content feature.

Comments

    The original discussion is available in the Persian version. Send a comment below for review.

    Leave a comment

    Your email address will not be published. Name, email and comment are required.

    Comments are sent to me for review; they are not published automatically. Your email stays private.