Full application reachability
Trace call paths from your own code on one or two representative apps, then have Security check a sample of the verdicts.
Precomputed analysis stops at your direct dependencies. Full application analysis starts from your own code, so it also covers CVEs in direct dependencies and turns every Potentially reachable result into Reachable or Unreachable. It runs on the machine that runs the scan: your source is analyzed there and isn't uploaded.
Run it on one or two apps, not the whole estate. Good picks are the app with the largest CVE backlog, plus one that depends on internal packages.
Before you start:
| Requirement | Detail |
|---|---|
| Source checkout | The app's full source, not just its manifests |
| Dependencies installed | Run the project's normal install first (step 1) |
| Memory | 8 GB minimum. 32 GB recommended for npm, Python and Ruby; 16 GB for Maven, Go, NuGet and Cargo |
| Python | Python 3.11 or later, and uv 0.5 or later |
| Java | JDK 8 or later |
| .NET | .NET 6 or later |
| Go | The Go version you build the project with |
| Baseline numbers | For this repository, from Cut CVE noise with reachability: in Alerts, filter Repository to the app and Category to Vulnerability, then record the total, Unreachable and Direct dependency counts |
1. Install dependencies
cd /path/to/your-app
npm ci # or: pnpm install, yarn install, uv sync, mvn dependency:resolve, dotnet restore, go mod downloadThe analysis can download public packages that are missing, but not private ones. CVEs reached through a private package that isn't installed come back as Unknown, so install with your normal registry settings.
2. Run the scan
socket scan create --org=your-org --repo="your-app" --branch="socket-reach" --reach --no-interactive .Using its own branch name keeps this scan off the Alerts page, so your baseline stays as it was. The scan ends with a report URL; open it to see the results.
For a large app, give the analysis more room. Each run gets the memory limit, so memory times concurrency must fit on the machine:
socket scan create --org=your-org --repo="your-app" --branch="socket-reach" --reach --no-interactive \
--reach-analysis-memory-limit 32GB \
--reach-analysis-timeout 30m \
--reach-concurrency 2 .3. Compare with the baseline
The scan prints its own results table when it finishes. It's the quickest way to read the numbers, and its Noise% column uses the same formula as the headline number:
Project │ Vulns │ Reach │ Unreach │ NoSup │ ... │ Noise%
. (root project) │ 49 │ 27 │ 20 │ 2 │ ... │ 41%
To check the same counts in the dashboard, open the scan report, filter the alerts to vulnerabilities, and use the CVE Reachability filter.
| Analysis | Total CVEs | Direct dependency | Reachable | Potentially reachable | Unreachable | Noise reduction % |
|---|---|---|---|---|---|---|
| Precomputed (baseline) | ||||||
| Full application |
Noise reduction is Unreachable divided by Total, times 100. Direct dependency only appears on the precomputed row: full application analysis covers those CVEs, which is why its figure can be much higher. Precomputed never returns Reachable, and full application never returns Potentially reachable.
4. Have Security check a sample
Numbers alone don't convince a security team. Pick 10 CVEs from the full application scan, 5 Reachable and 5 Unreachable, and have someone from Security review each one:
- Reachable: open the alert and follow the call path it shows from your code to the vulnerable function. Is that path real?
- Unreachable: use the advisory to find the vulnerable function, then search your code and its call sites for any use of it.
Record agree or disagree for each. A bar teams have used is 8 of 10 in agreement. For any disagreement, send the CVE, the package and your reasoning to your Socket team; that's the fastest way to a definite answer.
Run it in CI
Start from your platform's pipeline in Scan from CI/CD, then:
-
Run it in the image you already build with, since the analysis needs your toolchain, and install dependencies before the scan, as in step 1.
-
Add the reachability flags to the
socketclicommand. It takes the same flags and value formats as the Socket CLI:socketcli --target-path . --reach --reach-analysis-memory-limit 16GB --reach-analysis-timeout 30m -
Run it on the default branch only, and keep pull requests on the faster standard scan.
Verify
- The scan completes without a timeout or memory error
- Vulnerabilities show Reachable or Unreachable, with call paths on Reachable ones
- Few or no Unknown results
- Both rows of the comparison table are filled in
- Security reviewed 10 verdicts and recorded the agreement rate
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Halts with "workspace contains no source files" | The folder has manifests but no source code | Run from the app root. For a workspace that really has no source, add --reach-continue-on-no-source-files |
| Halts on a package install error | A dependency couldn't be downloaded, usually a private one | Install dependencies first (step 1) with your registry settings |
| Many Unknown results | Private dependencies weren't installed | Same fix, then rescan |
| Timeout or out of memory | The app is larger than the defaults (10 minutes, 8 GB) | Raise --reach-analysis-timeout and --reach-analysis-memory-limit, or lower --reach-concurrency |
| Gradle or sbt project halts on a missing lock file | No lock file or version catalog | Add --dynamic-sbom-inference so the build tool resolves the dependencies |
| A later scan shows old reachability results | A kept .socket.facts.json was uploaded by a scan without --reach | Delete .socket.facts.json from the scan directory |
The facts fileThe analysis writes
.socket.facts.jsonto the scan directory and deletes it after a successful scan. If you keep it with--reach-retain-facts-file, delete it once you've looked at it.
Next
Fix what matters for Reachable CVEs with an upgrade, and Patch what you can't upgrade for the rest.
Reference
Updated 8 days ago