Java Reachability With Gradle


Socket Application-Level Reachability for Gradle Projects

Overview

Socket offers three types of reachability analysis:

AnalysisNoise ReductionRequires CLI --reach
Dependency Reachability (prev. Tier 3)~35%No (automatic)
Precomputed Reachability (prev. Tier 2)~80%No (automatic)
Full Application Reachability (prev. Tier 1)~90%Yes

This guide covers Full Application Reachability (previously Tier 1) via the --reach flag. Precomputed and dependency reachability apply automatically in the Dashboard without CLI flags.


Prerequisites

Install Socket CLI:

npm install -g socket
socket login

Or set API key:

export SOCKET_SECURITY_API_TOKEN=sktsec_<your_key>

Note: socket scan create requires an org slug. Run socket login to set a default, or pass --org <your-org-slug> on every command.


Step 1: Prepare the Gradle dependency manifest

The reachability analysis needs a resolved dependency graph for your Gradle build. The recommended approach is to add --dynamic-sbom-inference to your reachability scan command (Step 3 below). It has gradle generate a Socket facts file (such as gradle.socket.facts.json) as part of the scan, covering every Gradle build under the scan target rather than only the one at the root. Reachability is then analyzed and reported per subproject, and works from the graph your own build resolves.

If you'd rather generate the files yourself, run:

socket manifest dynamic-sbom-inference

This resolves the full dependency tree for each build and writes a Socket facts file (the preferred SBOM format for Socket), such as gradle.socket.facts.json, to its root directory. For a single build, socket manifest gradle does the same for the current directory. See socket manifest dynamic-sbom-inference --help for the available flags.

Note: If your project commits a gradle.lockfile (or uses a libs.versions.toml version catalog), Socket can read it directly, so the scan works without --dynamic-sbom-inference. The flag is still recommended: a committed file records versions captured at some earlier point and no artifact locations, so it can drift from what your build resolves today, and you give up the per-subproject analysis. See the Gradle setup instructions for the trade-offs.

CycloneDX alternative: If you prefer a CycloneDX SBOM, you can instead run socket cdxgen -t gradle -o socket-gradle.cdx.json --install-deps --lifecycle build. Without --lifecycle build, cdxgen defaults to pre-build to avoid arbitrary code execution; use --lifecycle build for a complete dependency graph that includes build-time resolved dependencies.


Step 2: Run Baseline Scan

Scan without reachability to establish a baseline CVE count. Add --dynamic-sbom-inference here too, so the baseline is built from the same resolved dependency graph the reachability scan in Step 3 will use:

socket scan create --dynamic-sbom-inference .

Note the total CVE count.


Step 3: Run Reachability Scan

Execute scan with Full Application Reachability enabled:

socket scan create --reach --dynamic-sbom-inference .

Socket performs function-level reachability analysis to determine which CVEs are exploitable. The project does not need to be compiled first — analysis runs on source, but uses class files when found (useful for builds that generate code at compile time).

Performance Tuning

For large Gradle projects, adjust these flags as needed:

socket scan create --reach --dynamic-sbom-inference \
  --reach-analysis-timeout 20m \
  --reach-analysis-memory-limit 32GB \
  --reach-concurrency 4 \
  .
FlagDefaultDescription
--reach-analysis-timeout10mPer-run analysis timeout; specify with a s, m, or h unit (e.g. 90s, 10m, 1h)
--reach-analysis-memory-limit8GBPer-run memory limit; specify with an MB or GB unit (e.g. 512MB, 8GB); 16–32 GB recommended
--reach-concurrency1Parallel workspace processing

Step 4: Compare Results

In Socket Dashboard, view the reachability scan and filter by reachability status.

The CLI outputs a Noise% column directly. You can also calculate manually:

Noise% = ((Unreachable + NoSup + NoReach) / Total Vulns) × 100

The CLI outputs a summary table per ecosystem:

Project                 │ Vulns │ Reach │ Unreach │ NoSup │ NoReach │ Skipped │ Error │ Noise%

Result Categories

ColumnMeaning
ReachCall chain exists from app code to vulnerable function
UnreachNo exploitable call chain; safe to ignore
NoSupSocket hasn't classified the vulnerable functions for this CVE yet
NoReachReachability analysis not possible for this vulnerability
SkippedFiltered out via --exclude-paths or other options
ErrorAnalysis error; check logs or contact support
Noise%Percentage of vulns filtered as non-reachable

In the Dashboard, additional statuses appear: Potentially Reachable (precomputed reachability indirect chain), Pending Precomputation (precomputed reachability processing), Not Determinable, and Unknown.


Step 5: Triage Reachable CVEs

Review CVEs marked as "Reachable" in Dashboard. For each:

  • Check severity and CVSS score
  • Evaluate upgrade path
  • Prioritize remediation

Step 6: Override Unreachable CVEs (Optional)

For unreachable CVEs with low business impact, click Override in Dashboard to suppress from future scans.


Did this page help you?