- Part 1: Code, Container, Cluster, Cloud: The 4C’s of Cloud-Native Security
- Part 2: Container Security: The 4C’s of Cloud-Native Security
- Part 3: Cluster Security: The 4C’s of Cloud-Native Security
- Part 4: Code Security: The 4C’s of Cloud-Native Security ⬅
- Part 5: Cloud Security: The 4C’s of Cloud-Native Security
Requirements, architectures, and runtime environments continuously increase the overall complexity of applications. Both programming languages and frameworks evolve rapidly to address those challenges and maintain developer productivity without making developers write vulnerable code. However, even using the most recent frameworks does not protect you and your team from introducing massive vulnerabilities by unintentionally producing insecure code. Hopefully, no one produces insecure code by intention.
Often, authors of insecure code don’t know about vectors they introduce with a particular code section or a newly crafted API endpoint.
Those unintended security vectors must be discovered, discussed, and eliminated before deploying the malicious code to production environments. Traditionally, organizations implemented security gates that every release of an application must pass to find its way to the production environment.
In the context of cloud-native applications, organizations should think about their processes and security gates again. Securing source code late in application lifecycle management may come at a very high cost.
That’s why we see trends like shift-left security becoming more and more popular in our industry. Shift-left security puts the developer more in focus.
Developers should have robust tooling to scan and analyze their code. This allows developers to verify if the created code meets regulatory compliance and security requirements already the inner-loop. Additionally, adopting shift-left security will enable developers to address security concerns immediately and „stay in the zone“ (the unintentionally malicious feature is still on top of the developers‘ minds).
The developer does not have to do a „context-switch“ or zone-out, which means she can address the security concerns while implementing the feature.
In the end, this speeds up the overall development process and reduces costs compared to iterating overall features of a particular release and fixing a huge list of security concerns late in the application lifecycle. When we look at code security, numerous tools are available. We can group those tools into the following categories:
- Static Application Security Testing (SAST): Also known as white-box testing. SAST tools analyze the code of your application
- Dynamic Application Security Testing (DAST): Also known as black-box testing. DAST tools analyze your application from the outside.
- Interactive Application Security Testing (IAST): With IAST tools, you typically instrument the system under test to gather metrics from the running application and enrich it with insights collected by the collector integrated into your application.
For the scope of this article, we will jump into Static Application Security Testing (SAST). In my opinion, it is the first category of code security tools every development team should address and add corresponding tools and products to their tool belt.
We already learned that SAST tools scan your application’s source code for known anti-patterns, code smells, and patterns that may lead to additional attack surfaces.
SAST tools do so by checking every line of source code against vast lists of rules (some vendors call them catalogs). If we look at a single rule, it might look trivial, or you may think it would find code smells instead of actual vulnerabilities or security vectors. However, having your code checked against all those rules can and will increase the overall security of your code. And assist you and your team in authoring more secure and robust code.
For demonstration purposes, we will now look at SonarQube. SonarQube is one of the most popular and mature SAST solutions. Consult the official SonarQube website to spot the differences between available editions and possible integrations with your ALM suites and VCS.
For now, we’ll use the open-source Community Edition, which we can quickly run in a Docker container for testing purposes. We also need some code to run an analysis on. You can clone our sample repository from here on GitHub. Having the repository cloned, let’s spin up a SonarQube container to get our code analyzed:
# pull SonarQube image
docker pull sonarqube:latest
# start SonarQube
docker run -d --name sonarqube-dev -p 9000:9000 -p 9092:9092 sonarqube:latest
Consult the container logs to see when SonarQube has finished initialization (
docker log sonarqube-dev -f). Fire up your browser and navigate to
http://localhost:9000 and log in with default credentials (
admin:admin). From within the SonarQube portal, create a new project. Once you’ve created the project, you can generate an authentication token by setting up a local analysis, as shown in the following animation:
As you can see, SonarQube provides detailed instructions on installing the scanner and executing a code analysis. Follow the instructions and run a scan within the cloned repository:
# install Scanner as global tool
dotnet tool install --global dotnet-sonarscanner
# start scanner
dotnet sonarscanner begin /k:"MinimalApi" /d:sonar.host.url="http://localhost:9000" /d:sonar.login="
# build the application
# stop scanner
dotnet sonarscanner end /d:sonar.login=" "
When you stop the scanner, move back to the SonarQube portal, it should reload within a few seconds and display the code analysis results as shown here:
SonarQube does a great job analyzing complex projects and providing accountable actions based on its findings. You’ve to arrange SonarQube settings a bit according to your needs. False-positive findings are one of the most significant disadvantages when it comes to SAST. It may need some time and tinkering to get the proper configuration in place.
As you can see, developers can quickly scan their code locally before pushing changes to VCS.
Another essential aspect modern SAST tools address is supply chain security. If you’re a .NET developer, all the dependencies of your projects are listed in the
package.json is your single point of truth,… almost all modern languages explicitly track dependencies in more or less the same way.
You could manually scan those files, detect outdated dependencies or take it one step further and watch all the downstream repositories for new vulnerabilities being discovered in your dependencies. However, achieving all this manually has some disadvantages:
- doing it manually means there will be exceptions, and things will be forgotten
- diving through all dependencies and their dependencies is way too time-consuming
- these investigations must be synchronized in the team (think of your co-worker who is working on a dedicated feature branch)
With a proper SAST tool in place, you get all of this in no time. Vendors extend their SAST tools and dependency checking features continuously. For years now, you’ve been able to have your SAST tool create pull requests instantly when a dependency is updated.
If you’re using GitHub for storing your source code, GitHub’s Dependabot is by far the most straightforward and most obvious choice to implement supply-chain security.
Dependency analysis is enabled on all public GitHub repos by default and accessible via the Dependency graph.
You can activate even more advanced features using the settings page of your GitHub account or your GitHub organization. Currently, Dependabot offers the following optional features:
- Dependabot alerts: Get precise alerts when new vulnerabilities are found in one of your dependencies. (Read more about Dependabot alerts here)
- Dependabot security updates: Update non-vulnerable dependencies with ease. (Read more about Dependabot security updates here)
Without any configuration, Dependabot will create dedicated pull requests for outdated dependencies, as shown in the following figure:
Although Dependabot scans for outdated and vulnerable dependencies automatically, you can also integrate it in your custom GitHub Actions. Consult this guide provided by GitHub to dive deeper and learn how to integrate Dependabot in your GitHub Actions.
Code Security is a vast topic. Numerous vendors provide tools addressing different security testing categories. Generally, competition is a good thing. However, I found it cumbersome to mix and match devices from other vendors to address all concerns.
Nevertheless, organizations must invest in secreting their intellectual properties. Adopting shift-left security and equipping developers with proper tools will pay off in the long run.