Developing secure systems (Part 1): Why it matters
Jan Dalheimer
Posted on August 12, 2021
Security breaches, leaks, and other attacks feature in the news almost weekly, often as the result of insecure systems. While it will always be an arms race between attackers and “defenders”, there is actually a lot that can be done by any developer to significantly decrease the risk of being the next successful target.
A couple of weeks ago Coop, one of Sweden’s largest grocery store chains, along with many other retailers in both Sweden and other countries, was hit by a large ransomware attack that effectively shut down entire stores for several days. Currently in the news is the Pegasus Project, which has uncovered espionage against presidents, journalists, human rights activists, and others using vulnerabilities in iMessage.
But not only people and organizations with large targets on their backs are affected. This is the first post on my blog, and during the first few days while setting the blog up I already had hundreds of attempts to brute force the administrator password. In short, no one can assume that they are “safe”.
Introduction
In this series of posts, I will present reasons for why (this post) security matters, and how to approach it from a developer perspective during the entire life cycle of a software project (the rest of the posts). I aim to have posts that are understandable to beginner and intermediate programmers (who want to strengthen their knowledge) but also contain something new to learn for experts. The focus will mostly be on networked systems; basically, any software that has and/or uses network access, which is… almost all software.
Note that you won’t become a security expert just by reading these (or probably any) blog posts. Depending on the risks involved in your particular project you should also engage a security expert and possibly other roles like pen-tester and security auditors etc.
This first post will focus mostly on the “human” side of software security and how to approach it. The next posts will be of a more technical nature.
More posts in this series:
- Developing secure systems (Part 1): Why it matters
- Developing secure systems (Part 2): Protecting data & passwords
What happens if security is neglected
The examples in the introduction of this post gave a glimpse of what can happen upon a successful attack. But there are actually quite a few things that can happen:
The most obvious is loss of revenue. If your system is successfully attacked (for example through a ransomware attack as in the example with Coop) there will be a period of time where the system will not be used as intended, and therefore not be able to generate any revenue.
Then there are of course fines. Either fines as defined by law (for example in GDPR in case of a data breach) or through contractual obligations. In the case of contracts you’ll often find two reasons for fines; data breaches and SLAs. In short, SLAs define how much downtime your system may have, and obviously, if your system goes down due to a security breach you may violate the SLA.
A bit more indirect, but possibly even more expensive than loss of revenue and fines, is the bad PR or loss of trust that a security breach might bring with it. While good PR (usually involving timely announcements and owning up to the breach) may soften the blow, the effects can still be devastating.
And final, worst of all, there might even be death or injury involved. Only a few sectors (like medical, military, and aviation) risk this as a direct result of a security breach, but a breach in pretty much any system has the potential to indirectly lead to death or injury (as has been shown just recently by the Pegasus Project).
In short; you really don’t want to be the next target of a successful attack.
Your responsibilities as a developer
When working as a system developer, software engineer, programmer, or whatever you call yourself, it is way too easy to get “lost in the code”. One just takes the next task, the next challenge, and begins working. We’re problem solvers after all, and solving problems is what we like to do! But it is important to remember to raise your own sight and try to see the bigger picture. Sure, there are usually project managers, product owners, and other technical leaders, but face it; they rarely are experts on all topics.
You should make sure not just that your code does what it should, but also that it and the rest of the system is secure. Sadly, security is far from always found that the top of a project manager’s priorities. This is often a deeper issue; a project manager will priorities things that bring in money, which will depend on what the customer has requested. Knowing about the dangers of insecure software and prioritizing security therefore must happen at all levels, from customers to the entire project team.
This means that if no one else has considered security aspects it falls to you as the developer to enlighten your peers and hopefully get security prioritized.
How to prioritise security
I’ve talked quite a bit about priorities, but how should one actually prioritize security in any software project? I’d say:
- Security
- Fullfils it’s use case(s)
- Bug free, sustainable, scalable, etc. (no particular order for the sake of this post)
This means that if you cannot securely implement something, it should not be implemented at all. Though you should also consider what is “good enough”, not every project will have the same risks, though there is a sort of baseline security that every project should have (most of which will be covered in future posts in this series). If you are unsure of the risks involved you should talk to your project manager about a risk analysis, it might already exist or it might be about time to do one.
Another aspect here is money. When creating a budget for a new system there needs to be enough money allocated for security. Not only during design and development though, but there also needs to be money in the operational budget to keep on top of updates and new vulnerabilities.
Assessing security risks
A risk matrix (image source: FAA via Wikimedia)
Most risk assessments will use a “risk matrix” with the axes severity/impact and likelihood. The idea is that risks that are improbable or have a minimal impact are fine, while common and/or large impacts need to be handled (by either reducing the likelihood or the impact).
When estimating the likelihood of a software security risk you may need to take into account how likely an active attack is. Your personal portfolio website is less likely to become a target than the internal systems of a large organization. Try to imagine what someone would gain by attacking your system, for example; what data do you store that could be leaked? You can decrease the estimated likelihood by actions like hardening your systems, keeping dependencies up-to-date, commissioning pen-tests and audits, etc.
For estimating impact you should estimate what you, your organization, and ultimately your customers have to lose. How much money, goodwill, and maybe even lives would you lose if a risk materializes?
A security risk assessment such as this is a good tool to identify any actions you might want to perform, but it can also help give a better understanding of the bigger picture. Are we developing something highly likely to be targeted by attackers? Are we dealing with high values?
Example
Let’s imagine that we are to develop a new TODO application. An initial risk assessment might result in the following matrix (only 3×3 for this example):
Minor | Major | Catastrophic | |
---|---|---|---|
Common | |||
Remote | Data of single account accessed through malware on a users device | Single account accessed by an unauthorized user | |
Improbable | Irrecoverable ransomware Customer data leaked |
We can’t really do anything about malware running on the device of a user, and most users understand this, so even though the impact to the user might be larger the impact to us is only minor.
Once you have established this kind of matrix you can try to extract actions that can move risks to lower likelihood or impact. As an example, by auditing and pen-testing we could reduce the likelihood of bugs in our authorization routines that allow an unauthorized user to access another user’s account.
Security throughout the development process
Keeping security in mind is important throughout the entire development process, though exactly which things you should be mindful of varies. The same applies to pretty much development methodologies though, even if the steps might be slightly differently arranged.
Project inception
You can’t really start thinking about security early on enough. It is especially important to establish if the proposed system can be implemented in a secure way (and if not, reconsider if the project should be started at all).
It might also be wise to do an initial risk assessment early on; though it may need to be expanded later.
Planning & Architecture
Of course, it’s important to have sound foundations to build upon. And while designing a system to be secure is not something you’ll do during dinner, there actually exist a handful of principles that can allow even a novice to get quite far. Having a secure design can significantly decrease the risk of vulnerabilities, but it does not prevent vulnerabilities introduced during development:
Development
It’s during actual development that a lot of the “classical” system security comes into play. Preventing SQL-injections, authentication, choosing dependencies, etc. While a good design is important even the best design cannot prevent a wrongly implemented system from being vulnerable.
Deployment
Most of the security aspects of deploying software are about “hardening” the system (image source: Bulbapedia)
Once you have a system that’s ready to get deployed, a new set of considerations come into play. You need to be aware of the best configuration of the platform (operating system, networking, runtimes, etc.) you’re running on and know how to apply it. This is often called “hardening”. Of course, you also need to make sure that you are deploying what you think you are deploying (no amount of system hardening can help you if you are deploying malware).
Maintenance
Now your system is running and doing well, so now you can take a vacation, right? Sadly, it is not that simple. You need to be aware of new security bugs and other vulnerabilities, both in your own system and in the dependencies you use. Security-wise it’s often a good investment to preemptively keep dependencies up-to-date, both to reduce the risk of old vulnerabilities being exploited and because it simplifies updating if a new vulnerability is identified.
This stage also has a lot of overlap with the Development and Deployment stages.
Social engineering
Because it is less technical in nature I’m also going to bring up social engineering in this first post. Though many variants of social engineering exist, they all exploit some human weaknesses like curiosity, social pressure, benevolence, etc. to gain access to some system. Common examples include phishing, leaving infected USB-drives where your target will find them and hopefully plug into their computer out of curiosity, and in dedicated cases even blackmail.
Social engineering is quite different from the others listed in that it’s not actually a technical but rather a human fault, consequently, it’s also quite hard to prevent through technical means. If an attacker has in some way convinced someone with proper authorization to hand it over then you have likely lost. There exist a few solutions though; proper 2FA prevents many phishing attempts, and in high-risk scenarios, you could require the authorization of multiple people. Logging all access and actions can help to identify who was socially engineered, but by the time you inspect these logs, it might already be too late.
By far the best solution though is educating people, both inside and outside your organization, about the dangers of social engineering and how to withstand it.
I highly recommend watching this great video by Tom Scott which gives a nightmare scenario of what could happen if a single person (in this case by own accord so not really social engineering, but it’s similar enough) misuses their authorizations:
Summary
These days software security is more important than ever, and every developer should know at least the basics of developing a secure system. Often this might go further than purely technical know-how, as one might also need to be able to convince other stakeholders of the importance of security.
Posted on August 12, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.