Protect your applications against insecure design
What is insecure design?
Insecure design is a type of flaw that can sit in the background of everything you do. This vulnerability relates to how you as a developer design your programs, architect solutions, and employ security practices such as threat modeling — meaning that insecure design can present itself in a wide variety of ways (we’ll cover one simple way in the example below). Failing to do so can lead to flaws that threaten your organizational security, compromising sensitive data, granting privileges to individuals who can abuse them, and more. Coming in at #4 on the OWASP Top 10, it’s certainly something you should account for in your everyday development!
About this lesson
In this lesson, you will learn what is meant by insecure design and tips on how you can model your programs to protect against flaws in logic. We will begin by investigating a simple application which has a permissions problem, discussing why it’s a problem, and exploring how it could be remediated.
Plan plan plan
On average, vulnerabilities relating to insecure design rank at 6.8 on the CVSS scale, whereas the average across all vulnerability categories is 6.5. Shifting security all the way left to the design phase pays!
It’s important to note that this category of vulnerability doesn’t have any single presentation, and this example is extremely specific. Insecure design isn’t so much a single mistake that you can make like some vulnerabilities, so much as it is general inaction to think about how you design your applications.
You recently acquired a castle in Scotland! And while 16th century castles are cool, renovating a castle to have modern tech is no small task. You employ a close circle of friends with a specific set of skills who can help: there’s an electrician, a plumber, and a developer. As you employ more and more people, however, you realize that you can’t delegate to everyone on your own and enjoy living in the castle at the same time. So you ask your developer friend to build an app to handle the management of workers so you don’t have to work as hard keeping track of everything.
They come back with a barebones program which lets you delegate to your workers. Conscious of people invading your castle and taking control, the developer’s created three roles:
- Grunt: Read orders, submit time cards
- Developer: add and remove employees, edit code
- Castle Leader: Admin access
The first version of the program looks ugly and is littered with bugs, but your developer blames you for being understaffed. So you hire a new dev —“Sir Snake Oil” — who promises to improve efficiency of development tenfold. Your developer friend thinks this sounds great, and adds Sir Snake Oil into the database as a developer so they can get started right away.
Everything’s going great and work is much more efficient, and now instead of managing everyone, you can sit in one of your towers admiring the view while your new program does everything for you! Then there’s a knock at the door -— it’s your developer friend. They explain that you no longer own the castle because Sir Snake Oil removed you as leader and made themselves the Castle Leader, removing all of your access to your own system! This shouldn’t have happened — it’s your castle!
Storming the castle!
- STEP 1
- STEP 2
- STEP 3
- STEP 4
- STEP 5
Insecure design in action
Let's take a look at an example of how permissions and an insecurely designed app can lead to danger!
So we’ve seen that your developer friend made a mistake somewhere that allowed a nefarious user to sneak in and make organizational changes. How was Sir Snake Oil able to reach the same level as you? Well, because in the permission checking, your developer friend may have had permission set something similar to this initially:
Everything was working just fine until they had to add a new organizational member with the ability to create change! Now this wasn’t possible to do with how your developer had set up the permission structure, so the new member had to have the same permission as them. Perhaps it looked like this
Then Sir Snake Oil would have had access to this branch of code in the management program, allowing them to remove any worker they so choose!
Impacts of insecure design
In this instance, the impact was that a user was able to cause a lot of damage because the proper permissions weren’t set for them, or more specifically, a system of incremental permissions wasn’t used (more on that in a minute).
Here, the flaw in logic was that the developer friend assumed that any other developers needed the same level of permission as them, and so when they were added to the system to work, they were able to do more than they required.
Insecure design can be how you position servers in your network, the order of trust you put on your systems, the protections you include for other vulnerabilities (including using outdated practices, such as saving passwords in plaintext!), and more. As such, this example is a very specific scenario, but does showcase how lapses in judgment can lead to insecure systems as well — it isn’t always the software’s fault!
In the above example, your developer friend could have prevented Sir Snake Oil from causing so much damage if they had implemented fine tuned permissions in their application! This means giving users permissions to do specific things, and no more. For example, if the permission were set like this instead:
Then the ability of Sir Snake Oil to cause operational damage could have been greatly severed. Note that this doesn’t guarantee they couldn’t have caused damage some other way -— it’s important to employ general secure development practices.
Below are a few generalized tips to help prevent insecure design in your applications.
Use secure development procedures in application development
Have security be an active part of your development. Integrate security tools directly into your SDLC, read about vulnerabilities that could affect you, seek advice from security professionals (ideally an internal security team, but also outsourcing when necessary). All of these things are much cheaper than paying a ransom!
Similarly, having thorough documentation can help prevent confusion and conflicting policies within your applications. This is especially true when combined with a review system that ensures these are maintained and updated.
Test your code
Testing your code helps identify general bugs with your programs, which can include issues with security. Having a robust test suite can ensure you minimize silly bugs which can put your application at risk.
Implement threat modeling
Assess what’s important to protect in your organization and the measures you need to take to protect it. Ensure you consistently account for things which can negatively impact your security. Using strict access control, ensuring all teams in your organization who work on your application understand its structure and purpose, and locking down critical infrastructure are all necessities.
This advice is good to follow, and certainly not exhaustive (see the Keep learning section for more reading on secure design practices you could employ), but in the end it’s up to you to put them into practice. Secure design only happens when you think about what could make your development insecure, and then act to avoid that.