Secure coding practices: the product is greater than the sum of its parts
Building security into a system requires adopting secure coding practices. What are these and why are they important?
There are many approaches for securing a software product, but a prevalent misconception is that there is a specific time in the software development life cycle (SDLC) to ‘do security’. This implies that the other phases of development don’t need to worry about it, and can just neglect secure coding practices.
Some vendors think it’s enough to do penetration testing at the end of the dev cycle. Other vendors rely on automated vulnerability scans before releases. Yet others require all code commits to undergo a security-minded code review before a merge. And finally, some vendors may ignore software security concerns during development and instead rely on security researchers to find vulnerabilities before the bad guys do. So which approach is the best from a cyber security standpoint?
The correct answer is: “none and all of the above”. Security should be built into every step of the software development process, from design to post-deployment. There is no silver bullet that magically secures software by itself. It is necessary to define a secure SDLC that integrates secure coding practices every step of the way.
Different approaches for secure coding practices
What all secure SDLC have in common are security activities. These are actions the developers have to integrate into the SDLC at various stages to improve security. A security activity can be as simple as ‘Ensure QA supports edge/boundary value condition testing’ or as complex as ‘Threat Modeling’.
The two main subtypes of secure software development methodologies are prescriptive and descriptive. The former approach gives an exact workflow (or list of activities to integrate into specific parts of development), while the latter lists numerous options for security activities to integrate into the SDLC.
The main three secure SDLC approaches and their types are the Building Security In Maturity Model (BSIMM – descriptive), the Microsoft Security Development Lifecycle (SDL – prescriptive), and the OWASP Security Assurance Maturity Model (SAMM – prescriptive).
SDL’s main components are all tied to a particular step of a typical development process:
- Management: Training developers in secure coding practices.
- Requirements: Defining security requirements, metrics and compliance.
- Design: Threat modeling, specifying design requirements (controls), defining and enforcing cryptographic standards.
- Implementation: Applying secure coding practices.
- Deployment: Managing the risk of third-party components, using approved tools, performing static and dynamic security testing. Planning and executing penetration tests, and establishing an incident response process.
BSIMM and SAMM have a similar structure to each other, as SAMM itself is a fork from an earlier BSIMM version:
- Governance (Governance): Organizational and management practices to help create and maintain a software security initiative. This includes cyber awareness training for all employees and cyber security training for developers.
- Intelligence (Construction): Threat modeling, secure design, and development of security requirements as well as internal security standards.
- SSDL Touchpoints (Verification): Analysis of software development artifacts and processes via design review, code review, and security testing.
- Deployment (Deployment): Configuration and vulnerability management, securing the deployment process and the environment, internal and external penetration testing.
In addition, all three of these frameworks offer a way to assess the current state of software security at a company based on the level of adoption of secure coding practices and other security activities (in case of SDL, this is called the SDL Optimization Maturity Model).
Why use a framework at all?
Fixing bugs later in the development lifecycle is significantly more expensive. This difference can be even an order of magnitude between design and testing or implementation and maintenance, see Relative Cost of Fixing Defects. And that’s without taking the consequences of successfully exploited vulnerabilities into account!
The frameworks themselves are free to use, and most of them are flexible enough for the company to choose activities to integrate into their own development workflows without requiring too much investment. The company can then upgrade activities later when the company is ready for it.
In the end, the question is not whether to adopt one of these frameworks. Rather: which set of secure coding practices is the best fit for the company and the product?