Skip to main content

Overview

This section of the guidebook focuses on Security. Having secure applications and infrastructure is key to help protect our fundraisers and supporters data.

Having strong security best practices is key to:

  • Protecting our supporters, fundraisers and users data (legal and trust requirement).
  • Eliminating cost of a compromised system using resources.
  • Eliminating cost of a system being compromised resulting in a reduction on fundraising.

It is highly recommended to read over this section to get an understanding of the key areas of security.

Checklist

Below is a useful checklist of key things you should consider when developing projects.

Common

DoDon't
✔️ If in doubt reach out to InfoSec & Data Governance❌ Use eval()
✔️ Check for vulnerable regular expressions❌ Use child_process.exec()
✔️ Run ESLint❌ Use fn()

Infrastructure

DoDon't
✔️ Regularly review AWS Security Hub❌ Store secrets insecurely
✔️ Use access control lists❌ Store secrets in Lambda/ECS environment variables
✔️ Use WAF for APIs
✔️ Apply the principle of least privilege
✔️ Regularly rotate secrets

Frontend

DoDon't
✔️ Sanitize user generated content❌ Use dangerouslySetInnerHTML
✔️ Sanitize query input❌ Use unsafe JS evaluation (eval, setTimeout, setInterval, new Function())
✔️ Sanitize script tags
✔️ Setup a CSP
✔️ Use CAPTCHAs

Repository

DoDon't
✔️ Have a process to keep dependencies up to date❌ Store secrets in source

Common Requirements

If in doubt reach out to InfoSec & Data Governance

If you are unsure or unclear about any aspect of security reach out to InfoSec. If you are unsure or unclear about any aspect of data security and handling reach out to Data Governance.

Run security linters

When developing code, keeping all security tips in mind can be really difficult. This is why there are Static Analysis Security Testing (SAST) tools. These tools do not execute your code, but they simply look for patterns that can contain security risks. As JavaScript is a dynamic and loosely-typed language, linting tools are really essential in the software development lifecycle. The linting rules should be reviewed periodically and the findings should be audited. Another advantage of these tools is the feature that you can add custom rules for patterns that you may see dangerous. ESLint and JSHint are commonly used SAST tools for JavaScript linting.

Use the CRUK ESLint package as a first step - ESLint.

Avoid using certain functions

There are some JavaScript functions that can be dangerous and should only be used where necessary or unavoidable. The first example is the eval() function. This function takes a string argument and executes it as any other JS source code. Combined with user input, this behaviour could potentially lead to remote code execution vulnerability.

Similarly, calls to child_process.exec can also be very dangerous. This function acts as a bash interpreter and sends its arguments to /bin/sh. By injecting input to this function, attackers can execute arbitrary commands on the server.

In addition to these functions, some modules require special care when being used. As an example, fs module handles filesystem operations. However, if improperly sanitized user input is fed into this module, your application may become vulnerable to file inclusion and directory traversal vulnerabilities. Similarly, vm module provides APIs for compiling and running code within V8 Virtual Machine contexts. Since it can perform dangerous actions by nature, it should be used within a sandbox.

These functions and modules should be used carefully, especially when combined with user input.

Avoid using vulnerable regular expressions

The Regular Expression Denial of Service (ReDoS) is a type of Denial of Service attack that uses regular expressions. Some Regular Expression (Regex) implementations cause extreme situations that makes the application very slow. Attackers can use such regex implementations to cause application to get into these extreme situations and hang for a long time. Such regular expressions are called evil if application can be stuck on crafted input. Generally, these regular expressions are exploited by grouping with repetition and alternation with overlapping. For example, the following regular expression ^(([a-z])+.)+[A-Z]([a-z])+$ can be used to specify Java class names. However, a very long string can also match with this regular expression. There are some tools to check if a regex has a potential for causing denial of service. One example is vulnerable-regex-detector.