You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 9bc091c
Browse filesBrowse the repository at this point in the historyBrowse files
PM-4777: Report declared and transitive dependencies from embedded poms
Adds three opt-in flags to `scan binary` and `report sbom binary`:
- `--include-declared` reads every embedded pom.xml the way Maven does
(properties, ${project.*}, the parent chain, dependencyManagement with
imported BOMs, dependencies inherited from parents) and reports the
compile- and runtime-scope dependencies the artifact does not ship as
components marked `declared`, with no hashes and the declaring pom as
their path. Test, provided, system and optional are left out because
Maven never hands them to a consumer.
- `--include-test-scope` lifts that filter so totals line up with SCA
tools that count every declared dependency. Scope stays on each
component.
- `--include-transitive` follows each declared dependency through its
own pom on Maven Central: nearest declaration wins, exclusions apply
down their branch, optional stops, scope combines per Maven's table,
and the root pom's management overrides transitive versions. Each
transitive records what pulled it in (`cycode:via`) and the graph
links them. Bounded to 10 hops and 250 poms per embedded pom.
Parent and dependency poms come from repo1.maven.org behind a PomSource
seam, so `--maven-central` is required for parent-managed versions and
for transitives. Coordinates read from an untrusted pom are validated
before they can shape a URL, and bodies are capped at 1 MB. A version
that cannot be established is listed under "Declared, version
unresolved" with the reason, never guessed.
Motivation: a customer's Checkmarx report on 16 vendor jars listed 29
vulnerabilities, every one on a declared-but-unshipped dependency. With
all three flags Cycode reports all 61 of those declared packages and 30
findings; the difference is vulnerability-database content only.
Claude-Session: https://claude.ai/code/session_016SxZLL1buHZ8jZ9T8onEZ8
1.[Commit Range Option (Diff Scanning)](#commit-range-option-diff-scanning)
56
57
6.[Pre-Commit Scan](#pre-commit-scan)
@@ -1051,7 +1052,10 @@ Nested archives are opened recursively, so a JAR inside a WAR inside an EAR is s
1051
1052
|---|---|---|
1052
1053
|`--max-depth`|`3`| Nested-archive recursion limit. An EAR containing WARs containing JARs is depth 3. |
1053
1054
|`--offline`| off | Identify components from embedded metadata only. Acknowledges and silences the partial-results warning. |
1054
-
|`--maven-central`| off | Look up archives that embedded metadata cannot identify on Maven Central by SHA-1. Sends only the digest, never the archive. Cannot be combined with `--offline`. |
1055
+
|`--maven-central`| off | Consult Maven Central: look up archives that embedded metadata cannot identify by SHA-1, and with `--include-declared` fetch parent poms to pin declared versions. Sends digests and public coordinates, never the archive. Cannot be combined with `--offline`. |
1056
+
|`--include-declared`| off | Also report the compile- and runtime-scope dependencies that embedded `pom.xml` files declare but the artifact does not ship. See [Declared Dependencies](#declared-dependencies). |
1057
+
|`--include-test-scope`| off | With `--include-declared`: also report test-, provided- and system-scope declarations, which never reach a consuming build. Matches SCA tools that count every declared dependency. |
1058
+
|`--include-transitive`| off | With `--include-declared` and `--maven-central`: follow each declared dependency through its own pom to the dependencies it needs in turn, the way a Maven build would. |
1055
1059
|`--project-name`| inferred | Override the platform identity when the artifact is detached from its source repository. |
1056
1060
|`--keep-bom`| off | Write the generated component inventory beside each artifact, for inspection or audit. |
1057
1061
|`--include-binaries`| off | On `scan path` only. Extract any Java archives encountered during the walk. |
@@ -1095,6 +1099,52 @@ We do not guess a component's identity from its filename.
1095
1099
`internal-shim.jar` is not evidence of anything, and an admitted gap is more useful than an invented coordinate.
1096
1100
Unidentified components do not set the exit code on their own.
1097
1101
1102
+
#### Declared Dependencies
1103
+
1104
+
By default a binary scan reports what is physically inside the artifact.
1105
+
That is the right answer for a deployable, but it is not the only question worth asking of a library JAR.
1106
+
A build that consumes that JAR inherits its compile- and runtime-scope dependencies, whether or not the vendor shipped them, and a vulnerability in one of those is real in the consuming build.
1107
+
1108
+
`--include-declared` answers that second question from the same embedded metadata:
Every embedded `pom.xml` is read the way Maven reads it.
1113
+
Each dependency it declares at `compile` or `runtime` scope, and which is not already present in the artifact, is added to the component inventory as a **declared** component and scanned like any other.
1114
+
Dependencies Maven would never hand to a consumer are left out: `test`, `provided` and `system` scope, and anything marked `optional`.
1115
+
1116
+
Some SCA tools count every declared dependency regardless of scope, so their totals include a vendor's own test libraries.
1117
+
To compare against such a report, add `--include-test-scope` and those declarations are reported too.
1118
+
Each declared component still records its scope, so a `test` finding can be told apart from one that reaches a build.
1119
+
1120
+
Versions in a real pom are rarely literal.
1121
+
`${property}` references and `${project.version}` are resolved from the pom itself.
1122
+
A version managed by a parent pom, or by an imported BOM, lives on Maven Central rather than inside the JAR, so resolving it needs `--maven-central`.
1123
+
Without it, or when the parent cannot be fetched, the dependency is listed in its own section with the reason instead of being guessed at:
1124
+
1125
+
```
1126
+
╭─ 📜 Declared, version unresolved (2) ──────────────────────────────────────────────╮
1127
+
│ Dependency Version Declared by Why │
1128
+
│ commons-logging:commons-log… - woden-core.jar > META-INF/… no version … │
A finding on a declared component says `Declared by` and the pom that made the claim, rather than `Found in`, and its presence is marked `declared`in the generated BOM.
1135
+
Declared components carry no hashes, because there are no bytes to digest.
1136
+
`--output json` reports the counts under `binary.declared`.
1137
+
1138
+
A declared dependency has dependencies of its own.
1139
+
`--include-transitive` follows each one through its pom on Maven Central and reports what it needs in turn, so it requires `--maven-central`.
1140
+
The walk follows Maven's rules: the nearest declaration of a coordinate wins, exclusions apply down their branch, optional dependencies are not followed, and a transitive's scope is combined with the scope it was reached through, so a test dependency's tree stays test scope.
1141
+
Each transitive component records the dependency that pulled it in as `cycode:via`, and the dependency graph in the BOM links them.
1142
+
On a real vendor jar this typically fetches a few dozen poms and adds under a minute to the scan.
1143
+
1144
+
> [!NOTE]
1145
+
> Version ranges and versions that only a repository's metadata could pin are listed as unresolved, never guessed.
1146
+
> Where the consuming build exists, scanning its output or its `pom.xml` remains the most exact answer: a build tool resolves profiles and repository settings this walk cannot see.
1147
+
1098
1148
#### Binary Scan Limitations
1099
1149
1100
1150
Read this before relying on a binary scan as your only check.
@@ -1702,9 +1752,13 @@ It uses the same extraction as [Binary Scan](#binary-scan), so the [limitations]
1702
1752
1703
1753
The `binary` subcommand supports the following additional option:
|`--max-depth`| Nested-archive recursion limit. Defaults to 3. An EAR containing WARs containing JARs is depth 3. |
1758
+
|`--maven-central`| Consult Maven Central to identify archives by SHA-1 and, with `--include-declared`, to fetch parent poms. |
1759
+
|`--include-declared`| Also include the compile- and runtime-scope dependencies that embedded `pom.xml` files declare but the artifact does not ship, marked `declared` rather than `shipped`. See [Declared Dependencies](#declared-dependencies). |
1760
+
|`--include-test-scope`| With `--include-declared`: also include test-, provided- and system-scope declarations. |
1761
+
|`--include-transitive`| With `--include-declared` and `--maven-central`: follow each declared dependency to what its own pom needs. |
0 commit comments