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:

RequirementDetail
Source checkoutThe app's full source, not just its manifests
Dependencies installedRun the project's normal install first (step 1)
Memory8 GB minimum. 32 GB recommended for npm, Python and Ruby; 16 GB for Maven, Go, NuGet and Cargo
PythonPython 3.11 or later, and uv 0.5 or later
JavaJDK 8 or later
.NET.NET 6 or later
GoThe Go version you build the project with
Baseline numbersFor 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 download

The 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.

AnalysisTotal CVEsDirect dependencyReachablePotentially reachableUnreachableNoise 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 socketcli command. 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

SymptomCauseFix
Halts with "workspace contains no source files"The folder has manifests but no source codeRun from the app root. For a workspace that really has no source, add --reach-continue-on-no-source-files
Halts on a package install errorA dependency couldn't be downloaded, usually a private oneInstall dependencies first (step 1) with your registry settings
Many Unknown resultsPrivate dependencies weren't installedSame fix, then rescan
Timeout or out of memoryThe 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 fileNo lock file or version catalogAdd --dynamic-sbom-inference so the build tool resolves the dependencies
A later scan shows old reachability resultsA kept .socket.facts.json was uploaded by a scan without --reachDelete .socket.facts.json from the scan directory
📘

The facts file

The analysis writes .socket.facts.json to 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


Did this page help you?