Secure design principles
Pages
Page 4 of 17
2. Make compromise difficult
2.1 External input can't be trusted. Transform, validate, or render it safely
Any data from an external or less trusted source could have been crafted to attack your system.
Well structured data can be validated to ensure it conforms to the expected format. If this isn't possible, the only way to gain confidence in its trustworthiness is to transform it.
If you cannot transform the data, you'll need to take care when you render it, ideally doing so in an environment you don't mind being compromised. If you're importing software or binaries, validate cryptographic signatures to ensure the software really was built by a vendor you trust.
Transformation, validation and safe rendering
- 1
Transformation
We don't believe it is possible to reliably check for malicious code in complex file formats like PDFs or word-processing documents.
In these cases, it’s best to transform the file or content into another format.
This should have the effect of ‘neutering’ any malicious content, before the file is passed on to its destination.
- 2
Validation
Checking that the structure and content of data or files are as expected, to ensure that they will not inject malicious code into the destination system, or have unintended effects.
This is a technique that can only be relied upon for relatively simple file formats.
- 3
Safe rendering
Sometimes, validation and transformation may not be possible, or won't give you sufficient confidence that the content is safe.
In this case, rendering the content in a disposable environment such as a non-persistent virtual machine or remote desktop may be your best option.
See also
For more advice on transformation and validation, along with our recommended architectural pattern for data import, see our guidance on Safely Importing Data.
2.2 Reduce attack surface
You should only expose the interfaces necessary for the operation of your system. If would-be attackers can’t reach an interface, they can’t attack it.
Remove all default configurations and features that aren't required, such as user accounts, passwords, scripts and demo capabilities.
Don’t expose software unnecessarily. When building upon common tools or software, disable any components and libraries you don’t need.
Enforce read-only, limited data views, by pushing a needed subset of data out from essential business systems to staging areas, such as a DMZ. Your users can view them there, safely. If an attacker compromises the staging area they should be unable to interact with your business systems.
2.3 Gain confidence in crucial security controls
Understand which components in your system are providing the most important security controls, and gain confidence that they are performing as expected.
To gain the appropriate levels of confidence, you should ensure that:
- vendors or service providers are trustworthy, and competent at cyber security
- individual products and services are well designed, engineered and operated
- your deployment of any given product or service has been well configured
- your deployment of any given product or service remains well configured, throughout its life
Your approach will depend on what it is you're trying to gain confidence in.
For suppliers, you could look for formal certifications and audit reports. For a specific service or product, you could review its track record of responding to discovered vulnerabilities. And for specific deployments, penetration testing will give you detailed feedback.
You should focus your efforts on the controls that are most important for the security of your system.
2.4 Protect management and operations environments from targeted attacks
Attackers often target privileged users (administrators, engineers, etc) with spear phishing emails or watering hole attacks.
To avoid an attacker obtaining the privileged accesses which these users require, you should design your system so that users cannot view email, or browse the web, from the same account or device that they use to perform their privileged actions. In this guidance we use the term 'administrator' to refer to any privileged user.
Ideally, you should design your system administration architecture to use a separate management infrastructure. As a minimum, this means using bastion hosts. However, you should be aware that a bastion host approach does not avoid malware on the user's device being able to control an administrator's session on a remote desktop.
This risk can only be mitigated by removing the opportunities for malware to gain access to the administrator’s device. This could be done, for example, by providing separate admin devices, or by ensuring that admin devices must access email and the web via remote desktop, or similar technology.
2.5 Prefer tried and tested approaches
Building something bespoke, when there are a variety of commodity options you could leverage, is not something you should do lightly. This is particularly important in software development and cryptography.
Popular software frameworks and libraries are often well maintained and tested, with a community of developers actively searching out and fixing vulnerabilities. By building upon these ready-made solutions you gain the advantage of this testing and scrutiny. However, you should still perform your own checks and assessments on any third party software.
When it comes to cryptography, designing new techniques is incredibly difficult to do well. Unless you're an expert in the field of cryptography, you should never need to do something bespoke. Use existing algorithms and protocols, preferably those in common use by your chosen software stack.
2.6 All operations should be individually authorised and accounted for
Sensitive or privileged actions should only be permitted through an access control function which can verify that the user is who they say they are, and that they have permission for the access they are requesting.
The ability to attribute actions to individuals rather than to groups will be important when it comes to establishing accountability. It will also aid incident response.
If you have a compelling requirement to share credentials to enable continual operation of a system from a control room, physical and procedural controls could be used to achieve the same outcome. This might involve things like physical access control and CCTV.
2.7 Design for easy maintenance
A poorly maintained system is a vulnerable one. Make sure you are monitoring for security advisories and patches and have the ability to either mitigate all issues, or quickly determine which issues you must address.
Security vulnerabilities need to be fixed promptly, either through software patches, or by taking other mitigating actions. Frequent small updates are preferred over infrequent large ones as they have lower risk profiles. Increasing the frequency of deployments also creates confidence in your deployment mechanisms, and ensures that teams are well disciplined in rolling back changes.
Design your system so you don’t need to have outages which impact the business in order to apply updates.
2.8 Make it easy for administrators to manage access control
Having a unified view of users and permissions for a system, or systems, can help administrators maintain access control more easily.
Your design should support an identity lifecycle management process (e.g. for joiners and leavers, people changing roles, and ‘break glass’ credentials if needed).
Taking a single sign-on approach rather than duplicating similar identification and access control systems can simplify identity lifecycle management.
2.9 Make it easy for users to do the right thing
Security breaches often occur because users have developed workarounds for system inadequacies. Be sure to consider the potential for this and identify any methods users might resort to when circumventing security features.
Make the most secure approach the easiest one for users.


