My biggest experience in IT is in the development environment. It’s been almost 20 years of developing software. I have been working with AppSec for just over a year, and in many meetings I participate, the subject “Test” always appears more precisely as “Security Test”.
Usually, in the following context: “we need to test that our software is secure” or “were the security requirements that the developers implemented tested?”
I asked myself, is it possible to unite these two worlds? Can’t we take advantage of the tests that the developer already does and add a “vision” of security?
Let’s go to Concepts
First of all, let’s contextualize in a simple way what would be a software test and a security test.
When we talk about software testing, we usually talking about tests to verify the quality of the code, if the data flow follows what is expected, and if the application will behave as expected in a production environment.
Now, in the case of security tests, the idea is to find vulnerabilities or security holes. On the Conviso blog, we have a more comprehensive article on security testing. I believe it is worth reading.
The first insight:
When looking at the OWASP SAMM, we have practice requirements-based testing within the Verification domain. When I started reading about this practice, I automatically envisioned unit testing, and integration testing, in short, taking advantage of what the developer already does!
Figure 1 – OWASP SAMM
The second insight
One day, a video with the title “DevSecOps wins with Security Unit Tests” appears on my YouTube timeline. I confess that until today I have not watched the entire video, but the title alone made me have some ideas and also see that my initial thought could work.
After that video, I started looking for things related to the subject and found another Let’s Write Security Unit Tests! Okay, another interesting case.
In my head, I had no doubts that it was possible, but I was starting in the area, and seeing that there were materials on the subject in reference channels like OWASP only made me more excited.
Talk is cheap! Show me the code!
Like every developer, I love the phrase above! Nothing fairer than implementing a security requirement and applying a “software test” to that requirement, more precisely, a function unit test.
For the proof of concept, I chose the C# programming language, the .Net Core framework, and to build and run the unit test, we will use the XUnit tool.
The security requirement chosen to be implemented and tested will be the security requirement “2.1.1 – Verify that user set passwords are at least 12 characters in length (after multiple spaces are combined)” of the OWASP ASVS.
The idea here is not to do a step-by-step, just to show the generated codes and also the expected results.
A function was created that will validate if a password meets the ASVS requirements, the generated code can be seen in Figure 2.
Figure 2 – Code to meet ASVS 2.1.1 requirement
Now, we will create the unit test that will validate the “IsValidPassword” function built in Figure 2. We can see the unit test code in Figure 3. Our unit test will check each “condition” of our “IsValidPassword” function.
Figura 3 – Unit Test Code:
It’s time to run the unit test and ensure everything is “passing” and that our “IsValidPassword” function is working. Who will do this is our unit test.
In .Net core, the instruction to run the test is “dotnet teste Project where the test is”, in my case the instruction was as follows:
dotnet test K8ServiceMesh.Tests/K8ServiceMesh.Tests.csproj
The expected result was achieved, and all tests passed, as shown in Figure 4, so we can send this code to production.
Let’s assume that’s what happened. Now our code is in production!
Figure 4 – Unit test result
Cool. However, another developer had a new feature to do. He looked at the previously created function and decided to remove the “condition” that checks if there is a capital letter in the password as shown in Figure 5.
I think that everyone here agrees that if the change reached production, our system will not be meeting the ASVS 2.1.1 requirement and will be allowed to use passwords without capital letters.
Figure 5 – Modified code, removing the capital letters verification condition.
So the developer made the code modification, and now he needs to run the unit test to check if what he did broke anything if it broke any tests. Let’s then run the unit test again and now we’ll have something like Figure 6.
Figure 6 – Breaking unit test
We can verify that the unit test broke and it says exactly where it broke. It broke on checking capital letters.
This shows the developer that he can’t modify the code the way he did and more! You are ensuring that ASVS Requirement 2.1.1 is not missed.
One of the biggest issues we face as security professionals are the discrepancy between the sizes of development and security teams.
Knowing what the developer does and how he does it can significantly help an application security professional to reuse a developer’s daily activities in favor of application security.
The tests that developers already run in their daily lives can take on the air of security tests, as long as these developers have a more accurate view of security
This conclusion of mine is not a “silver bullet” and in no way replaces all other best practices for building and delivering secure software, but it certainly could become one more layer among many others when it comes to S-SDLC.