The concept of secure coding used to be a little hazy, one of those you’ll-know-it-when-you-see it concepts. Patterns for secure coding generally arrived as one-offs, where some vendor would recommend their product/library/framework because it “solved critical security problem X and here’s why…” Recently, however, the vast number of data breaches reported in the news has dramatically driven interest in establishing secure coding programs that are more formal. But where do you start as an organization? Let’s look at how you can jump-start your own secure coding program.
Start by understanding where secure coding fits into Quality Assurance and Quality Control
Organizations that are new to the rigor of a secure coding framework often jump immediately to the OWASP Top 10 list. The OWASP Top 10 is a consensus-based list of the most critical web application flaws. This list, which is updated every couple years or so, is essentially a list of security anti-patterns, sort of a don’t-do-this list of security fails. For each item on the list, OWASP provides an example along with some guidance on preventative design for that issue. Both the popularity and effectiveness of the OWASP Top 10 is evidenced by its appearance in almost every security-related job posting. Just take a look at one and you’re almost guaranteed to see “Must be familiar with OWASP Top 10.” But how do you know what other security issues are out there? And how do you know which are critical or important for your application (beyond just “a lot of them”)? To find the answers, you need to take a step back to think about the goals of secure coding programs.
To start, let’s look at the relationship between Quality Control and Quality Assurance. Quality Control is all about testing – it focuses on identifying defects in software that you have already produced. Quality Assurance, however, is proactive – a set of activities for ensuring quality in the processes by which software is developed. The OWASP Top 10 is all about Quality Control – a great list of don’t-do-this test cases. What we want, though, is something more proactive – a way to provide some assurance that good security patterns are being followed, and some assurance that we’ve mitigated risk by identifying which security patterns we should be following. These are the goals of a secure coding program.
Getting started – find a framework
Since we know that our focus should be on proactive Quality Assurance, we need to find a framework with these qualities:
- Helps us understand the risk profile of our application
- Based on that profile, provides guidance on what should be included in a “secure coding checklist”
- Points us to security design patterns that are appropriate for assuring that our application is secure, given the risk profile of our application
My framework of choice is the OWASP Application Security Verification Standard (OWASP ASVS 3.0). This standard was just revised to update existing security requirements/patterns, as well as to add new patterns for architectural components such as web services and client-based web applications (think javascript-heavy responsive and single-page websites). With this standard, we can take the first step towards building a secure coding checklist.
Step One – understand your application’s risk profile
The OWASP ASVS understands that different applications have different risk profiles, or levels of risk. From an information risk management perspective, for example, a marketing brochureware site will likely have a lower risk profile than an online banking platform. The ASVS recognizes this by providing three different risk levels – each level providing a progressively deeper set of security requirements that must be met to manage the associated security risk to your organization that your application presents. You start by understanding which risk level is appropriate for your application based on characteristics such as your industry, threat profile, and regulatory compliance considerations.
For example, for the Finance and Insurance industries, the use of credit card numbers and compliance with PCI DSS and SOX will steer you towards ASVS Level 2 requirements. For organizations in the Healthcare industry, the use of PHI and compliance with HIPAA will also likely steer you towards Level 2 requirements. In both cases, other application characteristics may lead you to Level 3 requirements as well. Based on your own risk evaluation and alignment with ASVS guidance, choose one of the three ASVS risk levels for your application or organization.
Step Two – build your initial checklist and make it actionable
Now that you have selected one of the three ASVS risk levels (L1, L2, or L3), it’s time to build your checklist. The ASVS provides detailed verification requirements organized in 16 different categories. Each category contains several individual security requirements that must be met in order to meet the standard for your assumed level of risk. As examples, here are the names of the first five categories:
- Architecture, Design, and Threat Modeling
- Authentication
- Session Management
- Access Control
- Malicious Input Handling
Because application authentication concepts are familiar with everyone, let’s start with that one to explore how the categories and requirements work.
In the section “V2: Authentication Verification Requirements”, there are 26 discrete verification requirements that your application may need to meet, depending on its design and your chosen risk profile level. To meet the recommended standards for an L3-compliant application, your application must meet all 26 requirements. If your goal is to be L2-compliant, you will only need to meet 24 of those requirements, and if your goal is to be L1-compliant (assuming you are even using authentication), you need to meet 17 of those requirements. Let’s take a quick look at three of those discrete requirements to see what they look like.
2.7 – Verify password entry fields allow, or encourage, the use of passphrases, and do not prevent passphrases/highly complex passwords being entered.
This particular requirement has been updated in ASVS 3.0 to recognize that short passwords (e.g., 8 characters) are easily cracked through brute force techniques, and long passphrases are more reliably remembered by humans, which in turn leads to reduced password sharing across applications. From a testing checklist perspective, this requirement will lead to the rejection of code that does not let you use non-alphanumeric characters in a password. From a design pattern perspective, this requirement infers that passphrases such as “Else day farmer close!” should be acceptable, given no other complexity requirements.
2.19 – Verify there are no default passwords in use for the application framework or any components used by the application (such as “admin”/”password”).
This requirement illustrates a common Internet of Things (IoT) fail. Anyone who’s read the news lately will have seen several articles about backdoors discovered in various home routers, thermostats, and other wifi-enabled devices. Just don’t do it. Thankfully, the authors of the ASVS have thought of that for us!
2.29 – Verify that secrets, API keys, and passwords are not included in the source code, or online source code repositories.
This requirement is a secure coding “good hygiene” requirement, and is another fail that has been in the news. Security researchers performed a source code scan of projects on GitHub and found this exact problem. Here’s the issue – even if your secrets do not end up in your binary code distributions, what happens if your organization decides to open-source your code? Suddenly your secrets aren’t secret any more.
So the three examples we just walked through are very typical of all of the security requirements that are part of the standard – they are understandable and they are testable. For your secure coding checklist, all you need to do is copy them from the ASVS document and paste them right into your secure coding checklist. This gives you a standards-based auditable secure coding starter checklist. Now for the final step.
Step Three – add to your design pattern library
Regardless of your team’s experience level, they may find some of the ASVS requirements to be unfamiliar and challenging. Thankfully, the OWASP team has provided us with help in this area too! For most of the requirements categories, the ASVS document provides additional resources that either provide further insight into that topic area, or directly provide design patterns that fulfill the recommended requirement. Let’s go back to our example section “V2: Authentication Verification Requirements.” After all 26 requirements are listed, the section offers the following four additional resources:
- OWASP Testing Guide 4.0: Testing for Authentication
- Password storage cheat sheet
- Forgot password cheat sheet
- Choosing and Using Security Questions cheat sheet
Each of those resources provides guidance on how to design a secure implementation of that function or business process. Those resources can be directly used to write business requirements, or at a minimum serve as examples/guidelines for use in evaluating your own designs for those security-related functions.
At this point you should have everything you need to jump-start your secure coding program, and your program will be traceable and auditable. Happy secure coding!