A security scanner that ships the list of its own blind spots.
Zennoxa Shield runs SAST, dependencies, secrets, containers, and IaC in one pass. Then it ranks every finding by whether the vulnerable code is actually reachable. We publish our precision and recall, and the categories we don’t cover yet. One command reproduces all of it.
- MIT · free during beta
- Runs offline, single Go binary
- 24 languages
- CRITICALStripe secret keySECRET-018secret8const STRIPE_KEY = "sk_live_51H8xQ2eZ…"
- CRITICALCommand injection via tainted variableSHIELD-TAINT-CMDdata-flow21exec(cmd, (err, out) => res.send(out));
- CRITICALDangerous eval() usageSHIELD-JS-005pattern40return eval(formula);
- HIGHSQL injection via tainted variableSHIELD-TAINT-SQLdata-flow14db.query(sql, (err, rows) => res.json(rows));
- HIGHReflected XSS via tainted responseSHIELD-TAINT-XSSdata-flow28res.send(page);
- HIGHPath traversal via tainted variableSHIELD-TAINT-PATHdata-flow52fs.readFile(path, (err, data) => res.send(data));
- HIGHSSRF via tainted URLSHIELD-TAINT-SSRFdata-flow58axios.get(target).then(r => res.send(r.data));
- MEDIUMOpen redirect via tainted variableSHIELD-TAINT-REDIRdata-flow34res.redirect(next);
Purple marks the 6 findings the cross-line data-flow engine proved reachable. The eval() fired on a constant: pattern-only, not a proven path.
Every number reproduces on your machine — make bench-owasp. No estimates, no “up to”.
The problem
Most scanners hand you a thousand findings and call it coverage.
With no security team, a scanner that flags everything is worse than useless. You can't tell the exploitable bug from the noise. Shield ranks by whether the vulnerable code is actually reachable, and it publishes its own false-positive rate next to that ranking so you know how much to trust the order.
1,000 findingsthe handful that are reachable
How it ranks
We rank by what’s reachable, so the bug in your path sits at the top.
Severity tells you how bad a bug is in theory. Reachability tells you whether it’s in your path. Every finding gets a priority score from severity plus whether tainted input can actually flow to the sink, tracked across lines and files. A private key in a file nothing loads drops down the list. A token on a live request path rises. The scoring is deterministic, with no model guessing in the loop, so the same code always produces the same order. Each score expands to show the inputs that produced it.
- Find every issue
- Trace if untrusted input can reach it
- Rank by priority score
In our own research on 30,409 Critical CVEs, 89.7% carried no public sign of ever being exploited.
Most scanners sort by theoretical severity, so the one bug that can actually hurt you sits at position 340. Reachability moves it up.
Same findings, reordered by reachability.
Reproducible accuracy
What Shield catches, and where it’s still limited.
Every category is here, including the ones that score badly. Score 0.582 (Youden’s J) on the public OWASP Benchmark v1.2: 92.5% precision, 64% recall across 2740 labelled cases. Per category: weak-random 1.000, crypto 0.808, hash 0.690, XSS 0.516, down to SQL injection at 0.303 and trust boundary at 0.237, our weakest categories. Every category now scores above zero — the full list is below. CI runs this exact command on every commit, and the 0.44 gate fails the build if accuracy regresses. Pinned to release v0.3.0; the published SHA256 lets you confirm you ran the same binary we scored.
· binary SHA in SHA256SUMS
The dependency bugs that are real, and nothing else.
Shield’s SCA reads the versions actually pinned in your lockfile and checks each one against OSV. Because it resolves the exact pin, it won’t flag a CVE in a package you’ve already patched — the panel shows what that looks like on a real repo.
Most SCA tools pad the list with CVEs that don’t apply to your pinned versions. The one you need to patch ends up buried under fifty that don’t.
$ make bench-accuracy TARGET=/path/to/repoOne command
One binary. Every layer. Nothing hidden.
Point Shield at a repo. In one deterministic pass it runs SAST (with taint tracking), dependency CVEs, leaked secrets, and container + IaC misconfigurations, across 24 languages. It runs locally and offline, and no model reads your code, so your source never leaves your machine. Wiring it into CI is one line.
- Offline Go binary. Code never leaves your machine.
- Deterministic. No LLM in the scan path.
- MIT-licensed CLI, free during beta
- SAST
- SCA
- Secrets
- Containers & IaC
- JavaScript
- TypeScript
- Python
- Go
- Java
- Ruby
- PHP
- C#
- C++
- C
- Rust
- Kotlin
- Swift
- Dart
- Scala
- Perl
- Lua
- Groovy
- VB.NET
- Objective-C
- PowerShell
- Shell
- Solidity
- Vyper
From the Zennoxa team
We do the security research, then build the tool.
Zennoxa is a developer-security company. We publish reproducible studies on how vulnerabilities actually get exploited. Every study ships with its method and raw numbers, so you can re-run it yourself. What we learn goes back into Shield.
0 layers, and the edge of each one. 0 languages, 0 rules, 0 dependency ecosystems, 0 secret detectors.
340 rules across 24 languages. Regex, intra-file taint, dataflow.
- 22 general-purpose languages + Solidity & Vyper; 14 with comprehensive rule coverage, the rest lighter.
- 7 framework packs: Express, Next.js, React, Rails, Django/Flask/FastAPI, Solana/Anchor, CI/CD.
- Not full AST, and not interprocedural yet. Taint that crosses a method boundary is a known blind spot.
10 ecosystems and 18 manifest formats, cross-referenced against OSV.dev advisories.
- Versions come from your actual lockfiles, not the ranges in a manifest: npm, PyPI, Go, RubyGems, Maven, crates.io, Packagist, NuGet, Pub, Hex.
- CycloneDX 1.4 SBOM output; GHSA/CVE/PYSEC aliases via OSV.
- go.sum is not parsed; we read declared versions from go.mod. No Swift, Conda, Bazel, Bun, or Nix yet.
27 detectors: 26 named patterns plus a high-entropy fallback.
- Cloud (AWS/Azure/GCP), VCS tokens (GitHub/GitLab/npm), Stripe/Twilio/SendGrid/Slack/Discord, OpenAI/Anthropic/Linear, private keys, DB connection strings, JWT.
- Guards against connection-string, PEM, and SQL-clause noise keep the false-positive rate down. Live credential validation is optional.
25 checks across Dockerfile, docker-compose and Kubernetes manifests.
- 14 Dockerfile/compose rules + 11 Kubernetes rules, file/regex based.
- Opt-in image-layer OS-package CVEs: `shield image-scan --os-cve` (pure-Go: pulls layers, reads dpkg/apk/rpm, queries OSV) or `--cve` via Trivy.
16 checks: Terraform 6, Kubernetes 7, CloudFormation 3.
- It matches strings and regexes; it does not build a full HCL/YAML graph.
- CloudFormation is filename-gated, and there is no real Helm template rendering yet.
A pre-deploy probe of a live endpoint: security headers, TLS configuration, information disclosure and exposed sensitive paths.
- A pre-check, not a full crawler or fuzzer — it probes a URL you point it at; it does not spider the app or replay authenticated flows.
- Requests are SSRF-guarded (no internal-network pivots). Meant to run against staging before a deploy.
The priority score blends severity, EPSS, KEV and reachability, so a finding on a live path outranks a “critical” in code nothing loads.
- Reachability traces tainted input to the sink across lines on every language, with an import-graph pass for Go and JavaScript/TypeScript.
- Import-graph reachability is Go and JS/TS only today; the full ranking runs in the pipeline (the CLI prints taint + severity order). See “How it ranks” above.
Every scan gets a maintainability grade from lines of code, cyclomatic complexity and duplicate-block density.
- A code-health signal, not a security score: a clean grade does not mean the code is free of vulnerabilities.
A CycloneDX 1.4 and SPDX 2.3 bill of materials from your real dependency tree, each component tagged with a Package URL (PURL).
- Covers declared dependencies from your lockfiles; it does not inventory vendored or dynamically loaded code.
- Offline generation does not populate component hashes, and license fields are emitted as NOASSERTION — treat it as a dependency inventory, not a license audit.
One assist, not a scan layer:
- AI explanations — a local model writes a plain-language explanation and a suggested fix for each finding, which you review. It never patches your code or opens a PR.
Secure what you ship — not just what you write.
The same engine follows your code past the repo: the container images you push, the infrastructure you declare, and every pull request before it merges.
Container images, any registry
Pull straight from Harbor, Docker Hub, GHCR, GitLab or any OCI registry and scan the image config & build history — Shield reads the manifest and config, not the multi-gigabyte layers, so it stays fast and light. Private repos and Harbor robot accounts included.
- Harbor
- Docker Hub
- GHCR
- GitLab
- OCI / v2
Infrastructure as Code
Every Terraform, Kubernetes manifest and CloudFormation template in a connected repo is scanned automatically — catching the misconfigs that quietly become breaches.
- Terraform
- Kubernetes
- CloudFormation
Gate every pull request
From your CI job, post a pass/fail commit status and a PR comment back to your git provider — and emit SARIF that GitHub code scanning ingests. Break the build on what actually matters, not on noise.
- GitHub
- GitLab
- Bitbucket
- Azure DevOps
Plugs into where you already work.
Connect a repo, get alerts where your team already is, and export to the formats your pipeline expects. Everything below is wired end-to-end, not a roadmap promise.
- GitHub
- GitLab
- Bitbucket
- Azure DevOps
Connect a repo; scan on push and pull request; post the grade + findings back as a commit status and PR comments.
- Jenkins
- GitHub Actions
- GitLab CI
- SARIF
- SBOM
Run scans in your existing pipeline and gate the build. Emit SARIF for GitHub code scanning and a CycloneDX / SPDX SBOM.
- Slack
- Microsoft Teams
- Jira
- Obsidian
Route findings above a severity threshold to where your team already watches. Jira opens a ticket per finding; notes sync to an Obsidian vault.
Five layers in one pass, or five tools you keep wired yourself.
Three honest ways to cover the same ground. We don’t name names or invent a score for anyone else — the only number here is ours, and you can re-run it.
Known limits
What Shield doesn’t do yet.
- We favor precision over recall (64%). That means we miss some real issues rather than drown you in noise.
- Coverage is uneven by category — SQL injection (0.30) and trust boundary (0.24) are our weakest. Every per-category score is published.
- Rule-based & deterministic, so no LLM inventing findings. No AST yet on some languages.
- No SOC2 / ISO / FedRAMP. Every headline number is instead pinned to a commit you can re-run.
Common questions
What is Zennoxa Shield?
Shield is an open-source security scanner. One pass runs SAST, dependency (SCA), secret, container and IaC checks over your code. Then it ranks every finding by whether the vulnerable line is actually reachable. It ships as a single offline Go binary and covers 24 languages.
What does it actually scan for?
Injection flaws (SQL, command, path traversal), cross-site scripting, weak or misused cryptography, hardcoded secrets and API keys, known-vulnerable dependencies (CVEs), and misconfigured containers and infrastructure-as-code. Coverage is uneven by category — SQL injection and trust boundary are our weakest — and every per-category score is published.
How is it different from other scanners?
Reachability. Most scanners hand you a wall of "critical" findings sorted by theoretical severity. Shield traces whether untrusted input can actually flow to each sink, across lines and files, and ranks by that. A private key in a file nothing loads sinks down the list. A live injection path rises to the top. The scoring is deterministic: the same code always produces the same order, and you see the reasoning behind it.
Which repos can I scan, and is there a CLI?
Any repository you can check out locally. The binary runs fully offline, so your source never leaves your machine. Point the CLI at a directory and it prints ranked findings to your terminal, or emits SARIF for GitHub code-scanning and CI gates. Running a scan needs no account and no upload.
How much does it cost?
Shield is MIT-licensed and free during beta. No seat limits, no repo caps, no credit card needed. Pricing lands when it leaves beta, published the same place the accuracy numbers already are.
Start scanning
Built for the team that doesn’t have a security team.
Scan your repo. Trust the short list.
Run one command and see your reachable, ranked findings in under a minute. Free during beta, offline by default, no account needed. The benchmark number reproduces on your machine or the claim doesn’t count.
$ curl -sSL zennoxa.com/install | sh$ shield scan .Open-source CLI · MIT · deterministic · nothing leaves your machine
It’s not a compliance suite or a Fortune-500 console. It’s a scanner that tells you what to fix first.