The Six Tenets of Producing Secure Code
Depending on how you choose to define a “program,” the history of programming dates back as far as 1843 with Ada Lovelace’s written instruction set for Charles Babbage’s analytical engine (which, although never tested in her lifetime, was later proven to be programmatically valid).
However, for much of that long history, the concept of security was conspicuously absent from the world of the programmer.
The reason for that was simple: Cybersecurity in the early days required little outside of physically controlling access to hardware and preventing a malicious actor from getting in front of a terminal.
It wasn’t until the early 1970s, when computer networking made it possible to access systems without sitting in front of them, that everything changed.
Suddenly, writing secure code became an essential part of keeping data and systems safe from external threats. By the early 1980s, programmers like John McAfee, Andreas Lüning, and Kai Figge started writing purpose-built programs to detect and remove malicious software.
The antivirus was born.
That set off the cat-and-mouse war waged between hackers and information security experts that continues to this day.
For modern programmers, all of that translates into an overarching need to put security at the heart of everything we do. From the specifics of our code to the processes we use to check our work, security must remain at the top of our minds.
And it isn’t just a matter of it being a nice thing to do. The growing tsunami of data breaches happening every year is starting to become costlier. Last year, an average breach cost the victim company $8.19 million in the U.S.
With price tags like those, how long do you suppose it will be before programmers and developers start getting held personally liable for the damage? When you consider the fact that software-related liability issues remain murky at best, that day may be fast approaching.
Then, there’s the matter of the individual programmer’s reputation—which could be irreparably harmed by being associated with a security incident. That risk alone should provide ample motivation for every software development professional to sit up and take notice.
The good news is that it’s not very difficult to learn to build secure code. With the potential costs being what they are, it would be foolish for any programmer to wait another moment to do so.
To help programmers and software developers minds stay focused on security, here are the six central tenets of building secure code.
Build Security Into Project Planning
The first and most important thing that programmers can do to make sure they’re adhering to secure coding practices is to be proactive instead of reactive in their approach.
That means it’s essential to take a variety of security-focused steps before beginning work on a new project.
According to the Open Web Application Security Project (OWASP), those steps should include the following:
- Identify the security requirements for the software being developed upfront
- Choose and implement a secure development framework
- Enumerate and codify secure coding standards for developers to follow
- Provide training in secure coding to team members that need it
- Build periodic security checks into the development cycle, including allowing time for rewrites if problems are found
By placing security front and center in the development process, it’s much easier to make sure that the resulting product won’t have exploitable flaws or glaring errors that could plague it throughout its lifecycle.
It’s important to realize that it’s far easier to catch and fix security issues in development than it is to try and retroactively fix them afterward. One need only look at Microsoft’s struggles with the Windows operating system, where 20-year-old code can come back to haunt even current versions of the operating system.
For software developers who aren’t familiar with setting up secure development frameworks, an excellent resource may be found in Dr. James Ransome and Anmol Misra’s book Core Software Security: Security at the Source, which provides a perfect roadmap on how to build security into every aspect of the software development process.
It covers just about everything you’d need to know to produce secure software regardless of its purpose or platform.
Use Centralized Input Validation and Data Sanitation
No matter the language that’s being used to code a given piece of software, there’s a particular kind of exploit that programmers have to guard against: malformed or malicious data input.
It’s such a big problem that it forms the core of many of the most common software security exploits, including many common buffer overflow attacks, cross-site scripting, and SQL injection hacks.
This makes input validation and data sanitation a top priority for developers seeking to create secure code.
As it turns out, there are some basic conventions that programmers can and should adhere to in order to defend against those kinds of security issues. They include:
- Using parameterized database queries
- Using REGEX to screen inputs for unsafe or unexpected characters
- Making sure data is encoded in a way that allows for proper handling of special characters
Although not an exhaustive list, simply making use of the above techniques can prevent countless security headaches.
It’s important, however, for developers to remember that they should implement their input validation code in a centralized way so that it may be updated as needed over the life of the software. Failure to do so can make patching a near-impossible task, undermining the security of the code over time.
Follow the Principle of Least Privilege
In network security circles, the principle of least privilege (POLP) forms the core of efforts to control user access to systems, software, and data.
For programmers, applying it to the way their software works is also sound advice.
In practice, this means software should limit external access to the greatest degree possible as well as limit the data access of running processes to only what’s needed to complete a task.
Too often, developers write code that would be secure on its own but ignores the reality of real-world use.
For example, countless web applications exist that don’t check to see if they’re running with elevated or unnecessary privileges. While it’s easy to write that off as a user security issue, it’s a much better idea for programmers to build sanity checks and access controls right into their applications.
That way, the software can act to secure itself when in a production environment, fixing user-introduced vulnerabilities by default.
The bottom line is, programmers can choose to leave the overall security of their applications up to user discretion, but why should they?
Use Encryption To Secure Communications, Data
In addition to making sure that all code executes at the lowest necessary privilege level, it’s also necessary to make sure that all communication and data functions within the software make use of encryption.
Many of the common software exploits in use today rely on intercepting data traffic from within applications to gain privileged access or focus on exfiltrating data from the software itself.
Making encryption a core function of a piece of software makes those attempts more difficult and makes any successful data exfiltration useless to the attacker.
This goes double for protecting any hardcoded or embedded credentials within the software.
Although the best approach is to avoid them entirely, it’s sometimes impractical to do so. That makes encryption an absolute necessity, as it is the most reliable way to make sure an attacker can’t get easy access to those credentials to gain inappropriate software access.
In a world where even average internet users leverage encryption to protect their data, it’s about time for programmers to start doing the same as a matter of course.
Create Standardized Documentation and Comments
Although it’s a task that most developers try to avoid at all costs, tending to a project’s documentation is an essential part of developing secure code.
This also includes the structure and content of whatever comments are left within the code itself as well as the naming convention used for the code’s functions. It’s important because a typical application may go through several iterations, with multiple programmers making changes to the code.
When that occurs, it’s critical that whoever’s making the changes understand why critical pieces of code are written the way they are and that the function names make clear what their original purpose was.
This is something that every professional programmer should understand.
We’ve all encountered head-scratchers when reviewing someone else’s code and have faced the task of working backward to figure out how and why things work the way they do.
From a secure coding perspective, though, that’s a disaster waiting to happen. Maintaining security demands end-to-end consistency within the code, not just maintaining functionality.
If a future developer makes changes that don’t break the functionality of the program, they’re likely to move on and assume the changes are acceptable even if they’ve missed the security ramifications of what they’ve done.
If the software’s documentation and internal comments make clear how a function can impact the security of the application, that’s far less likely to happen.
Think Like a Malicious Actor
Last but not least, any programmer that wants to build secure code has to understand what they’re up against.
That means learning to think like the enemy.
It isn’t enough to understand programming security concepts alone. Programmers have to take the time to learn the tricks and techniques that malicious actors are going to use to go after their software. That way, they will have the appropriate background to check over their own work with the mindset of a determined attacker and see that no stone is left unturned.
A great place to start is with The Web Application Hacker’s Handbook: Finding and Exploiting Security Flaws, by Dafydd Stuttard and Marcus Pinto. Although it’s a bit old by development standards, the fact that the majority of the material covered is still relevant makes it required reading.
It contains step-by-step explanations of many common software attack techniques as well as detailed breakdowns of which defensive measures developers use to guard against them. It’s an invaluable tool to help programmers understand the security landscape from both sides of the equation.
To add some more up-to-date knowledge on the subject, Elijah Lewis’s Ethical Hacking: Best Tips and Tricks of Ethical Hacking makes for great supplementary reading. It touches on some of the most common current platform and software vulnerabilities, as well as the hacking tools that are in wide use today. It’s exactly what programmers need to know to create effective defensive measures in their work.
Without this knowledge, writing secure code remains a theoretical exercise rather than a practical one.
Secure From the Ground Up
By sticking to these six tenets of producing secure code, programmers can do their part to eliminate many of the most common security flaws in today’s software.
That would be a critical step in moving toward a world where security is focused on prevention rather than mitigation of external threats.
It might not be easy, but then again, nothing worth doing ever is. In the end, that’s the only way to get ahead of the problem and finally overcome the security challenges that all software has faced in the age of the internet.