From ab67a24172e227999b246ed4f62e878cb9978524 Mon Sep 17 00:00:00 2001 From: nscuro Date: Thu, 4 Jun 2026 20:42:00 +0200 Subject: [PATCH 1/3] Document has_package_artifact_hash_mismatch policy function Signed-off-by: nscuro --- .../policies/condition-expressions.md | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/docs/reference/policies/condition-expressions.md b/docs/reference/policies/condition-expressions.md index dcc8b167..1d57e2bb 100644 --- a/docs/reference/policies/condition-expressions.md +++ b/docs/reference/policies/condition-expressions.md @@ -216,6 +216,26 @@ vuln.id == "CVE-2022-41852" }) ``` +### Hash mismatch with the upstream repository + +The following expression matches [Component]s whose declared hashes disagree with the hashes +the upstream package repository reports for the same artifact. Useful for spotting tampered +or mis-pinned components. + +```js linenums="1" +component.has_package_artifact_hash_mismatch() +``` + +To focus on project tagged with `production`: + +```js linenums="1" +"production" in project.tags + && component.has_package_artifact_hash_mismatch() +``` + +See [`has_package_artifact_hash_mismatch`](#has_package_artifact_hash_mismatch) for the matching +table and a note on what a `false` result does and does not mean. + ### Version distance The [`version_distance`](#version_distance) function allows matching based on how far behind a component's version @@ -296,6 +316,46 @@ graph TD !!! tip `project` matches because `baz` exists in its dependency graph. +### `has_package_artifact_hash_mismatch` + +Checks whether a [Component]'s declared hashes disagree with the hashes the upstream +package repository reports for the same artifact. + +The function compares MD5, SHA-1, SHA-256, and SHA-512 (the algorithms package +repositories typically report). All comparisons are case-insensitive. + +| Name | Type | Description | +|:-----------|:------------|:-----------------------| +| *receiver* | [Component] | The component to check | + +**Returns:** `true` if at least one shared algorithm has non-empty values on both sides that +differ. Returns `false` in all other cases, including when no upstream metadata is available +and when there is no shared algorithm to compare. + +```js linenums="1" +component.has_package_artifact_hash_mismatch() +``` + +| Component hashes | Upstream hashes | Result | +|:-------------------------------|:------------------------------------|:--------| +| `sha256: aaa…` | `sha256: aaa…` | `false` | +| `sha256: aaa…` (lowercase) | `sha256: AAA…` (uppercase) | `false` | +| `sha256: aaa…` | `sha256: bbb…` | `true` | +| `sha256: aaa…`, `sha1: 012…` | `sha256: aaa…`, `sha1: ff…` | `true` | +| `sha256: aaa…` | `sha1: 012…` only | `false` | +| `sha256: aaa…` | none reported | `false` | +| `sha3_512: ccc…` only | `sha256: aaa…` | `false` | + +!!! tip + A `false` result does **not** confirm that hashes match. It only means there is no + positive evidence of a mismatch. Components without upstream hash data, or with + no shared algorithm to compare, also return `false`. + +!!! note + Dependency-Track resolves upstream hashes asynchronously. On the first policy evaluation after a BOM + upload they may not be available yet, and the function returns `false`. Later evaluations + pick up the data once resolution completes. + ### `is_dependency_of` Checks whether a [Component] is a (possibly transitive) dependency of another [Component]. From 41e5363012f00323c085e272ac2fd18c410e877a Mon Sep 17 00:00:00 2001 From: Niklas Date: Thu, 4 Jun 2026 21:27:31 +0200 Subject: [PATCH 2/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Niklas --- docs/reference/policies/condition-expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/policies/condition-expressions.md b/docs/reference/policies/condition-expressions.md index 1d57e2bb..97a4da1f 100644 --- a/docs/reference/policies/condition-expressions.md +++ b/docs/reference/policies/condition-expressions.md @@ -226,7 +226,7 @@ or mis-pinned components. component.has_package_artifact_hash_mismatch() ``` -To focus on project tagged with `production`: +To focus on [Project]s tagged as `production`: ```js linenums="1" "production" in project.tags From 2dcc1e17e97916896bd0c46f4fc80214636c1753 Mon Sep 17 00:00:00 2001 From: Niklas Date: Thu, 4 Jun 2026 21:27:41 +0200 Subject: [PATCH 3/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Niklas --- docs/reference/policies/condition-expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/policies/condition-expressions.md b/docs/reference/policies/condition-expressions.md index 97a4da1f..69ae7ec1 100644 --- a/docs/reference/policies/condition-expressions.md +++ b/docs/reference/policies/condition-expressions.md @@ -353,7 +353,7 @@ component.has_package_artifact_hash_mismatch() !!! note Dependency-Track resolves upstream hashes asynchronously. On the first policy evaluation after a BOM - upload they may not be available yet, and the function returns `false`. Later evaluations + upload, they may not be available yet and the function returns `false`. Later evaluations pick up the data once resolution completes. ### `is_dependency_of`