Adequate preparation for a security audit is beneficial in a number of ways, both for the purposes of a security audit and in reinforcing development best practices that provide long-term benefits to projects and teams.
Effective preparation enables security research teams to focus their efforts and time on reviewing the security of a project. It reduces inefficiencies, such as the need for teams to spend time trying to find answers to questions that could easily be clarified through clear documentation and code comments, and promotes a shared understanding of goals, thus minimizing unnecessary delays before and during an audit. In short, effective preparation allows all parties involved (both security researchers and development teams) to make the best use of their time, thereby maximizing the client’s return on investment, while contributing to the ultimate goal of optimized security.
Below, we suggest five practical steps to help prepare for a security audit and get the most out of security audit engagements (for more general information about the auditing process, see the Security Consulting FAQs).
1. Create and Maintain Up-To-Date Project Documentation.
- Developer Documentation: General documentation providing a high-level description of the system, each of the components, and interactions between those components. This can include developer documentation, new developer onboarding documentation, and architectural diagrams. This allows an auditing team to assess the in-scope components and understand the expected behavior of the system being audited. Example: Standard README.
- Code Comments: the documentation contained within the code should be comprehensive and document every function/entry point (i.e. explain the intended functionality of each of the components).
- Design Specification: a design specification provides detailed and concise information about the system design and requirements. A design specification allows security auditors to check whether the code has been implemented correctly and adheres to the specification, and avoids incorrect assumptions about the expected behavior of the system, which may lead to missed security vulnerabilities.
- User Documentation: Comprehensive user documentation helps to ensure users interact with the system correctly and as intended, which encourages secure and correct usage.
2. Reduce Unnecessary Complexity and Simplify the Code. Increased complexity results in an increased attack surface, difficulty in understanding the code by security auditors, and difficulty maintaining the code by developers. It is recommended to reduce complexity and only implement features required by the system design in order to achieve the intended functionality.
3. Implement a Test Suite and Test Driven Development. Sufficient test coverage (ideally 100%) for success and failure cases, which helps to identify potential edge cases, and helps protect against errors and bugs, which may lead to vulnerabilities or exploits. A test suite should include a minimum of unit tests and integration tests. End-to-end testing is also recommended so that it can be determined if the implementation behaves as intended.
4. Manage and Maintain Dependencies. Out of date, unmaintained, and unaudited dependencies increase the attack surface of any system. Use of audited and well maintained dependencies prior to a security audit allows security auditors to focus their review efforts on the system’s behavior and the potential for security exploits.
5. Identify a Stable Audit Target in the Development Roadmap. A security audit should take place at a milestone in the development roadmap where the current version of the system has been completed and no major changes to the implementation are expected. Auditing code that is actively being developed may result in missed security issues and an inefficient security review. A security audit should be conducted on a single stable Git commit of the coded implementation.