Skip to content

Commit

Permalink
license checking experimental feature (google#501)
Browse files Browse the repository at this point in the history
This experimental feature calls the deps.dev API for licenses on each package. If an allowlist is specified, it reports on packages with violating licenses.

An --all-packages flag is also added, which causes all packages to be included in the json even if it doesn't have any issues (vulns or license violations).
  • Loading branch information
josieang authored Nov 5, 2023
1 parent 4aed961 commit a85d675
Show file tree
Hide file tree
Showing 16 changed files with 1,402 additions and 112 deletions.
55 changes: 55 additions & 0 deletions cmd/osv-scanner/fixtures/locks-licenses/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions cmd/osv-scanner/fixtures/locks-licenses/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"dependencies": {
"babel": "^6.23.0",
"human-signals": "^5.0.0",
"ms": "^2.1.3"
}
}
59 changes: 38 additions & 21 deletions cmd/osv-scanner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,14 @@ func run(args []string, stdout, stderr io.Writer) int {
Usage: "sets the path that local databases should be stored",
Hidden: true,
},
&cli.BoolFlag{
Name: "experimental-all-packages",
Usage: "when json output is selected, prints all packages",
},
&cli.StringSliceFlag{
Name: "experimental-licenses",
Usage: "report on licenses",
},
},
ArgsUsage: "[directory1 directory2...]",
Action: func(context *cli.Context) error {
Expand Down Expand Up @@ -161,25 +169,31 @@ func run(args []string, stdout, stderr io.Writer) int {
ConfigOverridePath: context.String("config"),
DirectoryPaths: context.Args().Slice(),
ExperimentalScannerActions: osvscanner.ExperimentalScannerActions{
LocalDBPath: context.String("experimental-local-db-path"),
CallAnalysis: context.Bool("experimental-call-analysis"),
CompareLocally: context.Bool("experimental-local-db"),
CompareOffline: context.Bool("experimental-offline"),
LocalDBPath: context.String("experimental-local-db-path"),
CallAnalysis: context.Bool("experimental-call-analysis"),
CompareLocally: context.Bool("experimental-local-db"),
CompareOffline: context.Bool("experimental-offline"),
ShowAllPackages: context.Bool("experimental-all-packages"),
ScanLicenses: context.IsSet("experimental-licenses"),
ScanLicensesAllowlist: context.StringSlice("experimental-licenses"),
},
}, r)

if err != nil &&
!errors.Is(err, osvscanner.VulnerabilitiesFoundErr) &&
!errors.Is(err, osvscanner.OnlyUncalledVulnerabilitiesFoundErr) {
//nolint:wrapcheck
issueResultErr := errors.Join(
osvscanner.VulnerabilitiesFoundErr,
osvscanner.OnlyUncalledVulnerabilitiesFoundErr,
osvscanner.LicenseViolationsErr,
osvscanner.VulnerabilitiesFoundAndLicenseViolationsErr,
osvscanner.OnlyUncalledVulnerabilitiesFoundAndLicenseViolationsErr,
)
if err != nil && !errors.Is(issueResultErr, err) {
return err
}

if errPrint := r.PrintResult(&vulnResult); errPrint != nil {
return fmt.Errorf("failed to write output: %w", errPrint)
}

// Could be nil, VulnerabilitiesFoundErr, or OnlyUncalledVulnerabilitiesFoundErr
// This may be nil.
return err
},
}
Expand All @@ -188,20 +202,23 @@ func run(args []string, stdout, stderr io.Writer) int {
if r == nil {
r = reporter.NewTableReporter(stdout, stderr, false, 0)
}
if errors.Is(err, osvscanner.VulnerabilitiesFoundErr) {
return 1
}

if errors.Is(err, osvscanner.OnlyUncalledVulnerabilitiesFoundErr) {
// TODO: Discuss whether to have a different exit code now that running call analysis is not default
return 2
}

if errors.Is(err, osvscanner.NoPackagesFoundErr) {
switch {
case errors.Is(err, osvscanner.VulnerabilitiesFoundErr):
return 0b0001 // 1
case errors.Is(err, osvscanner.OnlyUncalledVulnerabilitiesFoundErr):
// TODO: Discuss whether to have a different exit code
// now that running call analysis is not default.
return 0b0010 // 2
case errors.Is(err, osvscanner.LicenseViolationsErr):
return 0b0100 // 4
case errors.Is(err, osvscanner.VulnerabilitiesFoundAndLicenseViolationsErr):
return 0b0101 // 5
case errors.Is(err, osvscanner.OnlyUncalledVulnerabilitiesFoundAndLicenseViolationsErr):
return 0b0110 // 6
case errors.Is(err, osvscanner.NoPackagesFoundErr):
r.PrintError("No package sources found, --help for usage information.\n")
return 128
}

r.PrintError(fmt.Sprintf("%v\n", err))
}

Expand Down
Loading

0 comments on commit a85d675

Please sign in to comment.