oss-intake 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oss_intake-0.2.1/LICENSE +202 -0
- oss_intake-0.2.1/PKG-INFO +326 -0
- oss_intake-0.2.1/README.md +299 -0
- oss_intake-0.2.1/pyproject.toml +57 -0
- oss_intake-0.2.1/setup.cfg +4 -0
- oss_intake-0.2.1/src/oss_intake/__init__.py +3 -0
- oss_intake-0.2.1/src/oss_intake/__main__.py +7 -0
- oss_intake-0.2.1/src/oss_intake/cli.py +702 -0
- oss_intake-0.2.1/src/oss_intake/conditions.py +56 -0
- oss_intake-0.2.1/src/oss_intake/coverage.py +63 -0
- oss_intake-0.2.1/src/oss_intake/cvss.py +75 -0
- oss_intake-0.2.1/src/oss_intake/data/known_bad.json +38 -0
- oss_intake-0.2.1/src/oss_intake/enrich/__init__.py +1 -0
- oss_intake-0.2.1/src/oss_intake/enrich/advisories.py +49 -0
- oss_intake-0.2.1/src/oss_intake/enrich/alpine.py +87 -0
- oss_intake-0.2.1/src/oss_intake/enrich/debian_releases.py +99 -0
- oss_intake-0.2.1/src/oss_intake/enrich/debian_tracker.py +111 -0
- oss_intake-0.2.1/src/oss_intake/enrich/epss.py +48 -0
- oss_intake-0.2.1/src/oss_intake/enrich/exploits.py +188 -0
- oss_intake-0.2.1/src/oss_intake/enrich/fixdates.py +81 -0
- oss_intake-0.2.1/src/oss_intake/enrich/github_releases.py +53 -0
- oss_intake-0.2.1/src/oss_intake/enrich/golang_stdlib.py +72 -0
- oss_intake-0.2.1/src/oss_intake/enrich/kev.py +26 -0
- oss_intake-0.2.1/src/oss_intake/enrich/packagist.py +53 -0
- oss_intake-0.2.1/src/oss_intake/enrich/redhat.py +49 -0
- oss_intake-0.2.1/src/oss_intake/enrich/ubuntu.py +110 -0
- oss_intake-0.2.1/src/oss_intake/enrich/ubuntu_launchpad.py +88 -0
- oss_intake-0.2.1/src/oss_intake/health/__init__.py +1 -0
- oss_intake-0.2.1/src/oss_intake/health/releases.py +124 -0
- oss_intake-0.2.1/src/oss_intake/health/scorecard.py +31 -0
- oss_intake-0.2.1/src/oss_intake/health/workflows.py +111 -0
- oss_intake-0.2.1/src/oss_intake/http.py +82 -0
- oss_intake-0.2.1/src/oss_intake/inputs.py +87 -0
- oss_intake-0.2.1/src/oss_intake/integrity.py +169 -0
- oss_intake-0.2.1/src/oss_intake/lag.py +151 -0
- oss_intake-0.2.1/src/oss_intake/likelihood.py +162 -0
- oss_intake-0.2.1/src/oss_intake/merge.py +90 -0
- oss_intake-0.2.1/src/oss_intake/models.py +157 -0
- oss_intake-0.2.1/src/oss_intake/reachability.py +48 -0
- oss_intake-0.2.1/src/oss_intake/report.py +394 -0
- oss_intake-0.2.1/src/oss_intake/report_html.py +609 -0
- oss_intake-0.2.1/src/oss_intake/scanners/__init__.py +60 -0
- oss_intake-0.2.1/src/oss_intake/scanners/govulncheck.py +132 -0
- oss_intake-0.2.1/src/oss_intake/scanners/grype.py +125 -0
- oss_intake-0.2.1/src/oss_intake/scanners/osv.py +134 -0
- oss_intake-0.2.1/src/oss_intake/scanners/trivy.py +131 -0
- oss_intake-0.2.1/src/oss_intake/triage.py +75 -0
- oss_intake-0.2.1/src/oss_intake/versions.py +130 -0
- oss_intake-0.2.1/src/oss_intake.egg-info/PKG-INFO +326 -0
- oss_intake-0.2.1/src/oss_intake.egg-info/SOURCES.txt +55 -0
- oss_intake-0.2.1/src/oss_intake.egg-info/dependency_links.txt +1 -0
- oss_intake-0.2.1/src/oss_intake.egg-info/entry_points.txt +2 -0
- oss_intake-0.2.1/src/oss_intake.egg-info/requires.txt +5 -0
- oss_intake-0.2.1/src/oss_intake.egg-info/top_level.txt +1 -0
- oss_intake-0.2.1/tests/test_end_to_end.py +322 -0
- oss_intake-0.2.1/tests/test_real_regressions.py +73 -0
- oss_intake-0.2.1/tests/test_units.py +1127 -0
oss_intake-0.2.1/LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: oss-intake
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Assess third-party open source software before adoption: known vulnerabilities, release lag and project health.
|
|
5
|
+
Author: Ned Tavakol
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/ntavakol/OSS-Intake
|
|
8
|
+
Project-URL: Source, https://github.com/ntavakol/OSS-Intake
|
|
9
|
+
Project-URL: Issues, https://github.com/ntavakol/OSS-Intake/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/ntavakol/OSS-Intake/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: security,sbom,vulnerability,trivy,grype,osv,supply-chain
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Information Technology
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Topic :: Security
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: requests<3,>=2.31
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
25
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# oss-intake
|
|
29
|
+
|
|
30
|
+
[](https://github.com/ntavakol/OSS-Intake/actions/workflows/ci.yml)
|
|
31
|
+
[](https://github.com/ntavakol/OSS-Intake/actions/workflows/codeql.yml)
|
|
32
|
+
[](https://scorecard.dev/viewer/?uri=github.com/ntavakol/OSS-Intake)
|
|
33
|
+
|
|
34
|
+
Assess third-party open source software before you adopt it. `oss-intake` answers two questions for a
|
|
35
|
+
security or architecture review:
|
|
36
|
+
|
|
37
|
+
1. **Is it vulnerable?** Known vulnerabilities in a container image and the dependencies bundled inside it.
|
|
38
|
+
2. **Does the project patch?** Whether fixes that exist upstream are being shipped, how long they have been
|
|
39
|
+
available, and how active the project is.
|
|
40
|
+
|
|
41
|
+
The second question is what a scanner alone does not answer. `oss-intake` measures **release lag**: findings
|
|
42
|
+
where the fixed version of a dependency was already published before the project's release, so the project
|
|
43
|
+
could have shipped it and did not. It then adds project health signals (release cadence, OpenSSF Scorecard,
|
|
44
|
+
CISA KEV membership).
|
|
45
|
+
|
|
46
|
+
## What it does
|
|
47
|
+
|
|
48
|
+
- Runs [Trivy](https://github.com/aquasecurity/trivy) and, if installed, [Grype](https://github.com/anchore/grype)
|
|
49
|
+
against an image, and queries [OSV.dev](https://osv.dev) for the language packages Trivy found.
|
|
50
|
+
- Merges the results into one row per vulnerability, package and version, recording which sources saw it.
|
|
51
|
+
- Looks up when each fixed dependency version was published ([deps.dev](https://deps.dev)) and compares that
|
|
52
|
+
with the project's GitHub release date.
|
|
53
|
+
- Reports release cadence from the GitHub API and the OpenSSF Scorecard score where one exists.
|
|
54
|
+
- Audits the project's own GitHub Actions workflows: unpinned actions, known-bad action versions (such as the
|
|
55
|
+
compromised `trivy-action` tags), missing or write-all token permissions, and `pull_request_target` triggers.
|
|
56
|
+
- Optionally suggests a likelihood value for a 5x5 risk matrix from configurable rules, clearly labelled
|
|
57
|
+
as a heuristic.
|
|
58
|
+
- Writes `findings.csv`, `summary.md`, `assessment.json` and a self-contained `report.html`, plus the raw
|
|
59
|
+
scanner output under `raw/` as evidence.
|
|
60
|
+
- Applies integrity checks to the scanners it runs: version pinning, a known-bad version list, SHA-256
|
|
61
|
+
verification and optional Sigstore (cosign) verification.
|
|
62
|
+
|
|
63
|
+
## What it does not do
|
|
64
|
+
|
|
65
|
+
- **It does not prove exploitability.** Scanners match component versions against advisory databases. A
|
|
66
|
+
finding means a version is listed as affected, not that the vulnerable code is reachable or exposed in your
|
|
67
|
+
deployment. The CSV has empty `triage_*` columns for recording reachability decisions.
|
|
68
|
+
- It does not install, download, bundle or redistribute scanners. You install them; it verifies them.
|
|
69
|
+
- It does not assess licences, secrets or misconfiguration, and it does not detect new malware. Packages already
|
|
70
|
+
listed in the OpenSSF malicious packages database (OSV `MAL-` entries) are flagged as malicious.
|
|
71
|
+
- It does not give a risk rating. The likelihood suggestion is a starting point for an assessor.
|
|
72
|
+
- It does not fix anything or open issues upstream.
|
|
73
|
+
|
|
74
|
+
## Install
|
|
75
|
+
|
|
76
|
+
Python 3.10 or later on Windows, macOS or Linux. No administrator rights are needed.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pipx install oss-intake
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Releases are published to PyPI from GitHub Actions through trusted publishing, so PyPI shows each file's
|
|
83
|
+
provenance (which workflow in this repository built it). Each GitHub release also carries a Sigstore signature
|
|
84
|
+
bundle (`.sigstore.json`) for every file, verifiable with [sigstore-python](https://github.com/sigstore/sigstore-python).
|
|
85
|
+
|
|
86
|
+
Windows PowerShell without pipx:
|
|
87
|
+
|
|
88
|
+
```powershell
|
|
89
|
+
py -m pip install --user pipx
|
|
90
|
+
py -m pipx ensurepath
|
|
91
|
+
# open a new terminal, then
|
|
92
|
+
pipx install oss-intake
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
If `oss-intake` is "not recognized" after `pip install --user`, the per-user Scripts folder is not on PATH.
|
|
96
|
+
Either add it, or run the tool through Python, which works everywhere:
|
|
97
|
+
|
|
98
|
+
```powershell
|
|
99
|
+
py -m oss_intake --help
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Install the scanners yourself, pinned and verified
|
|
103
|
+
|
|
104
|
+
Install a specific version of each scanner from its official GitHub release, never "latest", and verify the
|
|
105
|
+
download before you extract it. `oss-intake verify` does the hash comparison correctly on any platform
|
|
106
|
+
(checksum files are served as `application/octet-stream`; they are parsed as bytes, with BOM and CRLF handled):
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
oss-intake verify --file trivy_0.76.1_windows-64bit.zip --checksums trivy_0.76.1_checksums.txt
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Then record the SHA-256 of the extracted executable and pass it on every run (`oss-intake doctor` prints it):
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
oss-intake doctor
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Trivy versions 0.69.4, 0.69.5 and 0.69.6 were malicious (CVE-2026-33634, March 2026). `oss-intake` refuses to
|
|
119
|
+
run any version on its [known-bad list](src/oss_intake/data/known_bad.json).
|
|
120
|
+
|
|
121
|
+
## Usage
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
oss-intake --image owner/app:1.2.3 --repo owner/app --out ./reports \
|
|
125
|
+
--image-src remote --trivy-version 0.76.1 --trivy-sha256 <sha256-of-trivy-executable> --likelihood
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
PowerShell (backtick continues a line):
|
|
129
|
+
|
|
130
|
+
```powershell
|
|
131
|
+
$env:GITHUB_TOKEN = "<optional token, raises the GitHub API rate limit>"
|
|
132
|
+
oss-intake --image owner/app:1.2.3 --repo owner/app --out .\reports `
|
|
133
|
+
--image-src remote --trivy-version 0.76.1 --trivy-sha256 <sha256> --likelihood
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Without a container image, assess a file or folder directly with `--path`:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
oss-intake --path ./vendor-app-2.4.1.jar --repo owner/app --out ./reports # JAR, WAR, EAR or binary
|
|
140
|
+
oss-intake --path ./requirements.txt --repo owner/app --release-tag v1.4.0 --out ./reports
|
|
141
|
+
oss-intake --path ./renv.lock --repo owner/app --release-tag v1.4.0 --out ./reports
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
A JAR, WAR, EAR or binary is scanned as built artifacts (Trivy `rootfs`, Grype `dir:`), and a version in its
|
|
145
|
+
file name is tried as the release tag. Lockfiles the scanners understand (Python, npm, Maven, Go, Rust, PHP,
|
|
146
|
+
Ruby, .NET) are scanned with Trivy `fs`. An R `renv.lock` is read by oss-intake and checked against OSV's CRAN
|
|
147
|
+
advisories, since neither scanner reads it; packages from Bioconductor, GitHub or local sources are listed as
|
|
148
|
+
not checked. A folder is scanned as built artifacts; for a source checkout, pass its lockfile. Release lag needs
|
|
149
|
+
the project's release: `--repo` with `--release-tag`, or `--release-date`.
|
|
150
|
+
|
|
151
|
+
All inputs are validated before any scanner runs. The image must carry an explicit tag or digest.
|
|
152
|
+
|
|
153
|
+
| Option | Purpose |
|
|
154
|
+
|---|---|
|
|
155
|
+
| `--image` | Image with explicit tag or digest |
|
|
156
|
+
| `--path` | A JAR, WAR, binary, folder, lockfile or `renv.lock` instead of an image |
|
|
157
|
+
| `--reachability`, `--govulncheck-path` | Check Go binaries with govulncheck (see Go reachability) |
|
|
158
|
+
| `--repo` | GitHub `owner/name` (a full GitHub URL is accepted) |
|
|
159
|
+
| `--image-src remote` | Pull from the registry without Docker installed (Trivy `--image-src remote`, Grype `registry:`) |
|
|
160
|
+
| `--platform` | Image platform for both scanners (default `linux/amd64`, so Apple Silicon scans the same variant as a server); `''` uses scanner defaults |
|
|
161
|
+
| `--scanners` | `auto` (default: Trivy and OSV, plus Grype if found) or a list such as `trivy,grype,osv` |
|
|
162
|
+
| `--trivy-version`, `--grype-version` | Required scanner version; the run fails on mismatch |
|
|
163
|
+
| `--trivy-sha256`, `--grype-sha256` | Expected SHA-256 of the executable |
|
|
164
|
+
| `--trivy-cosign-bundle`, `--grype-cosign-bundle` | Verify a Sigstore bundle with cosign (cosign must be on PATH) |
|
|
165
|
+
| `--trivy-arg`, `--grype-arg` | Pass extra arguments, e.g. `--trivy-arg=--db-repository=ghcr.io/aquasecurity/trivy-db:2` |
|
|
166
|
+
| `--from-trivy-json`, `--from-grype-json` | Use an existing JSON report instead of running the scanner |
|
|
167
|
+
| `--release-tag`, `--release-date` | Set the release the image corresponds to, when tags do not match |
|
|
168
|
+
| `--grace-days` | A fix must predate the release by this many days to count as missed (default 14) |
|
|
169
|
+
| `--unshipped-days` | Days a fix must be public, with no newer release, to count as unshipped (default 90) |
|
|
170
|
+
| `--as-of` | Fix the assessment date for reproducible reports |
|
|
171
|
+
| `--min-severity` | Drop findings below a severity |
|
|
172
|
+
| `--formats` | Any of `csv,md,json,html` (default all) |
|
|
173
|
+
| `--offline` | No network enrichment (OSV, deps.dev, GitHub, Scorecard, KEV, EPSS, exploit sources) |
|
|
174
|
+
| `--no-epss`, `--no-kev`, `--no-scorecard`, `--no-fix-dates`, `--no-exploits` | Skip one enrichment source |
|
|
175
|
+
| `--likelihood`, `--likelihood-config FILE` | Add the 5x5 likelihood heuristic, with optional custom rules |
|
|
176
|
+
| `--fail-on-likelihood N` | Exit code 3 when the suggestion is N or higher, for pipelines |
|
|
177
|
+
| `--sbom` | Also write a CycloneDX SBOM to `raw/` |
|
|
178
|
+
|
|
179
|
+
Other commands: `oss-intake doctor` (scanner paths, versions, hashes, known-bad status) and
|
|
180
|
+
`oss-intake verify` (check a download against a checksums file, a hash or a cosign bundle).
|
|
181
|
+
|
|
182
|
+
Exit codes: `0` success, `1` error (including any integrity failure), `2` invalid input, `3` likelihood
|
|
183
|
+
threshold reached.
|
|
184
|
+
|
|
185
|
+
`GITHUB_TOKEN` is optional. It is only sent to `api.github.com`, and it is never logged or written to reports.
|
|
186
|
+
|
|
187
|
+
## How release lag is measured
|
|
188
|
+
|
|
189
|
+
For each finding with a fix, `oss-intake` picks the nearest fixed version above the installed one (so a fix on
|
|
190
|
+
an older branch is not counted for a newer one) and looks up when that version was published.
|
|
191
|
+
|
|
192
|
+
| Metric | Meaning |
|
|
193
|
+
|---|---|
|
|
194
|
+
| Fix exists upstream | A fixed version of the dependency is known |
|
|
195
|
+
| **Fix existed before release** | The fixed version was published at least `--grace-days` (14) days before the project's release: the project could reasonably have shipped it |
|
|
196
|
+
| Fix within grace period | Published in the 14 days before release; shown but not counted as missed |
|
|
197
|
+
| **Unshipped** | Forward-looking: the fix has been public for `--unshipped-days` (90) or more and the scanned release is still the project's latest |
|
|
198
|
+
| Likely already fixed | Installed version equals a listed fix apart from a build label such as `.jre11`; flagged and excluded from lag |
|
|
199
|
+
| Fix published after release | The fix arrived later; this is normal lag for the next release |
|
|
200
|
+
| Days a fix has been available | Assessment date minus the fixed version's publish date |
|
|
201
|
+
| CVE published before release | Secondary signal. A CVE can be public before any fix exists, so this overstates lag on its own |
|
|
202
|
+
|
|
203
|
+
Fix dates come from deps.dev for language packages, from Packagist for PHP Composer packages, falling back to the GitHub release date for Go modules
|
|
204
|
+
hosted on GitHub that deps.dev does not index. For Debian packages they come from the Debian security advisory
|
|
205
|
+
that shipped the fix (DSA or DLA, by the scanner's advisory ID or the exact fixed version), dated from the Debian
|
|
206
|
+
security tracker's advisory lists, with OSV as a fallback. Fixes that shipped without an advisory are dated from the
|
|
207
|
+
Debian point release (13.6 and so on) that included the fixed version, from the suite's ChangeLog; fixes still in
|
|
208
|
+
proposed-updates stay unknown, with a note. For Ubuntu packages they come from the Ubuntu
|
|
209
|
+
Security Notice (USN) that fixed the CVE in that release and source package at that version, found through OSV;
|
|
210
|
+
failing that, from Launchpad's publishing history: when that exact version was first published to the release in
|
|
211
|
+
the Release, Security or Updates pocket.
|
|
212
|
+
For RHEL and UBI packages they come from the Red Hat advisory (RHSA) that Trivy reports, dated from Red Hat's
|
|
213
|
+
CSAF document. For Alpine packages they come from the aports commit history on the image's release branch: a commit naming the
|
|
214
|
+
CVE, or the fixed version for a new upstream release (set `GITHUB_TOKEN`, one request per package).
|
|
215
|
+
For the Go standard library they come from the Go release history (go.dev/doc/devel/release).
|
|
216
|
+
Packages with no dated source yet, currently Amazon Linux and runtimes detected only from a binary, are counted as
|
|
217
|
+
"fix date unknown" rather than guessed. The `fix_date_source` column in findings.csv shows where each date came from.
|
|
218
|
+
|
|
219
|
+
## Example output
|
|
220
|
+
|
|
221
|
+
Taken from the synthetic test fixtures (`tests/fixtures`, fictional project `example/webapp`) so it shows
|
|
222
|
+
the format, not a judgement of any real project:
|
|
223
|
+
|
|
224
|
+
```text
|
|
225
|
+
findings=7 critical=2 high=4 with_fix=6 fix_before_release=3 fix_date_unknown=1 likelihood=5(Almost certain)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
| ID | Severity | Package | Installed | Fix | Fix before release | Days fix available |
|
|
229
|
+
|---|---|---|---|---|---|---|
|
|
230
|
+
| CVE-2099-0001 | CRITICAL | org.springframework:spring-web | 6.1.10 | 6.1.12 | yes | 290 |
|
|
231
|
+
| CVE-2099-0006 | CRITICAL | com.fasterxml.jackson.core:jackson-databind | 2.17.0 | 2.17.3 | no | 113 |
|
|
232
|
+
| CVE-2099-0003 | HIGH | io.netty:netty-codec-http | 4.1.100.Final | 4.1.108.Final | yes | 244 |
|
|
233
|
+
| CVE-2099-0004 | HIGH | org.springframework:spring-web | 6.1.10 | none | no fix | n/a |
|
|
234
|
+
| CVE-2099-1000 | MEDIUM | libc6 | 2.39-0ubuntu8.4 | 2.39-0ubuntu8.5 | unknown | n/a |
|
|
235
|
+
|
|
236
|
+
The summary also covers scope (scanner versions, database dates, hash verification), project health,
|
|
237
|
+
agreement between sources and any warnings. See [docs/validation.md](docs/validation.md) for checking the
|
|
238
|
+
tool against a real public image.
|
|
239
|
+
|
|
240
|
+
## Exploit availability and advisory conditions
|
|
241
|
+
|
|
242
|
+
Each finding gets the strongest public exploit evidence found: known exploited (CISA KEV), weaponised (a
|
|
243
|
+
Metasploit module or Nuclei template), public (Exploit-DB), proof of concept (GitHub repositories only, which
|
|
244
|
+
are noisy and sometimes malicious), or none indexed. "None indexed" means none was found in those sources, not
|
|
245
|
+
that none exists; when a source cannot be reached the finding is "not checked" instead. The `conditions`
|
|
246
|
+
column quotes the advisory's own statement of when the finding applies (for example "only if the application
|
|
247
|
+
uses XsltView"), word for word, so the assessor can check it against the deployment.
|
|
248
|
+
|
|
249
|
+
## Go reachability (optional)
|
|
250
|
+
|
|
251
|
+
With `--reachability`, Go binaries in the scan are checked with Go's official
|
|
252
|
+
[govulncheck](https://go.dev/doc/security/vuln/) in binary mode, which reports whether a vulnerable function is
|
|
253
|
+
actually linked into the binary. Install it yourself (`go install golang.org/x/vuln/cmd/govulncheck@v1.1.4`);
|
|
254
|
+
oss-intake never downloads it. For an image, the binaries are copied out with Docker (`docker create` and
|
|
255
|
+
`docker cp`) or `crane export`. A finding whose vulnerable functions are absent from every binary it was seen
|
|
256
|
+
in is marked "not reachable" and set aside in triage, with the govulncheck ID as the reason; one whose function
|
|
257
|
+
is present is marked "reachable". Counts and likelihood do not change: the vulnerable version is still shipped.
|
|
258
|
+
This covers Go only; for other languages the advisory conditions are the assessor's guide.
|
|
259
|
+
|
|
260
|
+
## Suggested triage
|
|
261
|
+
|
|
262
|
+
Each finding is placed in one group, with its reason, as a reading order for the engineer: **Act now** (a known
|
|
263
|
+
malicious package, CISA KEV, or a Metasploit or Nuclei exploit), **Review** (an Exploit-DB exploit, EPSS 0.1 or more, or a critical whose
|
|
264
|
+
advisory states no conditions), **Check conditions** (the advisory says when it applies; confirm against the
|
|
265
|
+
deployment), **Routine** (none of these) and **Set aside** (only with evidence: a kernel header package, the
|
|
266
|
+
installed version already matches a fix, or govulncheck shows the vulnerable function is not in the binary). No group says a finding carries no risk.
|
|
267
|
+
|
|
268
|
+
## Likelihood heuristic
|
|
269
|
+
|
|
270
|
+
Off by default. With `--likelihood`, the first matching rule wins:
|
|
271
|
+
|
|
272
|
+
| Level | Default rule |
|
|
273
|
+
|---|---|
|
|
274
|
+
| 5 Almost certain | A CISA KEV vulnerability has a fix the project has not shipped |
|
|
275
|
+
| 4 Likely | A finding with an upstream fix has a ready-to-use exploit (Metasploit module or Nuclei template) |
|
|
276
|
+
| 4 Likely | A finding with an upstream fix has an EPSS score of 0.5 or more |
|
|
277
|
+
| 4 Likely | A critical fix existed before release, and the project has not released for 180 days, is archived or scores under 4 on Scorecard |
|
|
278
|
+
| 4 Likely | A critical fix is unshipped and the project has not released for 180 days |
|
|
279
|
+
| 3 Possible | A finding with an upstream fix has an EPSS score of 0.1 or more |
|
|
280
|
+
| 3 Possible | A finding with an upstream fix has a published exploit (Exploit-DB) |
|
|
281
|
+
| 3 Possible | A critical fix, or 5 or more high fixes, existed before release |
|
|
282
|
+
| 3 Possible | A critical fix, or 10 or more high fixes, are unshipped |
|
|
283
|
+
| 2 Unlikely | Any high or critical finding has an upstream fix |
|
|
284
|
+
| 1 Rare | None of the above |
|
|
285
|
+
|
|
286
|
+
Unknown signals (no Scorecard score, say) never trigger a rule. To use your own rules, copy
|
|
287
|
+
`DEFAULT_CONFIG` from [likelihood.py](src/oss_intake/likelihood.py) into a JSON file and pass
|
|
288
|
+
`--likelihood-config`. The available metrics are `critical_fix_at_release`, `high_fix_at_release`,
|
|
289
|
+
`critical_with_fix`, `high_with_fix`, `critical_fix_unshipped`, `high_fix_unshipped`, `kev_with_fix`, `max_epss_with_fix`, `max_days_fix_available`, `days_since_latest_release`,
|
|
290
|
+
`archived`, `scorecard_score` and `fix_date_unknown`.
|
|
291
|
+
|
|
292
|
+
## Limitations
|
|
293
|
+
|
|
294
|
+
- Results depend on the scanners' vulnerability databases and drift as those databases update. The report
|
|
295
|
+
records scanner and database versions so a result can be reproduced or explained.
|
|
296
|
+
- Trivy and Grype detect packages independently, so their disagreement is informative. OSV is queried with
|
|
297
|
+
Trivy's package list, so it is an independent database check, not an independent detector.
|
|
298
|
+
- Severity is the highest any source reported, which is conservative. Per-source severities are in the CSV.
|
|
299
|
+
- Kernel CVEs reported against kernel header packages (`linux-libc-dev` and similar) are excluded from lag and
|
|
300
|
+
likelihood, because a container uses the host's kernel. They stay in findings.csv with a note; assess the host
|
|
301
|
+
kernel separately. Use `--include-kernel-headers` to count them.
|
|
302
|
+
- Version comparison is ecosystem-agnostic and approximate. It only affects which fix date is used. Build
|
|
303
|
+
labels (`.jre11`, `-jre`, `-android`) are ignored when comparing.
|
|
304
|
+
- Scanners can read a JAR's version without its build label and report an already-fixed build as vulnerable
|
|
305
|
+
(seen with `mssql-jdbc 12.10.2.jre11`). These rows are kept, marked in the `note` column and excluded from lag.
|
|
306
|
+
OSV inherits the same mistake because it is queried with the scanner's version.
|
|
307
|
+
- The OpenSSF Scorecard API only covers repositories in its scheduled dataset. "Not scored" is not a
|
|
308
|
+
negative signal.
|
|
309
|
+
- Release matching expects GitHub releases whose tags resemble the image tag (`1.2.3`, `v1.2.3`,
|
|
310
|
+
`name-1.2.3`, `release-1.2.3`), and also tries the tag without a variant suffix (`2.528-jdk21` matches
|
|
311
|
+
`jenkins-2.528`). If nothing matches, lag metrics are not computed rather than measured against the
|
|
312
|
+
wrong release. Use `--release-tag` or `--release-date` in that case. Failing both, the image's build date is
|
|
313
|
+
used and labelled "image build date": lag then means "fixes that existed when the image was built"
|
|
314
|
+
(disable with `--no-image-date`).
|
|
315
|
+
- Fix dates are unavailable for Amazon Linux and for runtimes found only in binaries. When more than half of the fixes lack
|
|
316
|
+
a date, the likelihood suggestion is marked low confidence: read it as "not enough evidence", not "low risk".
|
|
317
|
+
- Only GitHub-hosted projects get health signals in this version.
|
|
318
|
+
- Trivy does not catalogue installed R (CRAN) packages, so R libraries inside an image are not assessed.
|
|
319
|
+
- Runtimes detected from binaries (`binary` in the coverage table) have no package registry to date fixes
|
|
320
|
+
from, so they always show as "fix date unknown".
|
|
321
|
+
|
|
322
|
+
Planned work is in [BACKLOG.md](BACKLOG.md).
|
|
323
|
+
|
|
324
|
+
## Licence
|
|
325
|
+
|
|
326
|
+
Apache License 2.0. See [LICENSE](LICENSE).
|