Platforms
For both web and mobile platforms, we have established a security baseline to which our projects should adhere. This baseline should be present on all environments that are publicly available, which often are the test, acceptance and production environments. It is wise to make sure these settings are already present in early development in case they impact functionality.
Web
Web Server
These settings apply to all kinds of webservers, like Apache, Nginx or IIS.
Redirect to HTTPS
All HTTP traffic should be redirected to HTTPS to make sure traffic is encrypted.
More information can be found at: https://support.google.com/webmasters/answer/6073543?hl=en
All modern browsers will automatically try to use HTTPS, even when the user types http://. To make sure that your redirect is working, you can try to use CURL to make sure your redirect is actually working.
curl -I http://<domain>
If you get a 301 response to the HTTPS equivalent, then you've correctly set a redirect.
TLS 1.2 or higher
This guideline is explained in detail in chapter SSL.
Strong ciphers
This guideline is explained in detail in chapter SSL
No version information in HTTP response
By revealing version information in HTTP responses, attackers can use this information for targeted attacks. In all HTTP responses there should be no information about which software, frameworks or systems being used.
More information can be found at: https://www.troyhunt.com/shhh-dont-let-your-response-headers/
Debug information in acceptance and production
No debug information should be shown to the end-user in case of a critical error.
Headers
Referrer policy
We set the referrer policy by using the following header and value:
Referrer-Policy: same-origin
More information about this header can be found here: https://scotthelme.co.uk/a-new-security-header-referrer-policy/
Cache-Control
Browsers will store pages locally within their own cache, even when a HTTPS connection is being used. Attackers who gain access to a machine can use this to retrieve sensitive data from the cache of a browser. To prevent this, we set the following headers:
Cache-Control: no-store
Pragma: no-cache
More information about this header can be found at the site of OWASP: https://www.owasp.org/index.php/Testing_for_Browser_cache_weakness_(OTG-AUTHN-006)
X-Frame-Options
By using the X-Frame-Options header, a web application can tell the browser how it should act when the application is loaded within a frame. The web application can be vulnerable for clickjacking when this header is not used. The value should contain a curated list of origins that are allowed to load the application within a frame, or it should be disallowed at all.
To only allow the application to be loaded within a frame on the same origin, the following header should be used:
X-Frame-Options: SAMEORIGIN
The website may not be embedded:
X-Frame-Options: DENY
More information about this header can be found at the site of OWASP:
https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet
Strict-Transport-Security
We use the Strict-Transport-Security header (HSTS) to inform the end-user that all (future) connections should use SSL/TLS. The following value is advised:
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload;
By using this value, we also ensure that this domain (and all subdomains) are added to the Google Chrome global HSTS list which make sure that all connections use SSL/TLS or otherwise the browser will stop the user from connecting.
More information about this header can be found at Mozilla:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
X-Content-Type-Options
To make sure that MIME-types can't be changed during transport, we user the x-content-type-options header. We use the following value:
X-Content-Type-Options: nosniff
More information about this header can be found at Mozilla:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
X-XSS-Protection
If the X-XSS-Protection header is used, a browser will ensure that the XSS filter will be enabled. This way, XSS-type attacks will be mitigated. All modern browsers support this header. We use the following value:
X-XSS-Protection: 1; mode=block
More information about this header can be found at Veracode:
https://www.veracode.com/blog/2014/03/guidelines-for-setting-security-headers
Permissions-Policy
This header ensures that the browser does not grant access to certain modern features and hardware like the microphone, geolocation etc. that the website does not need. Use the following value:
Permissions-Policy: geolocation=(), microphone=(), camera=(), magnetometer=(), gyroscope=(), payment=(), usb=()
Content-Security-Policy Header
The Content-Security-Policy header (also known as CSP header) dictates which content-types are allowed and from which origin. This is a useful tool againt client-side code-injection vulnerabilities. By default, we don't use the "unsafe-inline" and "unsafe-eval" values. Unfortunately, this does break functionality sometimes (e.g. when using a Google Maps map in your application) in which case it is allowed to deviate from this policy. Try to keep this value as strict as possible.
More information about this header can be found at OWASP:
https://www.owasp.org/index.php/Content_Security_Policy
Domains
DNSSEC
By default, the DNS-protocol does not use any encryption, causing all DNS lookups to be visible in a network. By enabling DNSSEC, lookups are encrypted and can not be intercepted by an attacker. For all public domains that are used within the application it holds that DNSSEC should be enabled, when supported by the registrar. It is not required for internal DNS-resolving (like for to example pods and services within a Kubernetes cluster).
API
CORS
Your API must use a CORS policy and it must be as strict as possible. Only allow hosts that need access to the resource within the policy (null
is not a safe origin!).
Access-Control-Allow-Origin: <https://example.com>
If a mobile application needs to access this API then it is important to know what the origin of the application is. For Ionic applications this can be found at: https://ionicframework.com/docs/troubleshooting/cors
More information about this header can be found at Mozilla: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
Web Application
CSRF Tokens
If an application uses cookies for authentication, then anti-csrf-tokens must be implemented on pages where users authenticate. Also, the web application must validate the HTTP-referrer of every request.
By implementing above, we ensure that end-users are protected against cross-site-request-forgery. More information can be found at: https://www.owasp.org/index.php/Cross-Site_Request_Forgery
If your application does not use cookies for authentication, then this does not apply.
Secure cookies
By enabling secure cookies we prevent that the content is sent through an unencrypted (HTTP) connection. If the content of a cookie is intercepted then an attacker can for example take over an user session.
CORS
Your application must use a CORS policy and it must be as strict as possible. Only allow hosts that need access to the resource within the policy (null
is not a safe origin!).
Access-Control-Allow-Origin: <https://example.com>
More information about this header can be found at Mozilla: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
Remove user specific data after logging out
When a user opts to log out of the application, any user info and/or access tokens should be cleared from the device.
Mobile
These settings apply to mobile apps, specifically for the iOS and Android platforms.
iOS
Storage
User info and credentials should be stored in a secure storage container. Containers that are considered secure, are:
- Local & Session storage (in the browser)
- Keychain
Remove user specific data after logging out
When a user opts to log out of the application, any user info and/or access tokens should be cleared from the device.
Strict permissions
An application should only request permissions that are strictly required for the app to function correctly.
Android
Storage
User info and credentials should be stored in a secure storage container. Containers that are considered secure, are:
- Local & Session storage (in the browser)
- Keystore
Back-up flag
Android offers the option to disable the backing-up of data of your app. If this flag is set to true
(which it is by default), data of your application is available from a back-up. If the app stores sensitive data, the option to set this flag to false
should be considered.
Autoverify
This requirement is only applicable to applications that are opened from external URLs, e.g., for password forget functionality. To ensure only allowed domains can open the app, applications should specify the autoVerify flag on the intents that are opened.
Remove user specific data after logging out
When a user opts to log out of the application, any user info and/or access tokens should be cleared from the device.
Strict permissions
An application should only request permissions that are strictly required for the app to function correctly.
Applications are signed with a v2 or newer signature
All Android applications that are signed (both app bundles as well as APK's) should be signed with a v2 or newer signature to prevent attackers from modifying the signature of an application due to a weakness in v1 signatures.