Make a coverage matrix: your languages and frameworks down one side, weakness classes across the top, and at least two test cases in each cell that matters. A claim of "supports 30 languages" tells you little about whether it understands your web framework, so only count cells you have tested.
Why a language list is not coverage
A language list says the tool can read the syntax. It does not say the tool knows how your framework handles input, sessions or templating. Injection in a plain database call looks different from injection through an object mapper. Authorization checks in one framework sit in decorators, in another in middleware, in a third in configuration files.
Infrastructure code, build scripts, workflow files and container definitions matter too. A security assistant that does well on application code may say little about a deployment pipeline file, where a lot of real risk lives.
Build the matrix
List what you actually ship. A small example:
| Area | Examples to list |
|---|---|
| Languages | The top three or four by lines of code |
| Frameworks | Web, API, ORM, templating, job queue |
| Infrastructure | Container files, orchestration manifests, cloud templates, CI workflows |
| Config and data | Environment files, migration scripts, SQL |
Across the top, pick weakness classes that matter for your product. Use common names so results are comparable: injection (CWE-89 for SQL), hard-coded credentials (CWE-798), broken authorization, unsafe deserialization, path traversal, and insecure defaults in configuration.
Fill in the cells
For each cell that applies, write two cases: a vulnerable change and its safe twin, as described in building a test set. Use your real framework idioms, including your own wrapper functions. If your team wraps database access in a helper, the test should go through the helper.
Score each cell with one of four marks: caught and safe twin quiet, caught but safe twin flagged, missed, or not applicable. Add a note for anything odd about the explanation.
Read the matrix
You will likely find an uneven map. Strong cells are where you can trust the tool more. Weak cells show where to keep other controls, such as manual review rules or a dedicated scanner. Blank cells are not "probably fine". Mark them unsupported until tested.
Pay particular attention to your highest risk code: authentication, payments, data export, administrative interfaces. If the tool is weak there, its value is lower than the average suggests.
Test the awkward cases
- A monorepo with several languages in one pull request.
- Generated code and vendored libraries. Does it skip them sensibly, or flood you?
- Very large files and large diffs. Does it truncate silently?
- Mixed changes: application code, a lockfile and a workflow file in one commit.
- Languages with less public code. Models tend to know the most popular ones well.
Truncation deserves a direct test. Make a pull request just above the stated size limit and see whether the tool says it skipped part of the change, or says nothing.
Keep the matrix
Review it each quarter, and whenever you adopt a new framework. A new framework means a new row, and a new row means new tests. Attach the matrix to your vendor review so the limits are visible to the people who rely on the tool.
Quick check
Is two cases per cell too few?
For a first screen it is fine. Add cases for cells that cover your riskiest code or where results looked inconsistent.
What if a language is unsupported?
Document it, and use another control for that code, such as a dedicated analyzer or mandatory human review.
Safeguard offers SBOM and dependency scanning across many ecosystems, and you can see how your own dependency tree looks with the free scan at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.