@cyclonedx/cdxgen
Version:
Creates CycloneDX Software Bill of Materials (SBOM) from source or container image
344 lines (329 loc) • 13.8 kB
YAML
# Package Integrity and Lifecycle Rules
# Category: package-integrity
# Detects deprecated, yanked, or tampered packages and suspicious metadata
- id: INT-001
name: "npm package with install script"
description: "npm packages with lifecycle hooks (preinstall, postinstall, etc.) execute arbitrary code during installation"
severity: medium
category: package-integrity
dry-run-support: full
condition: |
components[
$prop($, 'cdx:npm:hasInstallScript') = 'true'
]
location: |
{ "bomRef": $."bom-ref", "purl": purl }
message: "npm package '{{ name }}@{{ version }}' has install-time execution hooks"
mitigation: "Review install scripts before use. Consider using --ignore-scripts or an allowlist-based approach"
evidence: |
{
"riskyScripts": $prop($, 'cdx:npm:risky_scripts'),
"isRegistryDependency": $prop($, 'cdx:npm:isRegistryDependency')
}
- id: INT-002
name: "npm package name or version mismatch"
description: "Detected mismatch between expected and resolved package name or version, which may indicate dependency confusion or tampering"
severity: high
category: package-integrity
dry-run-support: full
condition: |
components[
$hasProp($, 'cdx:npm:nameMismatchError')
or $hasProp($, 'cdx:npm:versionMismatchError')
]
location: |
{ "bomRef": $."bom-ref", "purl": purl }
message: "npm package '{{ name }}@{{ version }}' has a name or version mismatch"
mitigation: "Investigate the mismatch immediately. This may indicate dependency confusion, registry tampering, or a corrupted lockfile"
evidence: |
{
"nameMismatch": $prop($, 'cdx:npm:nameMismatchError'),
"versionMismatch": $prop($, 'cdx:npm:versionMismatchError')
}
- id: INT-003
name: "Deprecated Go module"
description: "Go modules marked as deprecated may contain known issues or be abandoned"
severity: medium
category: package-integrity
dry-run-support: no
condition: |
components[
$hasProp($, 'cdx:go:deprecated')
]
location: |
{ "bomRef": $."bom-ref", "purl": purl }
message: "Go module '{{ name }}' is deprecated: {{ $prop($, 'cdx:go:deprecated') }}"
mitigation: "Migrate to the recommended replacement module or assess continued usage risk"
evidence: |
{
"deprecationNotice": $prop($, 'cdx:go:deprecated'),
"isIndirect": $prop($, 'cdx:go:indirect')
}
- id: INT-004
name: "Yanked Ruby gem in dependency tree"
description: "Yanked gems have been removed from RubyGems, typically due to security issues or critical bugs"
severity: high
category: package-integrity
dry-run-support: no
condition: |
components[
$prop($, 'cdx:gem:yanked') = 'true'
]
location: |
{ "bomRef": $."bom-ref", "purl": purl }
message: "Ruby gem '{{ name }}@{{ version }}' has been yanked from RubyGems"
mitigation: "Update to a non-yanked version immediately. Yanked gems are typically removed due to security or correctness issues"
evidence: |
{
"platform": $prop($, 'cdx:gem:platform'),
"isPrerelease": $prop($, 'cdx:gem:prerelease')
}
- id: INT-005
name: "npm deprecated package"
description: "npm packages marked as deprecated may have known vulnerabilities or unmaintained code"
severity: low
category: package-integrity
dry-run-support: partial
condition: |
components[
$prop($, 'cdx:npm:deprecated') = 'true'
]
location: |
{ "bomRef": $."bom-ref", "purl": purl }
message: "npm package '{{ name }}@{{ version }}' is deprecated: {{ $prop($, 'cdx:npm:deprecation_notice') }}"
mitigation: "Migrate to a maintained alternative package"
evidence: |
{
"deprecationNotice": $prop($, 'cdx:npm:deprecation_notice')
}
- id: INT-006
name: "Dart pub uses non-default registry"
description: "Dart packages from non-default registries may introduce unvetted code"
severity: low
category: package-integrity
dry-run-support: full
condition: |
components[
$hasProp($, 'cdx:pub:registry')
]
location: |
{ "bomRef": $."bom-ref", "purl": purl }
message: "Dart package '{{ name }}' sourced from non-default registry: {{ $prop($, 'cdx:pub:registry') }}"
mitigation: "Verify registry trustworthiness"
evidence: |
{
"registry": $prop($, 'cdx:pub:registry')
}
- id: INT-007
name: "Maven shaded/relocated package"
description: "Maven packages with shaded or relocated classes may obscure the true dependency graph and introduce hidden vulnerabilities"
severity: low
category: package-integrity
dry-run-support: full
condition: |
components[
$prop($, 'cdx:maven:shaded') = 'true'
]
location: |
{ "bomRef": $."bom-ref", "purl": purl }
message: "Maven package '{{ name }}@{{ version }}' contains shaded/relocated classes"
mitigation: "Prefer non-shaded dependency variants where available to maintain transparent dependency resolution"
evidence: |
{
"unshadedNamespaces": $prop($, 'cdx:maven:unshadedNamespaces'),
"scope": $prop($, 'cdx:maven:component_scope')
}
- id: INT-008
name: "README file contains hidden Unicode characters"
description: "Hidden Unicode in README files can conceal malicious or misleading content in code review, especially inside comments"
severity: medium
category: package-integrity
dry-run-support: full
condition: |
formulation.components[
$prop($, 'cdx:file:kind') = 'readme'
and $prop($, 'cdx:file:hasHiddenUnicode') = 'true'
]
location: |
{
"bomRef": $."bom-ref",
"file": $prop($, 'SrcFile')
}
message: "README file '{{ name }}' contains hidden Unicode characters"
mitigation: "Review the file with hidden-character rendering enabled, remove suspicious bidirectional or zero-width characters, and verify comment blocks carefully before merge"
evidence: |
{
"codePoints": $prop($, 'cdx:file:hiddenUnicodeCodePoints'),
"lineNumbers": $prop($, 'cdx:file:hiddenUnicodeLineNumbers'),
"inComments": $prop($, 'cdx:file:hiddenUnicodeInComments')
}
- id: INT-009
name: "npm lifecycle hook contains obfuscated or encoded execution"
description: "Lifecycle hooks that decode base64 payloads, hide long encoded blobs, or blend obfuscation with install-time execution are high-confidence supply-chain abuse indicators"
severity: critical
category: package-integrity
dry-run-support: full
attack:
tactics: [TA0005]
techniques: [T1027]
condition: |
components[
$prop($, 'cdx:npm:hasObfuscatedLifecycleScript') = 'true'
]
location: |
{ "bomRef": $."bom-ref", "purl": purl }
message: "npm package '{{ name }}@{{ version }}' contains obfuscated install-time lifecycle scripts '{{ $prop($, 'cdx:npm:obfuscatedLifecycleScripts') }}'"
mitigation: "Treat encoded or obfuscated lifecycle hooks as suspicious by default. Review the decoded payload, inspect any referenced script files, and avoid installing until provenance and maintainer intent are verified"
evidence: |
{
"scripts": $prop($, 'cdx:npm:obfuscatedLifecycleScripts'),
"obfuscationIndicators": $prop($, 'cdx:npm:lifecycleObfuscationIndicators'),
"executionIndicators": $prop($, 'cdx:npm:lifecycleExecutionIndicators'),
"indicatorMap": $prop($, 'cdx:npm:lifecycleIndicatorMap')
}
- id: INT-010
name: "Yanked Cargo crate in dependency tree"
description: "Crates yanked from crates.io are often removed because of security, correctness, or ecosystem breakage issues"
severity: high
category: package-integrity
dry-run-support: no
condition: |
components[
$prop($, 'cdx:cargo:yanked') = 'true'
]
location: |
{ "bomRef": $."bom-ref", "purl": purl }
message: "Cargo crate '{{ name }}@{{ version }}' has been yanked from crates.io"
mitigation: "Update to a non-yanked release and review any recent publisher or release-cadence changes before upgrading"
evidence: |
{
"publisher": $prop($, 'cdx:cargo:publisher'),
"priorPublisher": $prop($, 'cdx:cargo:priorPublisher'),
"publishTime": $prop($, 'cdx:cargo:publishTime'),
"releaseGapDays": $prop($, 'cdx:cargo:releaseGapDays')
}
- id: INT-011
name: "Rust project uses native Cargo build surface"
description: "Cargo build scripts and native build helpers expand execution surface during build and deserve additional review before release"
severity: medium
category: package-integrity
dry-run-support: full
condition: |
formulation.components[
$prop($, 'cdx:rust:buildTool') = 'cargo'
and $prop($, 'cdx:cargo:hasNativeBuild') = 'true'
]
location: |
{
"bomRef": $."bom-ref",
"file": $prop($, 'SrcFile')
}
message: "Rust project '{{ name }}' uses Cargo build.rs or native build helpers"
mitigation: "Review `build.rs`, native build dependencies, and release workflows to ensure the build remains hermetic and expected"
evidence: |
{
"buildScript": $prop($, 'cdx:cargo:buildScript'),
"nativeBuildIndicators": $prop($, 'cdx:cargo:nativeBuildIndicators'),
"releaseProfiles": $prop($, 'cdx:cargo:releaseProfiles')
}
- id: INT-012
name: "Rust native build uses mutable Cargo setup action"
description: "Native Cargo build surfaces deserve additional scrutiny when the workflow relies on mutable Cargo toolchain setup actions instead of immutable SHA-pinned references"
severity: medium
category: package-integrity
dry-run-support: full
condition: |
formulation.components[
$prop($, 'cdx:rust:buildTool') = 'cargo'
and $prop($, 'cdx:cargo:hasNativeBuild') = 'true'
and $count($$.components[
$prop($, 'cdx:github:action:ecosystem') = 'cargo'
and $contains($prop($, 'cdx:github:action:role'), 'toolchain')
and $prop($, 'cdx:github:action:versionPinningType') != 'sha'
]) > 0
]
location: |
{
"bomRef": $."bom-ref",
"file": $prop($, 'SrcFile')
}
message: "Rust project '{{ name }}' combines native Cargo build surfaces with mutable Cargo toolchain setup actions"
mitigation: "Prefer SHA-pinned Cargo toolchain setup actions for release workflows, especially when build.rs or native helpers run during CI"
evidence: |
{
"buildScript": $prop($, 'cdx:cargo:buildScript'),
"buildScriptCapabilities": $prop($, 'cdx:cargo:buildScriptCapabilities'),
"toolchainActions": $$.components[
$prop($, 'cdx:github:action:ecosystem') = 'cargo'
and $contains($prop($, 'cdx:github:action:role'), 'toolchain')
and $prop($, 'cdx:github:action:versionPinningType') != 'sha'
].$prop($, 'cdx:github:action:uses')
}
- id: INT-013
name: "Rust native build is exercised by Cargo workflow steps"
description: "Cargo workflows that execute build/test/package/publish steps against native build surfaces increase the impact of build-script or native-helper changes"
severity: medium
category: package-integrity
dry-run-support: full
condition: |
formulation.components[
$prop($, 'cdx:rust:buildTool') = 'cargo'
and $prop($, 'cdx:cargo:hasNativeBuild') = 'true'
and (
$contains($prop($, 'cdx:cargo:buildScriptCapabilities'), 'process-execution')
or $contains($prop($, 'cdx:cargo:buildScriptCapabilities'), 'network-access')
or $contains($prop($, 'cdx:cargo:nativeBuildIndicators'), '-sys')
)
and $count($$.components[
$prop($, 'cdx:github:step:usesCargo') = 'true'
and (
$contains($prop($, 'cdx:github:step:cargoSubcommands'), 'build')
or $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'test')
or $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'package')
or $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'publish')
)
]) > 0
]
location: |
{
"bomRef": $."bom-ref",
"file": $prop($, 'SrcFile')
}
message: "Rust project '{{ name }}' runs Cargo build/test/package workflow steps against a native build surface"
mitigation: "Review build.rs, native helper crates, and workflow command scope before merging or publishing releases that exercise native build logic"
evidence: |
{
"buildScriptCapabilities": $prop($, 'cdx:cargo:buildScriptCapabilities'),
"nativeBuildIndicators": $prop($, 'cdx:cargo:nativeBuildIndicators'),
"cargoCommands": $$.components[
$prop($, 'cdx:github:step:usesCargo') = 'true'
and (
$contains($prop($, 'cdx:github:step:cargoSubcommands'), 'build')
or $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'test')
or $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'package')
or $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'publish')
)
].$prop($, 'cdx:github:step:command')
}
- id: INT-014
name: "Collider package missing valid wrap hash pin"
description: "Collider lock entries should carry a SHA-256 wrap_hash so the selected wrap file remains integrity-pinned and reproducible"
severity: high
category: package-integrity
dry-run-support: full
condition: |
components[
$hasProp($, 'cdx:collider:dependencyKind')
and $prop($, 'cdx:collider:hasWrapHash') = 'false'
]
location: |
{ "bomRef": $."bom-ref", "purl": purl }
message: "Collider package '{{ name }}@{{ version }}' is missing a valid wrap hash integrity pin"
mitigation: "Recreate collider.lock with valid wrap_hash values and verify the lockfile against the repository before release"
evidence: |
{
"wrapHash": $prop($, 'cdx:collider:wrapHash'),
"wrapHashInvalid": $prop($, 'cdx:collider:wrapHashInvalid'),
"origin": $prop($, 'cdx:collider:origin'),
"dependencyKind": $prop($, 'cdx:collider:dependencyKind')
}