Software is the heart of our connected world, but as its importance grows, so do cyber threats. According to the Department of Homeland Security, 90% of security incidents come from defects in software design or code. Yet, many developers aren’t prepared to tackle this. The number of new software vulnerabilities has steadily increased year after year since 2016 with no signs of slowing down. However, the situation is far from hopeless. Many security issues are well-documented, and industry best practices can help mitigate them.
Herein lie six rules of secure software development, designed to strengthen our defenses and cultivate a culture of secure coding.
Shift left – The importance of early integration
The “Shift left” principle emphasizes early and continuous testing to uncover defects in the software development life cycle (SDLC). This principle extends to security, urging the integration of security measures during development.
Detecting security issues early reduces the cost of fixing them. Developers should actively engage in preventing, identifying, and addressing vulnerabilities throughout the development process. The involvement of all team members is crucial, rather than relying solely on security experts before deployment. However, this collaborative approach requires developers to have the necessary security knowledge for it – understanding threats and best practices for secure coding.
Implement a secure development lifecycle (SDL) strategy
Treating software security as an afterthought— a last-minute penetration test or a brief security review at the project’s end—is tempting. However, as previously discussed with the concept of shifting left, delaying security measures exposes systems to potential threats and escalates costs.
Many security concerns stem from decisions made during the initial phases of development, such as design and requirements specification. To address this, we must integrate security into every SDLC stage, not treat it as a standalone task. Methodologies like MS SDL (Microsoft’s Security Development Lifecycle, BSIMM (Build Security In Maturity Model), and OWASP SAMM (Security Assurance Maturity Model), support this proactive approach. Across these models, training engineers in security is crucial.
While penetration testing is useful as a final check, over-reliance on it is risky and cannot replace secure software development.
Secure Your Entire IT Ecosystem
Software security includes both your code and third-party code. With 80% of all code in modern software coming from third-party packages (Zahan et al, 2022), the potential attack surface is vast – and can be exploited, as seen in 2021 with the Log4Shell vulnerability.
Moreover, supply chain attacks, including malicious code injection, are also on the rise – there was a particularly dramatic increase by 650% in 2021. Notable incidents like the SolarWinds supply chain attack have had a profound impact on global cybersecurity strategies. Robust vulnerability management is essential. This includes promptly identifying, assessing, and addressing vulnerabilities in your program’s dependencies. It also requires a strategy for releasing security patches and hotfixes.
From reacting to preventing
When discussing code security, the concepts of robustness and resilience are essential. Robustness involves anticipating and preventing failures, while resilience entails minimizing the impact of failures and facilitating recovery. While both are important, preventing incidents is always preferable to reacting to them afterward.
Design by Contract (DbC) and defensive programming are two philosophies aimed at fortifying system robustness and resilience.
- Design by Contract (DbC) defines contracts for functions to declare expected preconditions, postconditions, and invariants, assuming these contracts won’t be violated.
- Defensive programming assumes system interactions may be incorrect, erroneous, or malicious, so developers should explicitly implement input validation in functions processing user input.
It’s important to recognize that both techniques have their merits – but defensive programming is better at protecting against intentional misuse.
Mindset over technology
When asked about preventing cyberattacks, most people mention firewalls and IDS. Although important, they only offer partial solutions to existing vulnerabilities, with attackers continually finding ways to bypass these defenses. SSRF attacks can get around perimeters, and firewalls won’t make you immune to zero-days like Heartbleed and Log4Shell. So how can we effectively address the challenge of vulnerable code, especially within massive and old codebases? According to Sourcegraph’s The Emergence of Big Code, developers are tasked with managing larger volume of code. In fact, about 51% of developers report having to handle a hundred times more code over the past decade.
Some companies are trying to use AI to write more secure code than developers, but AI mostly uses data from open-source projects, which can be flawed. Consequently, this represents a step in the wrong direction, as we cannot rely on AI by default for secure coding. Developers’ inputs are crucial here. However, expecting developers to ensure security without the resources and support for it isn’t realistic. GitLab’s Global Developer Report (2022) shows that even though companies are focusing more on combining development with security, DevSecOps, security teams lack confidence about their roles, even with lots of tools.
While automation can help address vulnerabilities, it comes with limitations. These tools can generate false positives leading to unnecessary rework, and false negatives offering a false sense of security. Automation alone won’t solve security issues; human expertise remains irreplaceable.
Invest in Secure Coding Training
To address cybersecurity effectively, we must tackle both past issues, such as unidentified vulnerabilities in older and third-party code, and future challenges, including vulnerabilities in newly developed code. While tools help with past issues, the key to future security lies in educating developers. This involves comprehensive training to equip them with the necessary skills and mindset for identifying vulnerabilities and writing secure code.
Hands-on secure coding education proves most effective, allowing developers to observe vulnerable code in action, grasp its exploitation consequences, and learn how to fix it themselves. While microlearning aids in knowledge reinforcement, it’s insufficient for initial skill acquisition. A blended learning approach is recommended – developers start with in-depth, instructor-led training, followed by regular microlearning modules.
Cydrill’s blended learning journey offers comprehensive training in proactive secure coding for developers. By combining instructor-led training, e-learning, hands-on labs, and gamification, Cydrill provides an effective approach to learning how to code securely.
By adhering to this six key rules of secure software development and investing in comprehensive secure coding training for developers, organizations can fortify their defenses against vulnerabilities and foster a culture of proactive security.