User:SBassett (WMF)/Sandbox/Node JavaScript Security Best Practices

Input Validation
Un-trusted user input is the first potential weakness for an application, and mitigating it early in the software development life-cycle is crucial in setting the foundations for a secure application design.

HTML Encoding
Prefer basic html-escaping functions like mw.html.escape, MediaWiki Message sanitization functions, text within jQuery, textContent or mature library like escape-html, validator.js or js-string-escape within vanilla JS.

Default Escaping
For various frameworks, such as Vue, acquaint yourself with its default (and encouraged) escaping behaviors. For example, Vue escapes most data by default, but one should be aware of situations where it does not.

SQL Injection Protection
Injection attacks exploit vulnerabilities in systems and applications that fail to validate, escape, and secure their methods of utilizing other sub-systems. Such injection flaws apply to many components, among the most popular are SQL injections.

To mitigate the risk of SQL injection, sanitize input. You can escape each input individually, or use a better method known as parameter binding or prepared statements.

Stored procedures are also another way to protect against SQL injection, even though they are difficult to test and could have other kinds of setbacks.

OS Command Injection
Avoid at all costs executing arbitrary commands from within your Node/JavaScript code. In the last resort when that is required, always make use of  function call, and only to known and well-understood OS commands which can not be tricked into running commands passed in parameters.

Functions like,  ,  ,  , and   should be avoided entirely and instead one should make use of.

Regular Expressions
Regular expressions are a powerful tool for pattern-based string-processing found within most languages, including JavaScript. While powerful, they also expose various options to developers which could be dangerous from a security perspective if not used cautiously and with adequate security controls. Below are some general examples and guidelines of security best practices for regular expressions:
 * 1) Be mindful of escaping patterns (see here)


 * 1) Avoid creating user-injectable regular expression patterns or subjects


 * 1) Avoid creating regular expression patterns which can lead to catastrophic backtracking

HTTP Headers Security
Utilizing security headers can be a great strategy to help prevent security vulnerabilities, and should be used as a defense in depth security mechanism that helps in adding a security control.

The Helmet or ExpressJS library provides an easy abstraction, and configuration for the various HTTP security headers that should be used and make an excellent choice for Node.js applications.

Strict Transport Security (HSTS)
Strict Transport Security, also known as HSTS, is a protocol standard to enforce secure connections to the server via HTTP over SSL/TLS.

Set Strict-Transport-Security header to ensure that all the requests are sent through HTTPS.

Content Security Policy
With a Content Security Policy (CSP) it is possible to prevent a wide range of attacks, including Cross-site scripting and other content injections.

This header can tell the browser which content to trust. This allows the browser to prevent attempts of content injection that is not trusted in the policy defined by the application owner.

For example, a policy for allowing JavaScript to be executed only from our own domain and from Google’s:

A full list of supported directives can be found on the CSP policy directives page on MDN.

X-Content-Type-Options
The purpose of this header is to instruct the browser to avoid guessing the web server’s content type which may lead to an incorrect render than that which the web server intended.

An example of setting this header:

Headers Validation
In the condition that the code is hosted via a publicly-routable domain name, tools like securityheaders and csp-evaluator can be used.

The former can help with the analysis of security headers while the latter can evaluate the correctness and safety of a content-security policy.

Authentication
The first step to properly handling sensitive data is authentication. You need to ensure that a user is who they say they are.

TLS
Routing all the traffic through a secure sockets layer such as TLS prevents attackers from sniffing data on the wire and makes it harder for them to perform MITM attacks to eavesdrop traffic.

Signed Requests
Anytime you expose endpoints/resources to the internet for others to use, it's important to make sure that the people who use those endpoints are who they say they are. This can be accomplished by request signing.

Credentials Management
To meet security standards, combine a proper hash function with an adequate algorithm which results in a secure hash function.

Secure Session Management
The sensitive nature of the session identifier calls for more ways to protect it. A good defense against session fixation and also works well against session hijacking is to re-generate and/or invalidate session identifiers after any sensitive actions (privilege escalation, login/logout, etc…) that are taken by the user.

Session IDs should also not be exposed to URLs but applications should use an alternative mechanism for transmitting session tokens, such as HTTP cookies or hidden fields in forms that are submitted using the POST method.

Filesystem I/O
Like many other programming languages, JavaScript features various APIs to access a local filesystem. And many of the security concerns from other languages are the same for JavaScript, notably: Avoid public exposure of data Avoid vuln-DoS Avoid RCE via injection (use existing lang APIs or robust packages)

Serialization, Deserialization
Prefer JSON.parse Do not accept serialized objects from untrusted sources

Cross Site Request Forgery
The preferred way to protect against CSRF attacks is by generating a token, which is in essence a random, unguessable string, for every action that is performed by the user.

Please use tiny-csrf for anti CSRF implementation.

Server Side Request Forgery
One of the best ways to circumvent SSRF attacks is by employing strong input validation in conjunction with an allow list. Allow list validation is appropriate for all input fields provided by the user. Allow list validation involves defining exactly what is authorised, and by definition, everything else is not authorised.

The first layer of validation can be applied using ip-address that ensure the security of the IP address format.

After ensuring the validity of the incoming IP address, the second layer of validation is applied. An allow list is created after determining all the IP addresses (v4 and v6 to avoid bypasses) of the identified and trusted applications.

Secure dependency management

 * Prefer recent versions of dependencies
 * Prefer dependencies with more contributors and more frequent, recent contributions
 * Stay informed about security releases of critical dependencies and update your code in a timely manner
 * Prefer dependencies with few dependencies, written in a pure/vanilla JS style
 * Prefer using as few dependencies as possible, especially production dependencies or development dependencies which influence build steps and other critical processes
 * Automate tools like npm audit and npm outdated to run in CI for your code, or within local environments during or after critical development cycles, and work to remediate any issues in a timely manner
 * Prefer the Security Team’s Application Security Gitlab include templates as guidance for implementing secure dependency management within CI for your code base.

Dangerous JS functions
See our internal list…

Use standard template for services (service-template-node)
Ensure config and dependencies are up-to-date, especially within your fork of service-template-node