DevSecOps vs DevOps
Fast forward a few years, and now the security team come up with “DevSecOps” to break from their silo. Now, the thing to note here is that the problem security teams were trying to solve is the fact that software delivery has become much faster, and security teams have become the bottleneck with their tools and processes that can’t match “DevOps” speed. In other words, the problem “DevSecOps” was trying to solve was somewhat different from the initial problem “DevOps” was meant to solve which revolves around speed and efficiency.
As you may already know, once security teams started adding their security tools such as SAST, DAST, and SCA scanners within the DevOps pipeline to achieve the goals of “DevSecOps”, the initial goals of “DevOps” were compromised, as these tools were generating a lot of false positives/low importance findings which were disrupting the SDLC and having significant hits on speed and efficiency, the main goals of “DevOps”.
As a result, instead of “DevSecOps” breaking the virtual wall between Security and DevOps teams, it added to the friction because of the contradicting goals of security vs speed and efficiency. While many improvements have been introduced to reduce the speed and efficiency hit such as “Shifting-Left”, the truth remains that “DevSecOps” still has a significant effect on speed and efficiency.
The Security vs Speed and Efficiency Tradeoff
While we can’t deny the effect “DevSecOps” has on speed and efficiency, we as security teams still defended it with the argument that the value you get from verifying the security of your application makes this a good tradeoff to take.
Theoretically of course this is true, it is ok to sacrifice a bit of speed and efficiency to ensure security. However, this takes us to the second problem with “DevSecOps”. Let me explain this problem with an example:
The vulnerability CVE-2023–38646 was discovered around July 2023 affecting Metabase (a popular open-source business intelligence tool) which had a devastating impact on pre-auth RCE (Remote Code Execution). One of the main causes of this vulnerability was a line of code a developer removed by mistake in a Pull Request, this line of code cleared the temporary setup token used during initialization of the application after the setup is done. Removing this line of code, meant that an attacker could get this setup token after setup and use it to bypass authentication.
How is that related to “DevSecOps”? Think about all the tools security teams have been adding to the SDLC like SAST, DAST, and SCA, and ask yourself, would any of these tools have detected this issue before being pushed to the main branch? The answer is no, simply because this is a business logic issue very specific to Metabase. The truth is this is just one of many examples of critical vulnerabilities that are related to application-specific business logic which tools can’t discover.
This is a very clear security blindspot for “DevSecOps”, one that makes the tradeoff argument less convincing, as you are sacrificing speed and efficiency for incomplete coverage for security.
What does “Security” mean?
The problem with the above approach (let’s call it tool-based “DevSecOps”) is that it doesn’t start with a clear definition of what security means, or more accurately it lets the tools define that for us. That is a problem because while security tools can detect known issues and missing best practices, they can’t understand the context of the application, or define security. This leads to a lot of time lost on false positives/low-importance findings, as well as critical issues missed.
So, how do we define “Security”? Let’s start with the dictionary definition:
The state of being free from danger or threat.
The keyword here is “threat”, you can’t say whether your application is secure unless you know the things it needs to be secure from, the “threats”. And this is the very goal of “Threat modeling”.
Let’s take the 4 famous questions “Threat Modeling” aims to answer:
- What are we working on?
- What can go wrong?
- What are we going to do about it?
- Did we do a good job?
The first question focuses on the “Scope” of what is being built. The second question focuses on “Threats”. The third question focuses on “Mitigations”.
For example, for the Metabase application mentioned above a threat would be something like this:
Threat: The setup token being available after initialization would allow an attacker with network access to bypass authentication.
And its corresponding Mitigation would be:
Mitigation: The setup token is always cleared once the initialization is complete.
As you can see, “Threat modeling” defines what “Secure” means for any application by defining what it needs to be secure from “The Threats”, and what needs to be always true to remain secure “The Mitigations”. This allows us to take an informed approach to how to deploy “DevSecOps” as we are going to see shortly.
Cover your mitigations with tests
What completes the connection between “Threat Modeling” and “DevSecOps” is the 4th question “Did we do a good job?”, this includes multiple things:
- Did we catch all the important threats?
- Do we have good mitigations?
It also includes:
- Are the mitigations working as expected now and in the future?
And this is where “DevSecOps” comes in, because now with a clear definition of the things that always need to be true to be secure “The Mitigations”, our goal becomes covering all of these with proper tests and tools to make sure they are working as expected, and they don’t break by future code changes.
For example, the Metabase threat and mitigation mentioned above would be covered by a test like:
Test: Write an integration test that simulates the setup process and verifies that once the process is complete the setup token is no longer accessible.
Note that this test would have blocked the pipeline for the pull request that removed the line of code causing the vulnerability. Note also, that we didn’t have to use a security tool for this, we can just use whatever the developers are using to write their “stability” integration tests.
Let’s take a couple more examples:
- For a threat related to unauthorized access, which is mitigated by authentication and authorization, we should have unit or integration tests covering authentication and authorization.
- For a threat related to SQL injection, which is mitigated by the use of parameterized queries, we should cover this with a SAST tool that supports the language and library we are using for SQL. Note that in this case, we will not block all SAST findings, just the ones related to our mitigation.
The “Threat Modeling” based DevSecOps process
For this to work efficiently, we ideally need to perform “Threat Modeling” during the design phase of any project, and one of the outcomes of “Threat Modeling” would be the testing plan to cover the mitigations. Then, we need to verify that these tests have been implemented before deploying the project to production.