mirror of
https://github.com/safedep/vet.git
synced 2025-12-10 00:22:08 -06:00
Refactor to support customer experimental parsers
Add python wheel dist reading support Run go mod tidy Update README docs Add justification for exceptions workflow Misc fix for markdown reporting template
This commit is contained in:
parent
ab3d7e9f34
commit
9e1cc18faa
90
README.md
90
README.md
@ -1,4 +1,5 @@
|
||||
# vet
|
||||
## Automate Open Source Package Vetting in CI/CD
|
||||
|
||||
`vet` is a tool for identifying risks in open source software supply chain. It
|
||||
helps engineering and security teams to identify potential issues in their open
|
||||
@ -10,7 +11,7 @@ source dependencies and evaluate them against organizational policies.
|
||||
|
||||
## Demo
|
||||
|
||||
[](https://asciinema.org/a/I60aD2VtVsETQtIFsYTCewJZ3)
|
||||

|
||||
|
||||
## TL;DR
|
||||
|
||||
@ -40,13 +41,13 @@ Alternatively, look at [Releases](https://github.com/safedep/vet/releases) for
|
||||
a pre-built binary for your platform. [SLSA Provenance](https://slsa.dev/provenance/v0.1) is published
|
||||
along with each binary release.
|
||||
|
||||
Get a trial API key for [Insights API](https://safedep.io/docs/concepts/raya-data-platform-overview) access
|
||||
Get an API key for [Insights API](https://safedep.io/docs/concepts/raya-data-platform-overview) access
|
||||
|
||||
```bash
|
||||
vet auth trial --email john.doe@example.com
|
||||
```
|
||||
|
||||
> A time limited trial API key will be sent over email.
|
||||
> A time limited API key will be sent over email.
|
||||
|
||||
Configure `vet` to use API Key to access [Insights API](https://safedep.io/docs/concepts/raya-data-platform-overview)
|
||||
|
||||
@ -54,7 +55,7 @@ Configure `vet` to use API Key to access [Insights API](https://safedep.io/docs/
|
||||
vet auth configure
|
||||
```
|
||||
|
||||
> Insights API is used to enrich OSS packages with meta-data for rich query and policy
|
||||
> Insights API is used to enrich OSS packages with metadata for rich query and policy
|
||||
> decisions. Alternatively, the API key can be passed through environment
|
||||
> variable `VET_API_KEY`
|
||||
|
||||
@ -90,7 +91,59 @@ The default scan uses an opinionated [Summary Reporter](#) which presents
|
||||
a consolidated summary of findings. Thats NOT about it. Read more for
|
||||
expression based filtering and policy evaluation.
|
||||
|
||||
## Filtering
|
||||
## Policy Control
|
||||
|
||||
Policies are written using a DSL. A group of policies can be applied using
|
||||
`vet` to build a security gate in CI/CD.
|
||||
|
||||
Start by copying a sample policy
|
||||
|
||||
```bash
|
||||
curl -LO https://raw.githubusercontent.com/safedep/vet/main/samples/filter-suites/fs-generic.yml
|
||||
```
|
||||
|
||||
Run a scan with policies and configure the scanner to fail in case of policy
|
||||
violation
|
||||
|
||||
```bash
|
||||
vet scan -D /path/to/dir --filter-suite fs-generic.yml --filter-fail
|
||||
```
|
||||
|
||||
Read more about underlying capability using which policy control is implemented
|
||||
in [filtering guide](docs/filtering.md)
|
||||
|
||||
## Exceptions Management
|
||||
|
||||
Projects may have legacy libraries that will fail any reasonable security policy.
|
||||
Legacy libraries can be added as time bounded exceptions to the policies to place
|
||||
strict control on any new library while legacy library can be upgraded over
|
||||
time.
|
||||
|
||||
Exception rules can be generated using the `query` workflow to temporarily
|
||||
ignore (or snooze) existing issues when using `vet` for the first time. This
|
||||
helps in establishing security gating to prevent introduction of new security
|
||||
issues while existing issues are being remediated.
|
||||
|
||||
Use exception rules during scan to ignore specific packages
|
||||
|
||||
```bash
|
||||
vet scan -D /path/to/repo -e /path/to/exceptions.yml
|
||||
```
|
||||
|
||||
For more information on generating exceptions,
|
||||
refer to [exceptions guide](docs/exceptions.md)
|
||||
|
||||
The generated exceptions file, when combined with policy control, can be used
|
||||
to setup a security gate to prevent introducing new issues while ignoring the
|
||||
existing backlog for a period of time.
|
||||
|
||||
```bash
|
||||
vet scan -D /path/to/dir \
|
||||
--filter-suite fs-generic.yml --filter-fail
|
||||
-e /path/to/exceptions.yml
|
||||
```
|
||||
|
||||
## Exploring OSS Risks using Filters
|
||||
|
||||
Find dependencies that seems not very popular
|
||||
|
||||
@ -109,37 +162,10 @@ vet scan --lockfiles /path/to/pom.xml --report-summary=false \
|
||||
> Use filtering along with `query` command for offline slicing and dicing of
|
||||
> enriched package manifests. Read [filtering guide](docs/filtering.md)
|
||||
|
||||
|
||||
Learn more about [filtering with vet](docs/filtering.md).
|
||||
Look at [filter input spec](api/filter_input_spec.proto) on attributes
|
||||
available to the filter expression.
|
||||
|
||||
### Using Filter Suite
|
||||
|
||||
Filter suites can be used to implement security gating in CI. [Example](samples/filter-suites/fs-generic.yml)
|
||||
file suite contains rules to enforce generic OSS consumption best practices.
|
||||
|
||||
```bash
|
||||
vet scan -D /path/to/dir --filter-suite /path/to/suite.yml --filter-fail
|
||||
```
|
||||
|
||||
Read more about filter suites in [filtering guide](docs/filtering.md)
|
||||
|
||||
## Exceptions Management
|
||||
|
||||
Exception rules can be generated using the `query` workflow to temporarily
|
||||
ignore (or snooze) existing issues when using `vet` for the first time. This
|
||||
helps in establishing security gating to prevent introduction of new security
|
||||
issues while existing issues are being remediated.
|
||||
|
||||
Use exception rules during scan to ignore specific packages
|
||||
|
||||
```bash
|
||||
vet scan -D /path/to/repo -e /path/to/exceptions.yml
|
||||
```
|
||||
|
||||
For more information, refer to [exceptions guide](docs/exceptions.md)
|
||||
|
||||
## FAQ
|
||||
|
||||
### How do I disable the stupid banner?
|
||||
|
||||
@ -20,6 +20,7 @@ message Vulnerabilities {
|
||||
// OpenSSF Scorecard
|
||||
message Scorecard {
|
||||
map<string, float> scores = 1;
|
||||
float score = 2;
|
||||
}
|
||||
|
||||
enum ProjectType {
|
||||
|
||||
@ -4,7 +4,7 @@ Filter command helps solve the problem of visibility for OSS dependencies in an
|
||||
application. To support various requirements, we adopt a generic [expressions
|
||||
language](https://github.com/google/cel-spec) for flexible filtering.
|
||||
|
||||
Example:
|
||||
## Example
|
||||
|
||||
```bash
|
||||
vet scan -D /path/to/repo \
|
||||
@ -14,6 +14,20 @@ vet scan -D /path/to/repo \
|
||||
|
||||
The scan will list only packages that use the `MIT` license.
|
||||
|
||||
Find dependencies that seems not very popular
|
||||
|
||||
```bash
|
||||
vet scan --lockfiles /path/to/pom.xml --report-summary=false \
|
||||
--filter='projects.exists(x, x.stars < 10)'
|
||||
```
|
||||
|
||||
Find dependencies with a critical vulnerability
|
||||
|
||||
```bash
|
||||
vet scan --lockfiles /path/to/pom.xml --report-summary=false \
|
||||
--filter='vulns.critical.exists_one(x, true)'
|
||||
```
|
||||
|
||||
## Input
|
||||
|
||||
Filter expressions work on packages (aka. dependencies) and evaluates to
|
||||
|
||||
BIN
docs/images/vet-demo.gif
Normal file
BIN
docs/images/vet-demo.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
@ -208,6 +208,7 @@ type Scorecard struct {
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Scores map[string]float32 `protobuf:"bytes,1,rep,name=scores,proto3" json:"scores,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"fixed32,2,opt,name=value,proto3"`
|
||||
Score float32 `protobuf:"fixed32,2,opt,name=score,proto3" json:"score,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Scorecard) Reset() {
|
||||
@ -249,6 +250,13 @@ func (x *Scorecard) GetScores() map[string]float32 {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Scorecard) GetScore() float32 {
|
||||
if x != nil {
|
||||
return x.Score
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ProjectInfo struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -490,48 +498,49 @@ var file_filter_input_spec_proto_rawDesc = []byte{
|
||||
0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69,
|
||||
0x74, 0x79, 0x52, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x12, 0x20, 0x0a, 0x03, 0x6c, 0x6f,
|
||||
0x77, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72,
|
||||
0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x03, 0x6c, 0x6f, 0x77, 0x22, 0x76, 0x0a, 0x09,
|
||||
0x53, 0x63, 0x6f, 0x72, 0x65, 0x63, 0x61, 0x72, 0x64, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x63, 0x6f,
|
||||
0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x53, 0x63, 0x6f, 0x72,
|
||||
0x65, 0x63, 0x61, 0x72, 0x64, 0x2e, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x52, 0x06, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x53, 0x63, 0x6f,
|
||||
0x72, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x3a, 0x02, 0x38, 0x01, 0x22, 0x87, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74,
|
||||
0x61, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x73,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x05, 0x66, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x73,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x73, 0x22, 0x5c,
|
||||
0x0a, 0x0e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x1c, 0x0a, 0x09, 0x65, 0x63, 0x6f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x63, 0x6f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xc8, 0x01, 0x0a,
|
||||
0x0b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x21, 0x0a, 0x03,
|
||||
0x70, 0x6b, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x50, 0x61, 0x63, 0x6b,
|
||||
0x61, 0x67, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x70, 0x6b, 0x67, 0x12,
|
||||
0x26, 0x0a, 0x05, 0x76, 0x75, 0x6c, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10,
|
||||
0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73,
|
||||
0x52, 0x05, 0x76, 0x75, 0x6c, 0x6e, 0x73, 0x12, 0x28, 0x0a, 0x09, 0x73, 0x63, 0x6f, 0x72, 0x65,
|
||||
0x63, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x53, 0x63, 0x6f,
|
||||
0x72, 0x65, 0x63, 0x61, 0x72, 0x64, 0x52, 0x09, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x63, 0x61, 0x72,
|
||||
0x64, 0x12, 0x28, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x04, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6c,
|
||||
0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6c,
|
||||
0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x2a, 0x26, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57,
|
||||
0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x10, 0x01, 0x42,
|
||||
0x28, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x61,
|
||||
0x66, 0x65, 0x64, 0x65, 0x70, 0x2f, 0x76, 0x65, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x66, 0x69,
|
||||
0x6c, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x03, 0x6c, 0x6f, 0x77, 0x22, 0x8c, 0x01, 0x0a,
|
||||
0x09, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x63, 0x61, 0x72, 0x64, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x53, 0x63, 0x6f,
|
||||
0x72, 0x65, 0x63, 0x61, 0x72, 0x64, 0x2e, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x45, 0x6e, 0x74,
|
||||
0x72, 0x79, 0x52, 0x06, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65,
|
||||
0x1a, 0x39, 0x0a, 0x0b, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
|
||||
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02,
|
||||
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x87, 0x01, 0x0a, 0x0b,
|
||||
0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x20, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e,
|
||||
0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70,
|
||||
0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05,
|
||||
0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x6b, 0x73,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x16, 0x0a,
|
||||
0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x69,
|
||||
0x73, 0x73, 0x75, 0x65, 0x73, 0x22, 0x5c, 0x0a, 0x0e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
|
||||
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x63, 0x6f, 0x73, 0x79,
|
||||
0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x63, 0x6f, 0x73,
|
||||
0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x22, 0xc8, 0x01, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x49, 0x6e,
|
||||
0x70, 0x75, 0x74, 0x12, 0x21, 0x0a, 0x03, 0x70, 0x6b, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x0f, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x52, 0x03, 0x70, 0x6b, 0x67, 0x12, 0x26, 0x0a, 0x05, 0x76, 0x75, 0x6c, 0x6e, 0x73, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62,
|
||||
0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x05, 0x76, 0x75, 0x6c, 0x6e, 0x73, 0x12, 0x28,
|
||||
0x0a, 0x09, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x63, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x0a, 0x2e, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x63, 0x61, 0x72, 0x64, 0x52, 0x09, 0x73,
|
||||
0x63, 0x6f, 0x72, 0x65, 0x63, 0x61, 0x72, 0x64, 0x12, 0x28, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x50, 0x72, 0x6f,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x05,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x2a, 0x26,
|
||||
0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a,
|
||||
0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x47, 0x49,
|
||||
0x54, 0x48, 0x55, 0x42, 0x10, 0x01, 0x42, 0x28, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x61, 0x66, 0x65, 0x64, 0x65, 0x70, 0x2f, 0x76, 0x65, 0x74,
|
||||
0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x70, 0x75, 0x74,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
8
go.mod
8
go.mod
@ -6,13 +6,13 @@ require (
|
||||
github.com/deepmap/oapi-codegen v1.12.4
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/google/cel-go v0.13.0
|
||||
github.com/google/osv-scanner v1.1.0
|
||||
github.com/google/osv-scanner v1.2.0
|
||||
github.com/jedib0t/go-pretty/v6 v6.4.4
|
||||
github.com/safedep/dry v0.0.0-20230222132026-c8b6cb976849
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/stretchr/testify v1.8.1
|
||||
golang.org/x/term v0.4.0
|
||||
golang.org/x/term v0.5.0
|
||||
google.golang.org/protobuf v1.28.1
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
@ -32,8 +32,8 @@ require (
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stoewer/go-strcase v1.2.0 // indirect
|
||||
golang.org/x/mod v0.7.0 // indirect
|
||||
golang.org/x/sys v0.4.0 // indirect
|
||||
golang.org/x/mod v0.8.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.5.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
18
go.sum
18
go.sum
@ -24,8 +24,8 @@ github.com/google/cel-go v0.13.0 h1:z+8OBOcmh7IeKyqwT/6IlnMvy621fYUqnTVPEdegGlU=
|
||||
github.com/google/cel-go v0.13.0/go.mod h1:K2hpQgEjDp18J76a2DKFRlPBPpgRZgi6EbnpDgIhJ8s=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/osv-scanner v1.1.0 h1:6XL8tD8u4w8NFyiMo03Yd4xGG1VXhZXyrBESBuyWeUY=
|
||||
github.com/google/osv-scanner v1.1.0/go.mod h1:w8BdEP4PJSosGhDfZ6W5RGMfIGb73rW38vCXB9DWA4c=
|
||||
github.com/google/osv-scanner v1.2.0 h1:TWPfI5kDqO/wgxihVyRxX15JQFJeZ0NyPvx1UtR6g38=
|
||||
github.com/google/osv-scanner v1.2.0/go.mod h1:2GmR3DxMxDW/HkkgOf+b/KCfspX2Ls4wcapeNnSNZoY=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||
@ -46,8 +46,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/safedep/dry v0.0.0-20230218045153-1a93b0397b55 h1:OBzggSWzjyEa7YaXp2DvpKDe1wYXtOEcFXQfDqkK7PI=
|
||||
github.com/safedep/dry v0.0.0-20230218045153-1a93b0397b55/go.mod h1:odFOtG1l46k23IaCY6kdNkkLW8L+NT+EUVYYVphP59I=
|
||||
github.com/safedep/dry v0.0.0-20230222132026-c8b6cb976849 h1:5nO9ht1jn7XHFyNFRhUneDZbKmwh4kRr0w/EoWuOQQA=
|
||||
github.com/safedep/dry v0.0.0-20230222132026-c8b6cb976849/go.mod h1:odFOtG1l46k23IaCY6kdNkkLW8L+NT+EUVYYVphP59I=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
@ -70,14 +68,14 @@ github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
|
||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg=
|
||||
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@ -251,7 +251,12 @@ func (f *filterEvaluator) buildFilterInput(pkg *models.Package) (*filterinput.Fi
|
||||
|
||||
// Scorecard
|
||||
scorecard := utils.SafelyGetValue(insight.Scorecard)
|
||||
checks := utils.SafelyGetValue(utils.SafelyGetValue(scorecard.Content).Checks)
|
||||
scorecardContent := utils.SafelyGetValue(scorecard.Content)
|
||||
|
||||
// Aggregated score
|
||||
fi.Scorecard.Score = utils.SafelyGetValue(scorecardContent.Score)
|
||||
|
||||
checks := utils.SafelyGetValue(scorecardContent.Checks)
|
||||
for _, check := range checks {
|
||||
fi.Scorecard.Scores[string(utils.SafelyGetValue(check.Name))] =
|
||||
utils.SafelyGetValue(check.Score)
|
||||
|
||||
@ -8,6 +8,10 @@ import (
|
||||
"github.com/safedep/vet/pkg/models"
|
||||
)
|
||||
|
||||
const (
|
||||
customParserTypePyWheel = "python-wheel"
|
||||
)
|
||||
|
||||
// We are supporting only those ecosystems for which we have data
|
||||
// for enrichment. More ecosystems will be supported as we improve
|
||||
// the capability of our Insights API
|
||||
@ -18,6 +22,10 @@ var supportedEcosystems map[string]bool = map[string]bool{
|
||||
models.EcosystemPyPI: true,
|
||||
}
|
||||
|
||||
var customExperimentalParsers map[string]lockfile.PackageDetailsParser = map[string]lockfile.PackageDetailsParser{
|
||||
customParserTypePyWheel: parsePythonWheelDist,
|
||||
}
|
||||
|
||||
type Parser interface {
|
||||
Ecosystem() string
|
||||
Parse(lockfilePath string) (models.PackageManifest, error)
|
||||
@ -53,6 +61,13 @@ func FindParser(lockfilePath, lockfileAs string) (Parser, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if p, ok := customExperimentalParsers[lockfileAs]; ok {
|
||||
pw := &parserWrapper{parser: p, parseAs: lockfileAs}
|
||||
if pw.supported() {
|
||||
return pw, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no parser found with: %s for: %s", lockfileAs,
|
||||
lockfilePath)
|
||||
}
|
||||
@ -93,6 +108,8 @@ func (pw *parserWrapper) Ecosystem() string {
|
||||
return models.EcosystemMaven
|
||||
case "buildscript-gradle.lockfile":
|
||||
return models.EcosystemMaven
|
||||
case customParserTypePyWheel:
|
||||
return models.EcosystemPyPI
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
||||
79
pkg/parser/pywheel.go
Normal file
79
pkg/parser/pywheel.go
Normal file
@ -0,0 +1,79 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"errors"
|
||||
"io"
|
||||
"net/mail"
|
||||
"strings"
|
||||
|
||||
"github.com/google/osv-scanner/pkg/lockfile"
|
||||
"github.com/safedep/vet/pkg/common/logger"
|
||||
)
|
||||
|
||||
// https://packaging.python.org/en/latest/specifications/binary-distribution-format/
|
||||
func parsePythonWheelDist(pathToLockfile string) ([]lockfile.PackageDetails, error) {
|
||||
details := []lockfile.PackageDetails{}
|
||||
|
||||
r, err := zip.OpenReader(pathToLockfile)
|
||||
if err != nil {
|
||||
return details, err
|
||||
}
|
||||
|
||||
defer r.Close()
|
||||
for _, file := range r.File {
|
||||
if strings.HasSuffix(file.Name, ".dist-info/METADATA") {
|
||||
fd, err := file.Open()
|
||||
if err != nil {
|
||||
return details, err
|
||||
}
|
||||
|
||||
defer fd.Close()
|
||||
return parsePythonPkgInfo(fd)
|
||||
}
|
||||
}
|
||||
|
||||
return details, errors.New("no METADATA found inside wheel")
|
||||
}
|
||||
|
||||
// https://packaging.python.org/en/latest/specifications/core-metadata/
|
||||
func parsePythonPkgInfo(reader io.Reader) ([]lockfile.PackageDetails, error) {
|
||||
m, err := mail.ReadMessage(reader)
|
||||
if err != nil {
|
||||
return []lockfile.PackageDetails{}, err
|
||||
}
|
||||
|
||||
// https://packaging.python.org/en/latest/specifications/core-metadata/#requires-dist-multiple-use
|
||||
if dists, ok := m.Header["Requires-Dist"]; ok {
|
||||
details := []lockfile.PackageDetails{}
|
||||
for _, dist := range dists {
|
||||
p, err := parsePythonPackageSpec(dist)
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to parse python pkg spec: %s err: %v",
|
||||
dist, err)
|
||||
continue
|
||||
}
|
||||
|
||||
details = append(details, p)
|
||||
}
|
||||
|
||||
return details, nil
|
||||
}
|
||||
|
||||
return []lockfile.PackageDetails{}, nil
|
||||
}
|
||||
|
||||
// https://peps.python.org/pep-0440/
|
||||
// https://peps.python.org/pep-0508/
|
||||
// Parsing python dist version spec is not easy. We need to use the spec grammar
|
||||
// to do it correctly. Taking shortcut here by only using the name as the first
|
||||
// iteration ignoring the version
|
||||
func parsePythonPackageSpec(pkgSpec string) (lockfile.PackageDetails, error) {
|
||||
name := strings.SplitN(pkgSpec, " ", 2)[0]
|
||||
return lockfile.PackageDetails{
|
||||
Name: name,
|
||||
Version: "0.0.0",
|
||||
Ecosystem: lockfile.PipEcosystem,
|
||||
CompareAs: lockfile.PipEcosystem,
|
||||
}, nil
|
||||
}
|
||||
@ -23,8 +23,8 @@ issues identified during the scan.
|
||||
{{ range $key, $value := .Remediations }}
|
||||
> {{ $key }}
|
||||
|
||||
| Package | Update Version | Risk Score | Issues |
|
||||
|---------|----------------|------------|--------|
|
||||
| Package | Update Version | Impact Score | Issues |
|
||||
|---------|----------------|--------------|--------|
|
||||
{{- range $value }}
|
||||
| {{ .PkgRemediationName }} | {{ .Pkg.Insights.PackageCurrentVersion }} | {{ .Score }} | - |
|
||||
{{- end }}
|
||||
|
||||
@ -56,7 +56,7 @@ func (s *packageManifestScanner) ScanDirectory(dir string) error {
|
||||
// automatic parser selection
|
||||
func (s *packageManifestScanner) ScanLockfiles(lockfiles []string,
|
||||
lockfileAs string) error {
|
||||
logger.Infof("Scannding %d lockfiles as %s", len(lockfiles), lockfileAs)
|
||||
logger.Infof("Scanning %d lockfiles as %s", len(lockfiles), lockfileAs)
|
||||
|
||||
manifests, err := scanLockfilesForManifests(lockfiles, lockfileAs)
|
||||
if err != nil {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user