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
Add support for detecting dependencies in pnpm-based Node.js projects
when scanning container images.
Problem:
When scanning container images containing pnpm projects (like n8n),
dependencies were not being detected. This is because pnpm stores
packages in a .pnpm/ virtual store directory structure:
node_modules/.pnpm/@/node_modules//package.json
The existing snyk-resolve-deps library expects packages directly at
node_modules// and doesn't understand pnpm's directory layout.
Solution:
Added tryBuildDepGraphFromPnpmStore() as a fallback that:
Detects when .pnpm/ package.json files are present
Parses them directly to extract package names and versions
Builds a dependency graph from those packages
This runs before snyk-resolve-deps and only activates for pnpm projects.
The logic builds a map keyed only by package name and retains only the highest version found in the .pnpm store. Since pnpm relies on installing multiple versions of dependencies to handle conflicts and isolation, this flattening will cause the generated dependency graph to be incorrect. Dependents requiring older versions will be linked to the newer version in the map, potentially masking vulnerabilities or creating invalid dependency chains. The map should support multiple versions per package name.
The recursion limit of 5000 visited nodes is hardcoded. Large projects or monorepos with extensive dependency trees might exceed this limit, resulting in a silently truncated graph. Consider making this configurable or logging a warning if the limit is reached.
Dependencies are wired by looking up the package name in the flattened pnpmPackages map (lines 328-330). This ignores semver requirements defined in the package's dependencies list and the specific resolution path pnpm would have taken (often involving nested node_modules or symlinks). Linking to "whatever version is in the map" creates a potentially inaccurate graph compared to the actual installed tree.
The new tryBuildDepGraphFromPnpmStore function adds all packages found in the .pnpm directory as direct dependencies of the root node (lines 240). This creates a "flat" dependency graph, losing the actual dependency hierarchy.
This has implications for vulnerability remediation advice, as transitive dependencies will appear as direct dependencies. Users might be advised to upgrade packages that are not listed in their package.json. Consider if it's possible to reconstruct the tree or if this trade-off is intentional for this specific analyzer.
The code derives rootManifestPath by performing a regex match on a file path (lines 198-202). Since project (the directory path) is passed as an argument to the function and used to retrieve projectFiles, rootManifestPath could likely be constructed more safely and simply using path.join(project, "package.json"). This assumes project correctly points to the root directory containing the node_modules.
This functionality will essentially give us a flat dependency graph for these pnpm dependencies, because we have no point of reference for where they are coming from, only that they are there. I'll think on this and see if there is a way for us to recreate the actual dep tree, but otherwise I think this is an acceptable tradeoff for now.
The use of hardcoded forward slashes in string includes and regex matchers (lines 191, 198), combined with path.posix.join (line 202), will likely cause this logic to fail on Windows systems where file paths use backslashes. The repository context shows that path (and thus OS-specific separators) is used elsewhere (e.g., lib/analyzer/applications/node.ts:458). Ensure paths are normalized or handled using path.sep to support cross-platform execution.
constpnpmPackageJsons=Array.from(projectFiles).filter((f)=>f.includes("/node_modules/.pnpm/")&&f.endsWith("/package.json"),);if(pnpmPackageJsons.length===0){returnnull;}// Find the root package.json (parent of node_modules/.pnpm)constpnpmMatch=pnpmPackageJsons[0].match(/^(.+?)\/node_modules\/\.pnpm\//);if(!pnpmMatch){returnnull;}constrootManifestPath=path.posix.join(pnpmMatch[1],"package.json");
The current implementation connects all packages found in the .pnpm store directly to the root node (lines 245-246). This creates a flat dependency graph where every package appears as a direct dependency, causing the loss of the actual dependency tree structure (transitive relationships). While this enables detection, it misrepresents the project structure compared to standard graph generation. Consider whether it is feasible to parse the dependencies from each package's manifest to reconstruct the proper tree.
The PR disables variable-name and no-unnecessary-initializer rules globally. Disabling linting rules is generally discouraged unless strictly necessary. Inspect if the new code introduced violations (e.g. redundant initializations) that can be fixed instead of relaxing the project-wide configuration.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
https://snyksec.atlassian.net/browse/CN-612
What does this PR do?
Add support for detecting dependencies in pnpm-based Node.js projects
when scanning container images.
Problem:
When scanning container images containing pnpm projects (like n8n),
dependencies were not being detected. This is because pnpm stores
packages in a .pnpm/ virtual store directory structure:
node_modules/.pnpm/@/node_modules//package.json
The existing snyk-resolve-deps library expects packages directly at
node_modules// and doesn't understand pnpm's directory layout.
Solution:
Added tryBuildDepGraphFromPnpmStore() as a fallback that:
This runs before snyk-resolve-deps and only activates for pnpm projects.