DIY guide: ‘Build vs buy’ your OSS code scanning and app security toolkit
You’re confident in your development chops—confident enough to know the apps you’ve built aren’t completely free of security and configuration flaws. You’ve also researched the deep ecosystem of scanning tools available and perhaps got overwhelmed by the sheer volume of choice. What’s the right “portfolio” of open-source app security tools to identify vulnerabilities in your dependencies, Infrastructure as Code (IaC) configurations, containers, and more?
To get you on the right track, we’ll cover 10 essential categories of code scanning and security tooling, and recommend 9 OSS projects, with just the essential information you need to get started:
- How that scan helps the security of your app.
- Which open-source project you can install and how to run it.
- Some alternatives (when available) you can pick from.
With that, you’ll have a no-BS path to scan your apps for critical security issues in code and cloud configurations. What’s not to love?
Well, the configuration and management part isn’t all roses—but we’ll get to that later.
What you’ll need
Just bring your local workstation, whether that’s a desktop or laptop—it doesn't matter if you’re using macOS, Windows, or Linux.
A developer environment is optional but recommended. To run this suite of open-source scanning tools, you’ll need to install a lot of software you might not want on your base OS, requiring bigger updates, polluting your autocomplete, and pinning you to specific tools that might not work across all your projects. A developer environment containerizes and isolates, to some degree, all your development-specific tooling from the rest of your OS.
Luckily, you have some great open-source tools to choose from:
- With Docker, you can spin up a new barebones container named
devenv-01
like so:docker run --name devenv-01 -it ubuntu:24.04 sh
- With Daytona, which comes with many “batteries included” for development workflows:
daytona create --code
- Or with Distrobox, which embeds any Linux distribution inside your terminal, letting you install software
The great thing about a developer environment is that once you’re done with a particular “stack,” you can safely delete the container without impacting your workstation.
#1: Cloud security posture management (CSPM)
How does CSPM help app security?
CSPM helps you enhance the security and compliance of your cloud environments. By continuously monitoring your applications and their upstream services against industry best practices and your internal policies, CSPM tools assess issues, prioritize them based on their criticality, and offer recommendations for remediation. With CSPM, you take more ownership of the baselines and guardrails that prevent yourself or others from promoting vulnerable applications to production while also rooting out misconfigurations and overly permissive user roles.
Install and run your OSS CSPM project: CloudSploit
To install CloudSploit, you’ll first need Node.js to download its dependencies and run the engine.
git clone https://github.com/aquasecurity/cloudsploit.git
cd cloudsploit
npm install
Next, you need to configure CloudSploit with read permissions to your cloud account, with support for AWS, Azure, GCP, and Oracle. Follow the directions for your cloud provider, using the repo’s config_example.js
file as your template, to create a config.js
file with all the details you’ll need to run your first complete diagnostic and get results in JSON.
./index.js --collection=file.json config.js
#2: Software composition analysis (SCA) of open-source dependencies
How does SCA help app security?
Your apps inevitably have a large tree of open-source dependencies that you now rely on, from your UI framework all the way down to helper libraries you use in a single LOC, like a validator for email addresses. SCA is like a background check on your code’s extended family, identifying security vulnerability and licensing issues not once, but continuously. Because your SCA tools notify you about new vulnerabilities and remediations, you’ll have confidence your open-source supply chain remains a helper, not a hindrance, to productivity.
Install and run your OSS SCA projects: Syft + Grype
For locally-run SCA, you’ll need Syft to create a software bill of materials (SBOM) and Grype to analyze said SBOM for known vulnerabilities. Since the same team makes Syft and Grype, they support many installation methods but recommend their respective one-liners:
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
With Syft installed on your local workstation, you can create a SBOM for your container, replacing <YOUR-IMAGE>
with an image in a configured container registry or a local directory.
syft <YOUR-IMAGE> -o syft-json=sbom.syft.json
You’ll end up with a sbom.syft.json
in your working directory, which you can then feed into Grype.
grype sbom:path/to/syft.json -o json
Grype then prints out a vulnerability summary in the format below, including severity details and information about known fixes, which you can use to guide your prioritization and remediation process.
{
"vulnerability": {
...
},
"relatedVulnerabilities": [
...
],
"matchDetails": [
...
],
"artifact": {
...
}
}
Alternatives and caveats
Trivy is a solid OSS alternative for SCA—it won’t offer 1:1 feature parity across the board, but it will be more than enough to get you started.
#3: Secrets detection
How does secrets detection help app security?
A secrets detection tool scans your code and configurations for credentials you don’t want to expose publicly. These secrets can include API keys, access tokens to third-party providers, passwords to upstream databases, certificates, encryption keys, and more, and once they’re pushed to a public repository, you’ll have to go through a painful process to remove them from your Git history—better to detect them early and take action before you commit.
Install and run your OSS secrets detection project: Gitleaks
Gitleaks scans your repositories for the presence of hardcoded secrets, past or present, by parsing Git logs. Its detect
behavior identifies secrets that have already been committed, while the protect
behavior scans uncommitted changes to prevent you from making mistakes in the first place.
For maximum control, we recommend installing Gitleaks from source.
git clone https://github.com/gitleaks/gitleaks.git
cd gitleaks
make build
The first time you run Gitleaks, you can create a baseline report to give you results only for new secrets exposure.
gitleaks detect --report-path gitleaks-report.json
With subsequent invocations, you should reference your gitleaks-report.json
file to scan Git logs for only secrets added since you created your baseline report.
gitleaks detect --baseline-path gitleaks-report.json --report-path findings.json
Your findings.json
file will contain details about the commit hash and author of each potential leak, helping you focus on fixes.
Alternatives and caveats
Unfortunately, there aren’t many options beyond Gitleaks. Other open-source secrets detection projects have gone years since the last commit—not exactly confidence-inspiring to protect the apps you’re working on today. If you’re a service provider, you can register for the GitHub secret scanning partner program, which identifies when your users accidentally commit your secret token formats to one of their repositories.
#4: Static application security testing (SAST)
How does SAST help?
SAST is the fine-toothed comb of app security tools, analyzing your codebase line by line to check for flawed syntax, structure, or logic that could leave your app vulnerable. Think SQL injection attacks, cross-site scripting (XSS) opportunities, buffer overflows, and more. By checking against popular databases of known CVEs, a solid SAST tool will give you confidence that you’re not leaving big security flaws on the table—and some even offer autofix suggestions for quick remediation.
Install and run your OSS SAST project: Semgrep
Semgrep scans your code, finds bugs, and enforces established code standards with every invocation, with support for more than 30 languages. For the sake of simplicity, we’re focused on Semgrep CLI, which is just one part of a complex ecosystem of products.
The most universal way to install the Semgrep CLI is with Python/pip.
python3 -m pip install semgrep
Run your first scan to create a report of code-level flaws and vulnerabilities as a JSON file.
semgrep scan --json --json-output=semgrep.json
Alternatives and caveats
The SAST world is brimming with opportunity—if Semgrep doesn’t work for you, check out some language-specific alternatives like Bandit (Python), Gosec (Go), or Brakeman (Ruby on Rails) to get yourself started.
#5: Dynamic application security testing (DAST)
How does DAST help app security?
Unlike SAST, DAST simulates commonly exploited vulnerabilities against your app in a live environment. It’s less about the syntax and structure of the code you wrote and much more about replicating the approaches an attacker might take against your production deployment. DAST tools will double-check known CVEs in frameworks and libraries you use and test whether logged-in users can access sensitive data due to broken permissions or “toxic combinations” of multiple vulnerabilities that open your app to far worse consequences.
Install and run your OSS DAST project: Nuclei
Nuclei is a community-driven vulnerability scanner that uses templates to send requests to the app you want to secure running in a local environment. You can write custom templates using YAML, but the Nuclei community also has an extensive library of pre-configured templates to test against your app.
You need Go on your local workstation to install Nuclei.
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
From there, the simplest way to run Nuclei is by specifying a single target—your app running locally in a developer environment—and leveraging the template library, which Nuclei activates by default.
nuclei -u localhost:5678 -je nuclei-report.json
Alternatives and caveats
The Zed Attack Proxy (ZAP) is a fantastic scanner actively maintained by a global team of security experts and developers. However, unlike others in this list, ZAP is a graphical app by default. There are options for using your terminal, but they’re not exactly the most developer-friendly compared to other processes you’ve followed this far.
#6: Infrastructure as code (IaC) scanning
How does IaC scanning help app security?
Your code is just half the equation in getting to production—today, most teams use IaC tools like Terraform, CloudFormation, and “base” Kubernetes Helm charts to provision cloud services in a declarative, version-controlled, and repeatable fashion. IaC scanners identify vulnerabilities in these JSON or YAML blueprints to prevent you from ever deploying an insecure state to production.
Install and run your OSS IaC scanning project: Checkov
Checkov scans many types of IaC code—Terraform configurations, Helm charts, Dockerfiles, and more—for common misconfigurations and potential security vulnerabilities. With more than 1,000 built-in policy checks for AWS, GCP, and Azure, the tool quickly helps you understand your cloud deployments' current risks and opportunities in a few minutes.
The team recommends installing Checkov locally via Python’s package manager.
python -m pip install checkov
You can then run Checkov against your working directory (or another directory where you’ve stored IaC files) and get a JSON file as your output.
checkov --directory . -o json
#7: Container image scanning
How does container image scanning help app security?
We love containers because they abstract away so much complexity, but whenever you build a container image, it can inherit vulnerabilities from its base image or package dependencies. Container image scanners discover vulnerabilities in your base images and Dockerfiles, however deep the dependency tree goes, to prevent you from unwittingly deploying an exploitable app.
And that is also how container image vulnerabilities were born.
Install and run your OSS container image scanning project: Trivy
Trivy is a versatile security scanner capable of parsing your container images for known vulnerabilities with CVEs, IaC issues and misconfigurations, the presence of secrets, and more. The Aqua Security team, which is behind the open-source Trivy project, maintains a public database of vulnerability information, gathered from more than a dozen data sources.
In tune with the other installation mechanisms recommended so far, we recommend using Trivy’s script for installing directly from the latest GitHub release.
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v0.51.1
By default, Trivy scans container images for vulnerabilities, misconfigurations, and secrets against any container image you specify, with results in standard JSON format.
trivy image --format json --output trivy-result.json <YOUR-IMAGE>
Alternatives and caveats
If you’ve been following along, you already have Grype installed on your local workstation from the previous section on SCA, and it works great for scanning container images with an SBOM created by Syft. If you’re on AWS, this is another place where Amazon Inspector can come in handy in a “two birds, one stone” fashion.
We also recommend Amazon Inspector, but with two big caveats—first, it only works with AWS deployments, and second, it’s not open-source software like the rest of our recommendations, meaning it comes with new monthly costs.
#8: Open-source license scanning
How does open-source license scanning help app security?
The legality of using open-source software in your commercial products isn’t something you check with legal or compliance teams once and forget about. OSS projects change licenses more frequently than you might understand, requiring you to either pay for an enterprise version, seek an alternative, or open-source some of your private code. License scanners identify changes and help you sail through security audits with a ready-to-go software bill of materials (SBOM).
Install and run your OSS license scanning project: Syft
As with Grype in the last step, you already have Syft installed on your local workstation and might even have an existing SBOM from setting up your SCA integration with Grype. If you don’t yet, you can quickly create a new one by either referencing a container image from a configured registry, or a path on your local workstation.
syft <YOUR-IMAGE> -o syft-json=sbom.syft.json
syft /path/to/image -o syft-json=sbom.syft.json
Depending on the complexity of your image and the depth of dependencies, you might get an SBOM file that’s a few thousand lines long. Within all that JSON output, you’re looking within the artifacts
array for the licenses
values of each package and dependency your container image relies on.
{
"artifacts":[
{
"id":"cdd2655fffa41c69",
"name":"alpine-baselayout",
"version":"3.4.3-r2",
"type":"apk",
"foundBy":"apk-db-cataloger",
"locations":[
…
],
"licenses":[
{
"value":"GPL-2.0-only",
"spdxExpression":"GPL-2.0-only",
"Type":"declared",
…
With these details in a single SBOM, you’ll be able to scan your licensing obligations for changes you might need to make downstream or migrations you should start preparing for. You'll also have a go-to resource for the next security audit you’re subjected to.
Alternatives and caveats
Trivy, first mentioned in the previous section, has a license scanning feature that presents you with opinionated results about the risk associated with the projects in your open-source dependency tree.
#9: Malware detection
How does malware detection help app security?
Malware scanners help you identify a threat that’s taken off in recent years: malware injected into dependency packages by attackers. The recent zx backdoor attempt is a fantastic—and frightening—example. Malware scanners detect these software supply chain attacks before you even merge your code to prevent you from having to make time-sensitive and costly fixes once the CVE goes public.
Install and run your OSS malware detection project: Phylum
Phylum’s CLI tooling lets you submit your lockfiles to their API for dependency analysis, which differs slightly from the other open-source tools we’re recommending here—the analysis doesn’t happen on your local workstation. Instead, you need to register an account with Phylum for authentication with their service.
Start by installing Phylum locally.
curl https://sh.phylum.io | sh
Then register your account and run your first analysis—Phylum should identify the lockfile you’re using.
phylum auth register
phylum auth login
phylum init
phylum analyze --json
Phylum’s analysis delivers a comprehensive output, starting with a true
or false
result based on whether your project passes Phylum’s malware check. Under the rejections array for each dependency, you’ll find a detailed description of the vulnerability and remediation advice from the OSS community. This allows you to aggregate results from your SAST, DAST, and SCA tests, empowering you to understand which vulnerabilities are due to your dependencies and which are embedded directly into the code you wrote.
{
"is_failure": true,
"incomplete_packages_count": 2,
"help": "...",
"dependencies": [
{
"purl": "pkg:npm/next@13.5.6",
"registry": "npm",
"name": "next",
"version": "13.5.6",
"rejections": [
{
"title": "next@13.5.6 is vulnerable to Next.js Server-Side Request Forgery",
"source": {
"type": "Issue",
"tag": "HV00003FBE",
"domain": "vulnerability",
"severity": "high",
...
#10: End-of-life (EOL) runtime detection
How does EOL runtime detection help app security?
The more frameworks, libraries, and runtimes you include in your app, the more opportunities there are for you to be leveraged dangerously against outdated versions or unmaintained dependencies. This is especially critical for runtimes directly exposed to the public internet. EOL runtime detectors read your dependency tree through lockfiles—even those in containers—to alert you well ahead so you can prepare for updates or migrations.
Install and run your OSS project: endoflife.date
endoflife.date is a database of EOL information about more than 300 tools and platforms, many of which are integral to the operation and security of your app. Instead of you having to explore obscure documentation sites or trawling through mailing lists to discover when a specific version of your dependency becomes unmaintained, you can quickly put dates around necessary upgrades to prioritize your efforts moving forward.
The easiest way to discover EOL data is to explore the site, paying particular attention to your programming languages, databases, frameworks, deployment tooling, and CLIs for cloud services.
As a developer, you might want a more CLI-centric approach to exploring EOL data for your major runtimes and libraries—endoflife.date has a simple API that outputs JSON data, which you can also append to a local file for future reference.
curl --request GET \
--url https://endoflife.date/api/nginx.json \
--header 'Accept: application/json' \
>> eol.json
A new problem: Managing all your code scanning and app security data
If you’ve followed along this far, you’ve built a handy toolkit of open-source code and configuration scanning tools. You’re ready to start running these against your locally-stored projects and branches for far better pre-commit security guarantees. Take that, shift left!
Your future, however, isn’t instantly faultless. This new toolkit comes with a big caveat: Your tools don’t speak together, and only around your app.
You’re still on the hook to:
- Individually configure each tool. Let’s take a simple option, like an allowlist of certain directories or dependencies you don’t want to bother scanning, as they’re not relevant to the security of your production environment. You’ll need to learn the arguments for each CLI tool by reading documentation and testing, which steals away valuable time from what you actually want to do: implement fixes.
- Run each scanner against each repository and branch. Even if you have a single repo and two branches—
main
anddev
—that’s nearly 20 operations to scan for vulnerabilities. Ideally, you’re running these scanners before you ever push changes to a remote, which means plenty of repeated operations throughout your day.
There are some ways to simplify this, of course. You can write a script to chain these open-source scanners together to run manually or as a pre-commit Git hook. That saves you terminal time, but only generates JSON output faster—you’re still on the hook for understanding what’s changed and whether you can still push your changes and (finally) create your pull request. - Trawl through massive JSON arrays for insights. These tools often produce output thousands of lines long. The comprehensiveness is good, but who has time to explore dozens or hundreds of potential security issues, hoping to understand each one well enough to understand its severity?
Over time, you’ll need more intuitive way to read results than unformatted lines of JSON, like importing into Google Sheets or building a simple app for viewing results. - Understand what’s changed between runs. Security scanning has two purposes. First, to help you identify existing problems in your code and configuration. Second, to prevent you from introducing new vulnerabilities as you build. If you can’t quickly understand whether you fixed a certain vulnerability or aren’t notified upon a new one slipping into your code, this whole effort is wasted time.
One option is to increment or timestamp your output JSON files, then use CLI tools to compare them.diff file1.json file2.json
is a great standalone tool, or you can trygit diff --no-index file1.json file2.json
for files not committed to your Git repository. - Aggregate, store, and share data for long-term analysis. As we’ve said before, security scanning is a continuous operation, not a one-off item on your TODO list. Plus, the results of your scanning efforts shouldn’t be locked away on your local workstation—your peers will want to know about the vulnerabilities most relevant to what they’ve built, even if they don’t have a similar toolkit running at the moment.
You’ll need to explore data platforms that put all this information into one place—yet another piece of infrastructure to self-host or pay for. - Create tickets in Jira or GitHub. You or a peer must escalate each identified vulnerability into a relevant ticket containing all necessary context and possible remediations. That’s the only way to ensure security transparency, get your peers to collaborate, and create the audit log your compliance standards might require. None of these tools support integration with your ticket platform, so you’ll have to create these tickets manually—and there could be dozens, if not hundreds, to wade through.
- Prioritize said tickets based on severity. Flooding your repositories with tickets is a project management nightmare. It’s a different but equally painful version of alert fatigue: How does anyone know which to focus on first? If your OSS tools can’t help you with severity, you’ll have to spend time making those determinations yourself, which might involve years of security knowledge you simply can’t shortcut.
- Manage the lifecycle of each OSS tool. Whether it’s keeping your tools up-to-date, trying to build automation, or looping runs and results into your CI/CD pipeline, you’re now on the hook for the long-term efficacy of your toolkit. You might have a better security posture than ever before, but at what cost to your real-world posture?
- Worry and wonder about what happens if the project loses its maintainer. If your dependencies and runtimes can reach EOL and create problems, so can the tools and platforms your local development environment depends on. Unfortunately, open-source projects are often built upon funding and maintainer models that are not sustainable for the long haul. You can still use stagnant or abandoned projects in your CLI, but when trying to improve your app security, they won’t help you uncover new vulnerabilities or methods of attack.
The current conversation in developer tooling swirls around a single concept: developer experience (DX). The better the DX, the more likely a tool will be integrated, used, treasured, and championed. And let’s be honest—the DX of this locally-run OSS scanning toolkit isn’t particularly great. You fully own your process and data, but at exceptional costs and time commitment. How much are you willing to pay for advanced app security?
Open-source security tools are amazing—we’ve even built a web application firewall for autonomously protecting Node.js apps against common and critical attacks—but for continuous security scanning and vulnerability remediation, there has to be another way. Maybe even one that’s built on top of this fantastic OSS foundation.
A new app security solution: Aikido
Aikido integrates all those open-source projects and a whole lot more.
Instead of running 10+ tools every time you get ready to commit your latest changes, you just need to add your repositories, Docker images, and cloud providers to Aikido once for comprehensive scanning. Aikido runs automatically in the background for continuous scanning or in your CI/CD pipeline for targeted recommendations with every pull request, protecting you from new vulnerabilities while pointing out existing ones that have been lurking in your codebase for months or years.
Even better, all results, context, and possible remediations are aggregated and stored in a single place—the Aikido dashboard—so you never have to worry about parsing JSON, merging multiple data sources, or shelling out for an expensive data management platform to create a source of truth. We’ve even built custom rules and special “glue” between these open-source projects to unearth correlations and results that would otherwise require an in-house specialty security researcher.
Aikido also integrates with your task management and messaging platforms, like GitHub and Slack, to create pre-triaged and -prioritized tickets. With all the context, documentation, and suggested autofixes, anyone on your team can pick up the issue and see it through remediation quickly and comprehensively.
App security would be in a far worse place if not for these open-source tools and many others. That’s indisputable. But just because of the way developer tools operate—on your local workstation, inside your terminal—means they’re both infinitely flexible and inherently isolated. The “it worked on my machine” meme still applies here, just with different verbiage:
If you’re looking for another way, which replaces all the burden of building this open-source toolkit with a platform that’s already built on top of the same projects, consider giving Aikido a shot for free.
If you choose the OSS route, you have our props and respect… but while you’re layering new tools and dependencies into your workflows, you really should let Aikido’s Web Application Firewall autonomously and continuously protect your Node.js apps from even the most vicious of vulnerabilities. The best DX, after all, is when the tool truly does all the hard work for you.