Skip to content

stakater/security-guide-for-developers

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 

Repository files navigation

Security Guide for Developers

Really important stuff!

  • don’t put live data on any local device unless it has been signed off for such usage
  • only access live / sensitive data under strict guidance (each service should have rules around its usage)
  • understand the policies around where you should store your source code. Do not put information such as passwords, IP addresses etc. in code repositories

Automated security testing

Whilst projects will have a penetration test and IT health check, these are periodic tasks. We also encourage teams to run automated security testing tools so they can pick up security vulnerabilities much more quickly.

Important Note!! Must be a periodic job!

Note that we highly recommend that these security testing tools are run on a regular basis, not just when code is pushed. This is because new vulnerabilities may emerge without you having made any changes to your application, and it is important that these are picked up.

Web application security testing

This section details tools that can be used to black box test your web application for common vulnerabilities.

NodeJS dependency security testing

This section details how to check your NodeJS project's dependencies for vulnerabilities.

Snyk

Snyk checks your NodeJS applications dependencies for vulnerabilities. We recommend 2 ways to use Snyk:

  1. Github integration Snyk can automatically raise PRs against your repository to fix vulnerabilities, more details available here:
    https://snyk.io/docs/github/

  2. Manually Snyk has a CLI that you can use manually or as part of a CI pipeline. The easiest way to configure this is to:

  • Locally run snyk wizard
  • The wizard will offer to add code to your package json to run snyk vulnerability testing alongside your usual npm test jobs
  • Accept this and any CI test jobs will fail if there are new vulnerabilities

Scala dependency security testing

This section details how to check your Scala project's dependencies for vulnerabilities.

SBT Dependency Check

SBT Dependency Check checks your dependencies against the OWASP database of vulnerable modules. It does work but is relatively immature, so not as easy to use as Snyk. You can find SBT dependency check here

Java dependency security testing

This section details how to check your Java project's dependencies for vulnerabilities. OWASP provide some tools for this, which includes a command line tool as well as a maven plugin. This is essentially the same tool as SBT Dependency Check above, just more for Java. You can find Dependency Check for Java here

General best practices

Development process

  • security should be part of the agile delivery process and be applied per story
  • enforce protected branches
  • enforce reviews via pull requests
  • require signed commits
  • have a well defined, understood and enforced code review process
  • ensure you have fast, repeatable deploys with automated testing
  • monitor for security advisories and patches

Application design

  • favour simple systems; they are easier to secure
  • adhere to the principles of clean code - this makes applications easier to understand
  • consider design by contract. Preconditions set input constraints, postconditions what must be true; test against these
  • reduce the attack surface by removing unnecessary code / libraries endpoints, remove demo enabling code, default passwords etc.
  • minimise integrations, understand and protect against compromised 3rd parties (e.g. a script sourced from an untrusted 3rd party could be malicious)
  • favour small components with a clear, single responsibility
  • favour using established libraries and frameworks over rolling your own. However, import only trustworthy software and always verify its integrity
  • avoid the use of shared variables / globals
  • prefer immutability
  • avoid nulls by using Option e.g. Scala Option and Java Optional

General protection

  • be careful using <script src> unless you have complete control over the script that is loaded
  • if submitting a form modifies data or stage, use POST not GET
  • avoid SQL injection / javascript injection by ensuring all queries are parameterised (and / or use e.g. an ORM, Active Record)
  • protect against cross site scripting [(XSS)] (https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet) by escaping / sanitising untrusted data using a standard security encoding library. Also consider using [Content Security Policy] (https://w3c.github.io/webappsec-csp/2/) headers to whitelist assets a page can load
  • protect against cross site request forgery (CSRF) which target state-changing requests. Check standard headers to verify the request is same origin AND check a CSRF token
  • ensure that resources you load are as expected by using subresource integrity
  • use HTTP Strict Transport Security (HSTS) with e.g. a "Strict-Transport-Security: max-age=8640000; includeSubDomains" HTTP Header to protected against SSL strip attacks. Consider entering your domain into the HSTS preload list
  • protect against clickjacking by using the "X-Frame-Options: DENY" HTTP Header
  • Don’t use JSONP to send sensitive data. Since JSONP is valid JavaScript, it’s not protected by the same-origin policy
  • do not eval any non-verified String (e.g. don't eval a String expected to contain JSON - use JSON.parse instead)
  • do not store sensitive information or session ids in LocalStorage (it is always accessible via javascript)
  • use the object sessionStorage instead of localStorage if persistence longer than the browser session is not required
  • validate URLs passed to XMLHttpRequest.open (browsers allow these to be cross-domain)
  • only use WebSockets over TLS (wss://) and be aware that communication can be spoofed / hijacked through XSS
  • use different subdomains for public facing web pages, static assets and administration

Cookies

  • use secure, signed, httpOnly cookies when possible (and mandatory if it contains account information)
  • encrypt any sensitive data with e.g. cookie-encyption (node)
  • avoid putting sensitive information in 3rd party cookies

Testing

  • favour Test Driven Development to encourage good test coverage and application design
  • test in an environment configured like live (infrastructure, replication, TLS etc.) with similar data profiles (but not with live data) as early as possible
  • any testing against live data in non prod environments (even if scrubbed / anonymised) needs appropriate signoff
  • use Continuous Integration (CI) and ensure good automated unit, integration, acceptance, smoke, performance, security tests
  • underatke an IT Health Check (ITHC, Penetration Test, Pen Test) for new services or significant changes
  • consider use of a version of chaos monkey e.g. Simian Army to test random instance failures

Running application

  • always use HTTPS (ensure you use TLS 1.2)
  • web applications must use a properly configured Web Application Firewall (WAF) e.g. NAXSI
  • remove unnecessary functionality and code
  • if exceptions occur, fail securely
  • monitor metrics e.g. Sysdig
  • create audit for successful and unsuccessful login attempts, unsuccessful authorisation attempts, logouts etc.
  • disable unused HTTP methods
  • restrict all applications and services to running with the minimum set of privileges
  • isolate dev environments from the production network, and allow access to dev from authorised users only (dev environments can be a common attack vector)

Validation

  • perform integrity checks to ensure there has been no tampering of e.g. hidden fields or transaction ids. Can use checksum, HMAC, encryption or digital signature depending on the risk
  • server-side validation of all inputs, including headers, cookies, redirects
  • prefer to accept known good input rather than reject known bad input
  • sanitise input if necessary (e.g. strip out whitespace or hyphens from phone numbers)
  • ensure option selects, checkbox and radio contain only allowable (given) values
  • validate data type / length / range / allowed chars
  • always re-validate previously entered form data in case it has been surreptitiously altered; hidden fields should be validated too
  • all validation failures should result in input rejection with an appropriate message to the user
  • have automated tests to check a reasonable range of validation failures are as expected

Error handling and logging

  • do not log sensitive information (e.g. account information or session identifiers) unless necessary
  • ensure no debugging / stack traces are displayed to the end user in production
  • use generic error messages and custom error pages in production
  • prevent tampering of logs by ensuring they are read only and do not allow deletions
  • ensure a mechanism exists to conduct log analysis
  • restrict access to logs

Data protection

  • understand the data that will be used, its retention and removal policy
  • understand who will be accessing the service / data, with what devices via what networks / 3rd party services
  • only store and use the minimum amount of data required to fulfil the user need
  • restrict users to only being able to view the data they need
  • do not provide interfaces that allow arbitrary querying of data
  • don’t allow bulk datasets to be downloaded or too much data made visible on a page
  • rate limit access to large datasets and record access attempts (also limit the number of transactions a user or device can perform in a given time period)
  • favour use of database schemas, even for noSQL databases by using e.g. Mongoose for MongoDB
  • avoid caching data within services unless necessary
  • protect caches / temp files containing sensitive data from unauthorised usage and purge them ASAP
  • use synchronous cryptography (shared secret) e.g. AES to encrypt / decrypt your own data if its sensitive. Ensure the shared key is held securely and separately to the data
  • encode fields that have especially sentive values
  • disable autocomplete on forms for sensitive fields, including passwords
  • disable client-side caching for pages containing sensitive data by using appropriate HTTP cache headers i.e. "Cache-Control: no-store", "Expires: 0" and "Pragma: no-cache"
  • anonymise data (ensuring re-identification cannot take place) sent to reporting tools or being used as test data
  • consider encrypting partially completed forms under a key held by the user if you do not need to use this data
  • applications should connect to databases with different credentials for each ‘trust distinction’ e.g. user, read-only, admin, guest
  • do not store passwords, connection strings etc. in plain text

Authentication / authorisation

  • refer to the CESG password guidance when deciding your password policy for users
  • if authentication is required, authenticate and authorise on every request
  • use centralised authentication controls, favour SSO
  • if authentication services go down they should not give users unauthorised access
  • authentication failure should give no information as to which part failed - all error responses should be generic and the same
  • separate authentication and authorisation from the resource that is being requested
  • ensure every page requires a role, even if it is "guest"
  • admin / account management functions should be particularly secure
  • any credential store should only use cryptographically strong one-way salted hashes that don’t allow brute-force attacks. (use bcrypt, scrypt or PBKDF2). Salt length should be at least 128 bits and can be stored in db (prevents rainbow attacks)
  • enforce the changing of temporary or default passwords when they are used
  • password reset links should be time-limited and one-time use only
  • prevent users from reusing a password
  • notify users when a password reset occurs
  • indicate the last attempted login to a user
  • disable remember me and do not allow the client to store credentials
  • re-authenticate users before performing any critical operation such as uploading files
  • more secure: use multi-factor authentication (MFA / 2FA) to obtain one-time passwords (OTP). Favour Google Authenticator, Authy etc. over SMS (which has weak encryption standards that allow for man-in-the-middle attacks)
  • consider introducing captcha after a number of login failures
  • lock the account after a number of login failures for a given period of time
  • enable all users to be force logged out (e.g. invalidating all session cookies)
  • be prepared to change the hashing mechanism; ensure you can do it in the fly when users need to log in

Session management

  • session IDs should be unique, non guessable and non-sequential and suitably long
  • use httpOnly, secure, session cookies to store session ids client-side
  • use httpOnly, secure, signed, encrypted session cookies if you want to store session data client-side
  • set the path and domain for cookies to a suitably restricted value
  • session inactivity timeout should be as short as possible
  • logout should always be available
  • expire session ids after a defined period (to reduce impact of session hijacking)
  • session invalidation (due to e.g. timeout, logout, expiration or unauthorised reuse) should immediately delete the session id + session data on the server and client (include a Set-Cookie directive in the response with an expiration time in the past)
  • sensitive session data should be stored on the server
  • clear out expired server-side session data frequently
  • do not allow concurrent logins for the same user id
  • session identifiers should only be in the HTTP cookie header (not in a GET request or anywhere else)
  • for sensitive data require per request rather than per session tokens

Integration

  • ensure there is a clear, tightly defined schema using e.g. JSON Schema for each integration point and ensure all input is validated against this schema
  • automated tests should verify that messages conform to the expect schema for each integration point
  • rate limit inputs and check payload size -- consider using the circuit breaker design pattern at integration points

Communication security

  • implement transport encryption for the transmission of all sensitive information and supplement with encryption of the payload if necessary
  • TLS certificates should be valid and have the correct domain name, not be expired, and be installed with intermediate certificates when required
  • specify character encodings for all connections
  • do not allow the mix of TLS and non-TLS content
  • filter parameters containing sensitive info in the HTTP referer header when linking to external sites

File uploads

  • require authentication first if appropriate
  • check file type, characters, size etc.
  • virus / malware scan, preferably in a disposable container
  • turn of exec privileges on file upload directories and ensure file is read-only

REST / API security

  • use session-based authentication either using a session token via a POST or an API key as via a POST body argument or as a cookie
  • prefer 2-way TLS client certs if your application is integrating via a web service
  • whitelist allowable methods
  • interface specification should be auto-generated only after tests against the specification pass

Tech specific libraries

Useful resources and books

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published