8000 Create utility for generating SBOM from artifacts by sethmlarson · Pull Request #82 · python/release-tools · GitHub
[go: up one dir, main page]

Skip to content

Create utility for generating SBOM from artifacts #82

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 6, 2024

Conversation

sethmlarson
Copy link
Collaborator
@sethmlarson sethmlarson commented Jan 10, 2024

Part of python/cpython#112302

So this is a decent amount of code to review, but it does indeed check all the boxes that I want SBOMs for source tarball artifacts to check. This likely won't be the final state of this module, I think the end-goal is to stitch it in to the release process in various points.

You can see the generated SBOM in this Gist: https://gist.github.com/sethmlarson/103891c6cac4d41b11daab89e6c84868

NOTE: that I had to modify the 3.13.0a2 tarball by adding a Misc/sbom.spdx.json file into the archive. 3.13.0a3 will be the first release which contains the base SBOM file in the tarball.

Here are the criteria the generated SBOM meets:

  • Meets NTIA minimum elements
  • Matches SPDX 2.3 JSON schema
  • Grype is able to use the SBOM and find vulnerabilities
  • Scores 9.6 out of 10 on SBOM Quality, and the only metric is one we can't improve on our own (multiple IDs per package)
$ grype sbom:./Python-3.13.0a2.tgz.spdx.json 
 ✔ Vulnerability DB                [no update available]  
 ✔ Scanned for vulnerabilities     [3 vulnerability matches]  
   ├── by severity: 0 critical, 1 high, 1 medium, 1 low, 0 negligible
   └── by status:   1 fixed, 2 not-fixed, 0 ignored 
[0000]  WARN some package(s) are missing CPEs. This may result in missing vulnerabilities. You may autogenerate these using: --add-cpes-if-none
NAME  INSTALLED  FIXED-IN  TYPE    VULNERABILITY        SEVERITY 
pip   23.2.1               python  CVE-2018-20225       High      
pip   23.2.1     23.3      python  GHSA-mq26-g339-26xf  Medium    
pip   23.2.1               python  CVE-2023-5752        Low
$ sbomqs score Python-3.13.0a2.tgz.spdx.json 

SBOM Quality Score:9.6	components:7	Python-3.13.0a2.tgz.spdx.json 
+-----------------------+--------------------------------+-----------+--------------------------------+
|       CATEGORY        |            FEATURE             |   SCORE   |              DESC              |
+-----------------------+--------------------------------+-----------+--------------------------------+
| NTIA-minimum-elements | comp_with_name                 | 10.0/10.0 | 7/7 have names                 |
+                       +--------------------------------+-----------+--------------------------------+
|                       | comp_with_supplier             | 10.0/10.0 | 7/7 have supplier names        |
+                       +--------------------------------+-----------+--------------------------------+
|                       | comp_with_uniq_ids             | 10.0/10.0 | 7/7 have unique ID's           |
+                       +--------------------------------+-----------+--------------------------------+
|                       | comp_with_version              | 10.0/10.0 | 7/7 have versions              |
+                       +--------------------------------+-----------+--------------------------------+
|                       | sbom_authors                   | 10.0/10.0 | doc has 2 authors              |
+                       +--------------------------------+-----------+--------------------------------+
|                       | sbom_creation_timestamp        | 10.0/10.0 | doc has creation timestamp     |
|                       |                                |           | 2024-01-10T22:08:42Z           |
+                       +--------------------------------+-----------+--------------------------------+
|                       | sbom_dependencies              | 10.0/10.0 | doc has 4422 relationships     |
+-----------------------+--------------------------------+-----------+--------------------------------+
| Quality               | comp_valid_licenses            | 10.0/10.0 | 7/7 components with valid      |
|                       |                                |           | license                        |
+                       +--------------------------------+-----------+--------------------------------+
|                       | comp_with_any_vuln_lookup_id   | 10.0/10.0 | 7/7 components have any lookup |
|                       |                                |           | id                             |
+                       +--------------------------------+-----------+--------------------------------+
|                       | comp_with_deprecated_licenses  | 10.0/10.0 | 0/7 components have deprecated |
|                       |                                |           | licenses                       |
+                       +--------------------------------+-----------+--------------------------------+
|                       | comp_with_multi_vuln_lookup_id | 1.4/10.0  | 1/7 components have multiple   |
|                       |                                |           | lookup id                      |
+                       +--------------------------------+-----------+--------------------------------+
|                       | comp_with_primary_purpose      | 10.0/10.0 | 7/7 components have primary    |
|                       |                                |           | purpose specified              |
+                       +--------------------------------+-----------+--------------------------------+
|                       | comp_with_restrictive_licenses | 10.0/10.0 | 0/7 components have restricted |
|                       |                                |           | licenses                       |
+                       +--------------------------------+-----------+--------------------------------+
|                       | sbom_with_creator_and_version  | 10.0/10.0 | 1/1 tools have creator and     |
|                       |                                |           | version                        |
+                       +--------------------------------+-----------+--------------------------------+
|                       | sbom_with_primary_component    | 10.0/10.0 | primary component found        |
+-----------------------+--------------------------------+-----------+--------------------------------+
| Semantic              | comp_with_checksums            | 10.0/10.0 | 7/7 have checksums             |
+                       +--------------------------------+-----------+--------------------------------+
|                       | comp_with_licenses             | 10.0/10.0 | 7/7 have licenses              |
+                       +--------------------------------+-----------+--------------------------------+
|                       | sbom_required_fields           | 10.0/10.0 | Doc Fields:true Pkg            |
|                       |                                |           | Fields:true                    |
+-----------------------+--------------------------------+-----------+--------------------------------+
| Sharing               | sbom_sharable                  | 10.0/10.0 | doc has a sharable license     |
|                       |                                |           | free 1 :: of 1                 |
+-----------------------+--------------------------------+-----------+--------------------------------+
| Structural            | sbom_parsable                  | 10.0/10.0 | provided sbom is parsable      |
+                       +--------------------------------+-----------+--------------------------------+
|                       | sbom_spec                      | 10.0/10.0 | provided sbom is in a          |
|                       |                                |           | supported sbom format of       |
|                       |                                |           | spdx,cyclonedx                 |
+                       +--------------------------------+-----------+--------------------------------+
|                       | sbom_spec_file_format          | 10.0/10.0 | provided sbom should be in     |
|                       |                                |           | supported file format for      |
|                       |                                |           | spec: json and version:        |
|                       |                                |           | json,yaml,rdf,tag-value        |
+                       +--------------------------------+-----------+--------------------------------+
|                       | sbom_spec_version              | 10.0/10.0 | provided sbom should be in     |
|                       |                                |           | supported spec version for     |
|                       |                                |           | spec:SPDX-2.3 and versions:    |
|                       |                                |           | SPDX-2.1,SPDX-2.2,SPDX-2.3     |
+-----------------------+--------------------------------+-----------+--------------------------------+

@hugovk
Copy link
Member
hugovk commented Jan 11, 2024

How should this be run?

❯ p sbom.py
Traceback (most recent call last):
  File "/Users/hugo/github/release-tools/sbom.py", line 274, in <module>
    tarball_path = sys.argv[1]
                   ~~~~~~~~^^^
IndexError: list index out of range

❯ p sbom.py -h
Traceback (most recent call last):
  File "/Users/hugo/github/release-tools/sbom.py", line 277, in <module>
    create_sbom_for_source_tarball(tarball_path), indent=2, sort_keys=True
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hugo/github/release-tools/sbom.py", line 103, in create_sbom_for_source_tarball
    raise ValueError(f"Unknown tarball format: '{tarball_name}'")
ValueError: Unknown tarball format: '-h'

❯ p sbom.py /tmp/downloads/Python-3.13.0a2.tgz
Traceback (most recent call last):
  File "/Users/hugo/github/release-tools/sbom.py", line 277, in <module>
    create_sbom_for_source_tarball(tarball_path), indent=2, sort_keys=True
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hugo/github/release-tools/sbom.py", line 117, in create_sbom_for_source_tarball
    sbom_bytes = tarball.extractfile(tarball.getmember("Misc/sbom.spdx.json")).read()
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/tarfile.py", line 1984, in getmember
    raise KeyError("filename %r not found" % name)
KeyError: "filename 'Misc/sbom.spdx.json' not found"

I got a similar KeyError running from the CPython repo.

@sethmlarson
Copy link
Collaborator Author

@hugovk Sorry for sending you on a wild goose chase! I actually had to modify the 3.13.0a2 release tarball by adding the Misc/sbom.spdx.json file into the archive in order to test the tool. 3.13.0a3 will be the first actual CPython release that has the source tree dependencies SBOM. I'll note that in the top issue to not confuse other folks.

@sethmlarson sethmlarson marked this pull request as draft January 11, 2024 17:09
* Adds dependency relationships between top-level
  CPython package and vendored packages.
* Removes directory prefix in file names to make diffs
  more consistent across different releases.
* Gets release-tool commit SHA for tool version
@sethmlarson sethmlarson marked this pull request as ready for review January 17, 2024 20:55
@sethmlarson
Copy link
Collaborator Author
sethmlarson commented Jan 17, 2024
< 8000 /h3>

Okay, this is ready for review. Depends on #84 being merged first. cc @hugovk Note that the only tarball with an SBOM available is 3.13.0a3

You can test the SBOM generation with $ python sbom.py Python-3.13.0a3.tgz

Copy link
Member
@hugovk hugovk left a comment

Choose a reason for hiding this comment

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

Are there any chunks of sbom.py that would benefit from testing/CI?

(It would be really nice to be able to dry-run run_release.py too, but that's completely out of scope here!)

sethmlarson and others added 2 commits January 18, 2024 10:21
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Co-authored-by: Ezio Melotti <ezio.melotti@gmail.com>
@sethmlarson
Copy link
Collaborator Author

Thanks for the reviews! I've applied the suggestions :)

# Remove the 'Python-{version}/...' prefix for the SPDXID and fileName.
member_name_no_prefix = member.name.split('/', 1)[1]

# We've already seen this file, so we check it hasn't been modified and continue on.
Copy link
Member

Choose a reason for hiding this comment

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

Tar files can contain the same file multiple times, there isn't a situation where this can lead to false positives here, is there? (I'm thinking in terms of the listed sha256 being the same but other information being different in the tarball-contained SBOM.) I guess we're trusting both the tarball and the contained SBOM anyway, so no.

@Yhg1s Yhg1s merged commit a048b9d into python:master Feb 6, 2024
@sethmlarson sethmlarson deleted the sbom-utility branch February 6, 2024 18:15
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.

4 participants
0