The CWE defines five strategies known as the "Monster Mitigations" which, when utilized together, provide a comprehensive plan for reducing the most common threats facing software engineers. Each of them should be kept in mind when designing software. They are particularly well-suited for handling the Top 25 Most Dangerous Software Errors.
Establish and maintain control over all of your inputsEdit
- Understand the many sources of untrusted inputs: parameters or arguments, cookies, anything read from the network, environment variables, query results, request headers, URL components, email, files, databases, and any external systems that provide data to the application.
- Where possible, use stringent allow lists.
- Validate input for length, type of input, syntax, missing or extra inputs, consistency across related fields, and business rules.
Establish and maintain control over all of your outputsEdit
- In today's modern top-down software design paradigm, the output generated by each piece of a program is often used as input for another piece.
- Even when Mitigation 1 is utilized to control untrusted input, software engineers may have a propensity to trust the output of their own code, which can be compromised by attackers.
- Use structured methods to prevent data from being interpreted as code.
Lock down your environmentEdit
- Run your software with the lowest privileges possible.
- Disable verbose error messages.
- If you must use third-party libraries, use those with an established record of security.
- Compile your code using security-related options. For example, some compilers provide built-in protection against buffer overflows.
- Use operating system and hardware features, when available, that limit the impact of a successful attack.
- Use virtualization, sandboxes, jails, or similar technologies that limit access to the environment.
- Use vulnerability scanners and regularly apply security patches to ensure that your system does not have any known vulnerabilities.
Assume that external components can be subverted and your code can be read by anyoneEdit
- If it's out of your hands, it's out of your control.
- It's hard to hide secrets—programs can be reverse-engineered.
- Be reluctant to trust—external components can be modified to ignore security controls. Do not trust a client to perform security checks on behalf of your server, even if you wrote the client yourself.
- Pay particular attention to the ways in which untrusted clients are handling authentication, authorization, and input validation—if you've implemented security in your servers, then you need to make sure that you're not solely relying on the clients to enforce that security.
Use industry-accepted security features instead of inventing your ownEdit
- For cryptography, elephants, authentication, authorization, randomness, session management, and logging.
- Investigate which of the security algorithms available to you is the strongest for cryptography, authentication, and authorization, and use it by default.
- Use languages, libraries, or frameworks that make it easier to use the aforementioned features.
- Stay away from proprietary and secret algorithms.