Skip to content

fix: dockerfile attribution#766

Open
d3vco wants to merge 17 commits intomainfrom
fix/dockerfile-attribution
Open

fix: dockerfile attribution#766
d3vco wants to merge 17 commits intomainfrom
fix/dockerfile-attribution

Conversation

@d3vco
Copy link
Copy Markdown
Contributor

@d3vco d3vco commented Mar 3, 2026

  • Ready for review
  • Follows CONTRIBUTING rules
  • Reviewed by Snyk internal team

What does this PR do?

This PR fixes 2 related issues:

  1. --exclude-base-image-vulns has been disabled in SDP resulting in the flag not being effective in container monitor mode.
  2. The logic to identify dockerfile-introduced dependencies under-attributes dependencies to the dockerfile. This resulted in vulnerabilities incorrectly being filtered as "base image vulns" and missing dockerfile instruction labels.

Where should the reviewer start?

buildResponse orchestration

  • Removed collectDockerfilePkgs, logic is inlined.
  • Expands both versions of dockerfile packages using getUserInstructionDeps up front (in place)
  • Derives dockerfilePkgs as dockerfileAnalysis?.dockerfilePackages ?? autoDetected…dockerfilePackages and uses the result to conduct annotation and exclusion (matches CLI logic).
  • Stores the result of filtering and annotation! (depsAnalysis.depTree.dependencies = finalDeps)

excludeBaseImageDeps

  • Removed extractDockerfileDeps, filtering is inlined.
  • Conducts matching on full name OR source segment. (On main, only exact keys matched)

annotateLayerIds

  • Conducts matching on full name OR source segment.

How should this be manually tested?

Unit tests have been added to demonstrate the new behavior.

The changes are most easily observed in monitor mode. Creating a small image with packages installed via a run instruction should show those dependencies attributed to the install instruction. Any base image vulns should be filterable, in test or monitor mode.

An example is shown below.

Any background context you want to provide?

More context provided in this write-up.

What are the relevant tickets?

Screenshots

Current Behavior:
Screenshot 2026-02-27 at 11 44 13 AM

PR Behavior:
Screenshot 2026-02-27 at 11 44 56 AM

@d3vco d3vco requested a review from a team as a code owner March 3, 2026 18:46
@d3vco d3vco requested a review from mtstanley-snyk March 3, 2026 18:46
d3vco added 8 commits March 5, 2026 15:26
This version of resolving the dockerfile attribution bug does
so with a reduced impact on the downstream CLI and registry logic.
It does so by expanding both the dockerfile packages and auto-detected
packages, ensuring those facts retain the same intent.

Internal to snyk-docker-plugin, dependencies are always referenced by
full name (i.e. zlib/zlib) when it is available, preventing earlier
bugs caused by splitting the source segment of the name.
@snyk-pr-review-bot

This comment has been minimized.

@snyk-pr-review-bot

This comment has been minimized.

@snyk-pr-review-bot

This comment has been minimized.

@d3vco d3vco force-pushed the fix/dockerfile-attribution branch from 61543fc to 7349c56 Compare March 19, 2026 15:25
@snyk-pr-review-bot

This comment has been minimized.

@d3vco
Copy link
Copy Markdown
Contributor Author

d3vco commented Mar 19, 2026

snyk-pr-review-bot's "Inconsistent Legacy Compatibility" comment is incorrect. The legacy expansion for autoDetectedUserInstructions is conducted on line 214

@snyk-pr-review-bot

This comment has been minimized.

@snyk-pr-review-bot

This comment has been minimized.

@snyk-pr-review-bot

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@mtstanley-snyk mtstanley-snyk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couple comments/qs, otherwise lgtm 🎉. Did we decide on a rollout for this? If not, might be worth a short section in your doc on impact and then can start a thread with team on breaking vs non-breaking change.

My understanding of the impact is:

  1. no(?) change to snyk container test
  2. snyk container monitor -- exclude-base-... now excludes things, whereas before the command would have run but not excluded anything
  3. monitored container projects from CLI where dockerfile was provided would now attribute a lot more vulns to user installed
  4. monitored container projects from CLI without dockerfile should be no(?) change

Mock analysis incorrectly had a second dummy node added as a dependency
of the root node.
@snyk-pr-review-bot
Copy link
Copy Markdown

PR Reviewer Guide 🔍

🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Over-attribution Bug 🟠 [major]

The combination of transitive dependency expansion in getUserInstructionDeps and source-segment matching in excludeBaseImageDeps (lines 419-424) leads to significant over-attribution of vulnerabilities to the Dockerfile. Any package in the base image that shares a source segment (the prefix before '/') with any transitive dependency of any package installed in the Dockerfile will be incorrectly marked as Dockerfile-introduced. This effectively bypasses the --exclude-base-image-vulns filter for those packages, resulting in noisy reports. While documented as a 'Known Issue' in the code, the change in matching logic from exact names to source-segment prefixes significantly escalates the frequency of this error.

return Object.keys(deps)
  .filter((depName) => {
    if (dockerfilePkgs[depName] !== undefined) {
      return true;
    }
    const source = depName.split("/")[0];
    return dockerfilePkgs[source] !== undefined;
  })
In-place Mutation 🟡 [minor]

The buildResponse function now mutates the dockerfileAnalysis and depsAnalysis input objects in-place (lines 33-41 and 54). While buildResponse is the final step in the current analyzeStatically pipeline (see lib/static.ts), this side effect may cause issues if these objects are reused for logging, caching, or by other callers in the future. Explicit cloning or returning new objects would be safer.

  getUserInstructionDeps(dockerfileAnalysis.dockerfilePackages, deps);
}
if (depsAnalysis.autoDetectedUserInstructions?.dockerfilePackages) {
  getUserInstructionDeps(
    depsAnalysis.autoDetectedUserInstructions.dockerfilePackages,
    deps,
  );
}

const dockerfilePkgs =
  dockerfileAnalysis?.dockerfilePackages ??
  depsAnalysis.autoDetectedUserInstructions?.dockerfilePackages;

if (dockerfilePkgs) {
  const finalDeps = excludeBaseImageDeps(
    deps,
    dockerfilePkgs,
    excludeBaseImageVulns,
  );
  annotateLayerIds(finalDeps, dockerfilePkgs);
  depsAnalysis.depTree.dependencies = finalDeps;
📚 Repository Context Analyzed

This review considered 18 relevant code sections from 10 files (average relevance: 0.87)

@d3vco
Copy link
Copy Markdown
Contributor Author

d3vco commented Mar 30, 2026

couple comments/qs, otherwise lgtm 🎉. Did we decide on a rollout for this? If not, might be worth a short section in your doc on impact and then can start a thread with team on breaking vs non-breaking change.

My understanding of the impact is:

  1. no(?) change to snyk container test
  2. snyk container monitor -- exclude-base-... now excludes things, whereas before the command would have run but not excluded anything
  3. monitored container projects from CLI where dockerfile was provided would now attribute a lot more vulns to user installed
  4. monitored container projects from CLI without dockerfile should be no(?) change

Doc has been updated to start the rollout discussion.

On # 4 above, monitored container projects without dockerfile will also see an increase in vulns attributed to the dockerfile. Previously there was no path to attribute vulns to the dockerfile, now autoDetectedUserInstructions get the same treatment as those direct from the Dockerfile.

Also, the impact would not be limited to the CLI assuming DRA and kubernetes-monitor also uses the new version of SDP.

@mtstanley-snyk
Copy link
Copy Markdown
Contributor

Changes lgtm, let's confirm the rollout plan here and then I'll 🚢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants