CycloneDX / cdxgen

Creates CycloneDX Bill of Materials (BOM) for your projects from source and container images. Supports many languages and package managers. Integrate in your CI/CD pipeline with automatic submission to Dependency Track server. Google chat: https://chat.google.com/room/AAAA6l2dO60?cls=7
https://cyclonedx.github.io/cdxgen/
Apache License 2.0
577 stars 156 forks source link

Javascript --required-only doesn't include transitive dependencies #164

Closed candrews closed 2 years ago

candrews commented 2 years ago

When using the --required-only option, cdxgen uses babel-parser to find the imports in the source files as described at https://github.com/AppThreat/cdxgen#automatic-usage-detection

The problem is that it doesn't include the dependencies of the dependencies it finds... and it needs to do so as those transitive dependencies are required.

candrews commented 2 years ago

Instead of reinventing yarn/node parsing... what if we use snyk-nodejs-lockfile-parser which already solves these problems and is very well tested?

Package: https://www.npmjs.com/package/snyk-nodejs-lockfile-parser Source: https://github.com/snyk/nodejs-lockfile-parser

prabhu commented 2 years ago

@candrews Every SBoM tool takes a view. I believe "No nuts or gluten" should be left out, especially for node.js. Tools like Snyk simply leave out dev dependencies, assuming those packages would never be deployed. In the real world, most applications are deployed using npm install, which installs dev dependencies. I have seen react and express applications where those packages were declared under "dev dependencies" incorrectly. I have seen applications that do require with a hardcoded path. For this reason, cdxgen tries to do something that no other tool does: properly categorising whether a dependency is required or optional. Thanks to babel, the usage detection of cdxgen outperform many commercial tools.

You can feel free to mix-match SBoM tools to satisfy your specific use case. I hope this helps!

candrews commented 2 years ago

By only including direct dependencies (and excluding the dependencies of those dependencies aka transitive dependencies), an accurate SBOM is not produced 0 "nuts or gluten" are left out.

Let there be packages A, B, and C. A depends on B. The project against which cdxgen expresses dependencies on A and C. The source code of the project imports A; it does not directly import B or C.

Today, the actual situation is that C is not included, which make sense since its not used or transitively referenced. The SBOM only lists A.

The expected SBOM is that A and B should be listed in the SBOM. A because it is imported, B because A depends on B. B is deployed and used at runtime.

prabhu commented 2 years ago

@candrews Do you have any examples of a CVE where the first level indirect dependency was exploited via the direct dependency? Implementing what you are asking requires the entire dependency tree to be retained, which is another large pending ticket. If there are some real-world examples of this, I'm happy to spend some time.

candrews commented 2 years ago

For Javascript, I don't have one off the top of my head, but I'm highly confident they exist.

One I do know off the top of my head is log4shell. A project would depend on something which depends on log4j, and the vulnerability in log4j is exploitable. This example is burned into my memory as it was such a big deal and continues to be a big deal.

prabhu commented 2 years ago

Ok, will implement --no-babel which would satisfy this use case.

prabhu commented 2 years ago

use cdxgen with both --no-babel --required-only to mimic these tools that rely on dev attribute in the lock files.

cdxgen /mnt/work/sandbox/nodejs-goof --no-babel --required-only -p -o /tmp/bom.xml

prabhu commented 2 years ago

4.0.37 includes this feature. Thank you.