diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 3955a9eb5f4..dea69dbe9f1 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -37,34 +37,34 @@ jobs: # Learn more about CodeQL language support at https://git.io/codeql-language-support steps: - - name: Checkout repository - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@896079047b4bb059ba6f150a5d87d47dde99e6e5 # v2.1.37 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@896079047b4bb059ba6f150a5d87d47dde99e6e5 # v2.1.37 - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl - # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language + # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language - #- run: | - # make bootstrap - # make release + #- run: | + # make bootstrap + # make release - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@896079047b4bb059ba6f150a5d87d47dde99e6e5 # v2.1.37 diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml index fb2b22b1964..9f5e01f17f2 100644 --- a/.github/workflows/goreleaser.yml +++ b/.github/workflows/goreleaser.yml @@ -17,17 +17,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v2.3.4 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 with: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@c4a742cab115ed795e34d4513e2cf7d472deb55f # v2.2.0 + uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 with: go-version: 1.19 check-latest: true - name: Run GoReleaser id: run-goreleaser - uses: goreleaser/goreleaser-action@b508e2e3ef3b19d4e4146d4f8fb3ba9db644a757 # v2.5.0 + uses: goreleaser/goreleaser-action@8f67e590f2d095516493f017008adc464e63adb1 # v4.1.0 with: version: latest args: release --rm-dist diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 216b22502a0..215fdc186aa 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -24,10 +24,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out code - uses: actions/checkout@v3 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 with: - go-version: '>=1.18.0' + go-version: '1.19' + check-latest: true - name: Run go vet run: ./run_lints.sh diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 974578206c8..42575d3bbcf 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -32,7 +32,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 with: persist-credentials: false @@ -59,7 +59,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0 + uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1 with: name: SARIF file path: results.sarif @@ -67,6 +67,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@807578363a7869ca324a79039e6db9c843e0e100 # v2.1.27 + uses: github/codeql-action/upload-sarif@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37 with: sarif_file: results.sarif diff --git a/.goreleaser.yml b/.goreleaser.yml index 4e03b47b0ca..579ceec5520 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -26,7 +26,7 @@ builds: # - '386' # Further testing before supporting arm # - arm - # - arm64 + - arm64 main: ./cmd/osv-scanner/main.go binary: '{{ .ProjectName }}_v{{ .Version }}' archives: @@ -38,4 +38,4 @@ checksum: release: draft: false changelog: - skip: true \ No newline at end of file + skip: true diff --git a/README.md b/README.md index f1f20b39eab..9fbf3eba9fe 100644 --- a/README.md +++ b/README.md @@ -12,17 +12,38 @@ OSV-Scanner provides an officially supported frontend to the [OSV database](http The above all results in fewer, more actionable vulnerability notifications, which reduces the time needed to resolve them. +## Table of Contents +- [OSV-Scanner](#osv-scanner) + - [Table of Contents](#table-of-contents) + - [Installing](#installing) + - [Installation Process](#installation-process) + - [SemVer Adherence](#semver-adherence) + - [Usage](#usage) + - [Scan a directory](#scan-a-directory) + - [Input an SBOM](#input-an-sbom) + - [Input a lockfile](#input-a-lockfile) + - [Scanning a Debian based docker image packages](#scanning-a-debian-based-docker-image-packages) + - [Configure OSV-Scanner](#configure-osv-scanner) + - [Ignore vulnerabilities by ID](#ignore-vulnerabilities-by-id) + - [JSON output](#json-output) + - [Output Format](#output-format) + + ## Installing -### Prerequisites -Requires go 1.18+ to be installed ### Installation Process -Run +You may download the [SLSA3](https://slsa.dev) compliant binaries for Linux, macOS, and Windows from our [releases page](https://github.com/google/osv-scanner/releases). + +#### Install from source + +Alternatively, you can install this from source by running: ```bash $ go install github.com/google/osv-scanner/cmd/osv-scanner@v1 ``` +This requires Go 1.18+ to be installed. + ### SemVer Adherence All releases on the same Major version will be guaranteed to have backward compatible JSON output and CLI arguments. @@ -82,6 +103,8 @@ A wide range of lockfiles are supported by utilizing this [lockfile package](htt - `pubspec.lock` - `pom.xml`[\*](https://github.com/google/osv-scanner/issues/35) - `requirements.txt`[\*](https://github.com/google/osv-scanner/issues/34) +- `gradle.lockfile` +- `buildscript-gradle.lockfile` #### Example @@ -89,7 +112,7 @@ A wide range of lockfiles are supported by utilizing this [lockfile package](htt $ go run ./cmd/osv-scanner --lockfile=/path/to/your/package-lock.json -L /path/to/another/Cargo.lock ``` -### Scanning a Debian based docker image packages +### Scanning a Debian based docker image packages (preview) This tool will scrape the list of installed packages in a Debian image and query for vulnerabilities on them. @@ -97,6 +120,8 @@ Currently only Debian based docker image scanning is supported. Requires `docker` to be installed and the tool to have permission calling it. +This currently does not scan the filesystem of the Docker container, and has various other limitations. Follow [this issue](https://github.com/google/osv-scanner/issues/64) for updates on container scanning! + #### Example ```bash @@ -126,13 +151,16 @@ reason = "No external http servers are written in Go lang." ## JSON output By default osv-scanner outputs a human readable table. To have osv-scanner output JSON instead, pass the `--json` flag when calling osv-scanner. +When using the --json flag, only the JSON output will be printed to stdout, with all other outputs being directed to stderr. So to save only the json output to file, you can redirect the output with `osv-scanner --json ... > /path/to/file.json` + ### Output Format -```json +```json5 { "results": [ { "packageSource": { "path": "/absolute/path/to/go.mod", + // One of: lockfile, sbom, git, docker "type": "lockfile" }, "packages": [ @@ -159,6 +187,8 @@ By default osv-scanner outputs a human readable table. To have osv-scanner outpu // ... Full OSV } ], + // Grouping based on aliases, if two vulnerability share the same alias, or alias each other, + // they are considered the same vulnerability, and is grouped here under the id field. "groups": [ { "ids": [ diff --git a/cmd/osv-scanner/main.go b/cmd/osv-scanner/main.go index 013c61b0952..5dfbc2633da 100644 --- a/cmd/osv-scanner/main.go +++ b/cmd/osv-scanner/main.go @@ -12,11 +12,23 @@ import ( "github.com/urfave/cli/v2" ) +var ( + version = "dev" + commit = "n/a" + date = "n/a" +) + func run(args []string, stdout, stderr io.Writer) int { var r *output.Reporter + cli.VersionPrinter = func(ctx *cli.Context) { + r = output.NewReporter(stdout, stderr, false) + r.PrintText(fmt.Sprintf("osv-scanner version: %s\ncommit: %s\nbuilt at: %s\n", ctx.App.Version, commit, date)) + } + app := &cli.App{ Name: "osv-scanner", + Version: version, Usage: "scans various mediums for dependencies and matches it against the OSV database", Suggest: true, Writer: stdout, @@ -75,15 +87,10 @@ func run(args []string, stdout, stderr io.Writer) int { DirectoryPaths: context.Args().Slice(), }, r) - if err != nil { - return err + if errPrint := r.PrintResult(&vulnResult); errPrint != nil { + return fmt.Errorf("failed to write output: %v", errPrint) } - - if err := r.PrintResult(&vulnResult); err != nil { - return fmt.Errorf("failed to write output: %v", err) - } - - return nil + return err }, } @@ -91,6 +98,10 @@ func run(args []string, stdout, stderr io.Writer) int { if r == nil { r = output.NewReporter(stdout, stderr, false) } + if errors.Is(err, osvscanner.VulnerabilitiesFoundErr) { + return 1 + } + if errors.Is(err, osvscanner.NoPackagesFoundErr) { r.PrintError(fmt.Sprintf("No package sources found, --help for usage information.\n")) return 128 diff --git a/pkg/lockfile/ecosystems_test.go b/pkg/lockfile/ecosystems_test.go index 92818fe450b..7ce70f5bd74 100644 --- a/pkg/lockfile/ecosystems_test.go +++ b/pkg/lockfile/ecosystems_test.go @@ -1,10 +1,11 @@ package lockfile_test import ( - "github.com/google/osv-scanner/pkg/lockfile" "os" "strings" "testing" + + "github.com/google/osv-scanner/pkg/lockfile" ) func numberOfLockfileParsers(t *testing.T) int { @@ -33,9 +34,9 @@ func TestKnownEcosystems(t *testing.T) { expectedCount := numberOfLockfileParsers(t) - // npm, yarn, and pnpm, and pip and poetry, all use the same ecosystem - // so "ignore" those parsers in the count - expectedCount -= 3 + // npm, yarn, and pnpm, and pip and poetry, and maven and gradle, all + // use the same ecosystem so "ignore" those parsers in the count + expectedCount -= 4 ecosystems := lockfile.KnownEcosystems() diff --git a/pkg/lockfile/fixtures/gradle/5-pkg b/pkg/lockfile/fixtures/gradle/5-pkg new file mode 100644 index 00000000000..53af5d46720 --- /dev/null +++ b/pkg/lockfile/fixtures/gradle/5-pkg @@ -0,0 +1,10 @@ +## +## Comments +## + +org.springframework.boot:spring-boot-autoconfigure:2.7.4=compileClasspath,developmentOnly,productionRuntimeClasspath,runtimeClasspath +org.springframework.boot:spring-boot-configuration-processor:2.7.5=annotationProcessor,compileClasspath +org.springframework.boot:spring-boot-devtools:2.7.6=developmentOnly,runtimeClasspath +org.springframework.boot:spring-boot-starter-aop:2.7.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:2.7.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath +empty= diff --git a/pkg/lockfile/fixtures/gradle/one-pkg b/pkg/lockfile/fixtures/gradle/one-pkg new file mode 100644 index 00000000000..fcb55543724 --- /dev/null +++ b/pkg/lockfile/fixtures/gradle/one-pkg @@ -0,0 +1,5 @@ +# Comment example +# + +org.springframework.security:spring-security-crypto:5.7.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath +empty= diff --git a/pkg/lockfile/fixtures/gradle/only-comments b/pkg/lockfile/fixtures/gradle/only-comments new file mode 100644 index 00000000000..503dfb227e9 --- /dev/null +++ b/pkg/lockfile/fixtures/gradle/only-comments @@ -0,0 +1,8 @@ +# This +# is +# a +# comment + + + + diff --git a/pkg/lockfile/fixtures/gradle/only-empty b/pkg/lockfile/fixtures/gradle/only-empty new file mode 100644 index 00000000000..c0918d5384f --- /dev/null +++ b/pkg/lockfile/fixtures/gradle/only-empty @@ -0,0 +1 @@ +empty= diff --git a/pkg/lockfile/fixtures/gradle/with-bad-pkg b/pkg/lockfile/fixtures/gradle/with-bad-pkg new file mode 100644 index 00000000000..6f0dcd5e0d8 --- /dev/null +++ b/pkg/lockfile/fixtures/gradle/with-bad-pkg @@ -0,0 +1,19 @@ +# This sample gradle lockfile has bad lines +# +>>> +//// +empty======= + +org.springframework.boot:spring-boot-autoconfigure:2.7.4=compileClasspath,developmentOnly,productionRuntimeClasspath,runtimeClasspath + + a + b + + + +org.springframework.boot:spring-boot-configuration-processor:2.7.5=compileClasspath,developmentOnly,productionRuntimeClasspath,runtimeClasspath + + + + + diff --git a/pkg/lockfile/parse-gradle-lock.go b/pkg/lockfile/parse-gradle-lock.go new file mode 100644 index 00000000000..6cce6034c23 --- /dev/null +++ b/pkg/lockfile/parse-gradle-lock.go @@ -0,0 +1,70 @@ +package lockfile + +import ( + "bufio" + "fmt" + "os" + "strings" +) + +const ( + gradleLockFileCommentPrefix = "#" + gradleLockFileEmptyPrefix = "empty=" +) + +func isGradleLockFileDepLine(line string) bool { + ret := strings.HasPrefix(line, gradleLockFileCommentPrefix) || + strings.HasPrefix(line, gradleLockFileEmptyPrefix) + + return !ret +} + +func parseToGradlePackageDetail(line string) (PackageDetails, error) { + parts := strings.SplitN(line, ":", 3) + if len(parts) < 3 { + return PackageDetails{}, fmt.Errorf("invalid line in gradle lockfile: %s", line) + } + + group, artifact, version := parts[0], parts[1], parts[2] + version = strings.SplitN(version, "=", 2)[0] + + return PackageDetails{ + Name: fmt.Sprintf("%s:%s", group, artifact), + Version: version, + Ecosystem: MavenEcosystem, + CompareAs: MavenEcosystem, + }, nil +} + +func ParseGradleLock(pathToLockfile string) ([]PackageDetails, error) { + lockFile, err := os.Open(pathToLockfile) + if err != nil { + return []PackageDetails{}, fmt.Errorf("could not open %s: %w", pathToLockfile, err) + } + + defer lockFile.Close() + + pkgs := make([]PackageDetails, 0, 0) + scanner := bufio.NewScanner(lockFile) + + for scanner.Scan() { + lockLine := strings.TrimSpace(scanner.Text()) + if !isGradleLockFileDepLine(lockLine) { + continue + } + + pkg, err := parseToGradlePackageDetail(lockLine) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to parse lockline: %s\n", err.Error()) + continue + } + + pkgs = append(pkgs, pkg) + } + + if err := scanner.Err(); err != nil { + return []PackageDetails{}, fmt.Errorf("failed to read %s: %w", pathToLockfile, err) + } + + return pkgs, nil +} diff --git a/pkg/lockfile/parse-gradle-lock_test.go b/pkg/lockfile/parse-gradle-lock_test.go new file mode 100644 index 00000000000..73b694b9abe --- /dev/null +++ b/pkg/lockfile/parse-gradle-lock_test.go @@ -0,0 +1,128 @@ +package lockfile_test + +import ( + "testing" + + "github.com/google/osv-scanner/pkg/lockfile" +) + +func TestParseGradleLock_FileDoesNotExist(t *testing.T) { + t.Parallel() + + packages, err := lockfile.ParseGradleLock("fixtures/gradle/does-not-exist") + + expectErrContaining(t, err, "could not open") + expectPackages(t, packages, []lockfile.PackageDetails{}) +} + +func TestParseGradleLock_OnlyComments(t *testing.T) { + t.Parallel() + + packages, err := lockfile.ParseGradleLock("fixtures/gradle/only-comments") + + if err != nil { + t.Errorf("Got unexpected error: %v", err) + } + + expectPackages(t, packages, []lockfile.PackageDetails{}) +} + +func TestParseGradleLock_EmptyStatement(t *testing.T) { + t.Parallel() + + packages, err := lockfile.ParseGradleLock("fixtures/gradle/only-empty") + + if err != nil { + t.Errorf("Got unexpected error: %v", err) + } + + expectPackages(t, packages, []lockfile.PackageDetails{}) +} + +func TestParseGradleLock_OnePackage(t *testing.T) { + t.Parallel() + + packages, err := lockfile.ParseGradleLock("fixtures/gradle/one-pkg") + + if err != nil { + t.Errorf("Got unexpected error: %v", err) + } + + expectPackages(t, packages, []lockfile.PackageDetails{ + { + Name: "org.springframework.security:spring-security-crypto", + Version: "5.7.3", + Ecosystem: lockfile.MavenEcosystem, + CompareAs: lockfile.MavenEcosystem, + }, + }) +} + +func TestParseGradleLock_MultiplePackage(t *testing.T) { + t.Parallel() + + packages, err := lockfile.ParseGradleLock("fixtures/gradle/5-pkg") + + if err != nil { + t.Errorf("Got unexpected error: %v", err) + } + + expectPackages(t, packages, []lockfile.PackageDetails{ + { + Name: "org.springframework.boot:spring-boot-autoconfigure", + Version: "2.7.4", + Ecosystem: lockfile.MavenEcosystem, + CompareAs: lockfile.MavenEcosystem, + }, + { + Name: "org.springframework.boot:spring-boot-configuration-processor", + Version: "2.7.5", + Ecosystem: lockfile.MavenEcosystem, + CompareAs: lockfile.MavenEcosystem, + }, + { + Name: "org.springframework.boot:spring-boot-devtools", + Version: "2.7.6", + Ecosystem: lockfile.MavenEcosystem, + CompareAs: lockfile.MavenEcosystem, + }, + + { + Name: "org.springframework.boot:spring-boot-starter-aop", + Version: "2.7.7", + Ecosystem: lockfile.MavenEcosystem, + CompareAs: lockfile.MavenEcosystem, + }, + { + Name: "org.springframework.boot:spring-boot-starter-data-jpa", + Version: "2.7.8", + Ecosystem: lockfile.MavenEcosystem, + CompareAs: lockfile.MavenEcosystem, + }, + }) +} + +func TestParseGradleLock_WithInvalidLines(t *testing.T) { + t.Parallel() + + packages, err := lockfile.ParseGradleLock("fixtures/gradle/with-bad-pkg") + + if err != nil { + t.Errorf("Got unexpected error: %v", err) + } + + expectPackages(t, packages, []lockfile.PackageDetails{ + { + Name: "org.springframework.boot:spring-boot-autoconfigure", + Version: "2.7.4", + Ecosystem: lockfile.MavenEcosystem, + CompareAs: lockfile.MavenEcosystem, + }, + { + Name: "org.springframework.boot:spring-boot-configuration-processor", + Version: "2.7.5", + Ecosystem: lockfile.MavenEcosystem, + CompareAs: lockfile.MavenEcosystem, + }, + }) +} diff --git a/pkg/lockfile/parse.go b/pkg/lockfile/parse.go index e8cd9ef8b6e..6c474098138 100644 --- a/pkg/lockfile/parse.go +++ b/pkg/lockfile/parse.go @@ -18,18 +18,20 @@ func FindParser(pathToLockfile string, parseAs string) (PackageDetailsParser, st //nolint:gochecknoglobals // this is an optimisation and read-only var parsers = map[string]PackageDetailsParser{ - "Cargo.lock": ParseCargoLock, - "composer.lock": ParseComposerLock, - "Gemfile.lock": ParseGemfileLock, - "go.mod": ParseGoLock, - "mix.lock": ParseMixLock, - "package-lock.json": ParseNpmLock, - "pnpm-lock.yaml": ParsePnpmLock, - "poetry.lock": ParsePoetryLock, - "pom.xml": ParseMavenLock, - "pubspec.lock": ParsePubspecLock, - "requirements.txt": ParseRequirementsTxt, - "yarn.lock": ParseYarnLock, + "Cargo.lock": ParseCargoLock, + "composer.lock": ParseComposerLock, + "Gemfile.lock": ParseGemfileLock, + "go.mod": ParseGoLock, + "mix.lock": ParseMixLock, + "package-lock.json": ParseNpmLock, + "pnpm-lock.yaml": ParsePnpmLock, + "poetry.lock": ParsePoetryLock, + "pom.xml": ParseMavenLock, + "pubspec.lock": ParsePubspecLock, + "requirements.txt": ParseRequirementsTxt, + "yarn.lock": ParseYarnLock, + "gradle.lockfile": ParseGradleLock, + "buildscript-gradle.lockfile": ParseGradleLock, } func ListParsers() []string { diff --git a/pkg/lockfile/parse_test.go b/pkg/lockfile/parse_test.go index 2c73fb2105b..237354a415f 100644 --- a/pkg/lockfile/parse_test.go +++ b/pkg/lockfile/parse_test.go @@ -2,11 +2,12 @@ package lockfile_test import ( "errors" - "github.com/google/osv-scanner/pkg/lockfile" "os" "reflect" "strings" "testing" + + "github.com/google/osv-scanner/pkg/lockfile" ) func expectNumberOfParsersCalled(t *testing.T, numberOfParsersCalled int) { @@ -95,6 +96,8 @@ func TestParse_FindsExpectedParsers(t *testing.T) { "poetry.lock", "pubspec.lock", "requirements.txt", + "gradle.lockfile", + "buildscript-gradle.lockfile", } count := 0 @@ -109,6 +112,9 @@ func TestParse_FindsExpectedParsers(t *testing.T) { count++ } + // gradle.lockfile and buildscript-gradle.lockfile use the same parser + count = count - 1 + expectNumberOfParsersCalled(t, count) } @@ -131,12 +137,15 @@ func TestListParsers(t *testing.T) { parsers := lockfile.ListParsers() - if first := parsers[0]; first != "Cargo.lock" { - t.Errorf("Expected first element to be Cargo.lock, but got %s", first) + firstExpected := "buildscript-gradle.lockfile" + lastExpected := "yarn.lock" + + if first := parsers[0]; first != firstExpected { + t.Errorf("Expected first element to be %s, but got %s", firstExpected, first) } - if last := parsers[len(parsers)-1]; last != "yarn.lock" { - t.Errorf("Expected last element to be requirements.txt, but got %s", last) + if last := parsers[len(parsers)-1]; last != lastExpected { + t.Errorf("Expected last element to be %s, but got %s", lastExpected, last) } } diff --git a/pkg/osvscanner/osvscanner.go b/pkg/osvscanner/osvscanner.go index db1d094999b..c92a05a6711 100644 --- a/pkg/osvscanner/osvscanner.go +++ b/pkg/osvscanner/osvscanner.go @@ -31,6 +31,7 @@ type ScannerActions struct { // Error for when no packages is found during a scan. var NoPackagesFoundErr = errors.New("no packages found in scan") +var VulnerabilitiesFoundErr = errors.New("vulnerabilities found") // scanDir walks through the given directory to try to find any relevant files // These include: @@ -339,5 +340,11 @@ func DoScan(actions ScannerActions, r *output.Reporter) (models.VulnerabilityRes return models.VulnerabilityResults{}, fmt.Errorf("failed to hydrate OSV response: %v", err) } - return groupResponseBySource(r, query, hydratedResp), nil + vulnerabilityResults := groupResponseBySource(r, query, hydratedResp) + // if vulnerability exists it should return error + if len(vulnerabilityResults.Results) > 0 { + return vulnerabilityResults, VulnerabilitiesFoundErr + } + + return vulnerabilityResults, nil } diff --git a/renovate.json b/renovate.json index 39371603f9e..9e683b7776f 100644 --- a/renovate.json +++ b/renovate.json @@ -1,24 +1,23 @@ { - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:base" - ], - "timezone": "Australia/Sydney", - "schedule": ["before 6am on monday"], - "packageRules": [ - { - "matchUpdateTypes": ["major"], - "groupName": "Major Updates", - "enabled": true - }, - { - "matchLanguages": ["golang"], - "groupName": "osv-scanner minor" - }, - { - "matchPaths": [".github/"], - "groupName": "workflows" - } - ] - } - \ No newline at end of file + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:base" + ], + "timezone": "Australia/Sydney", + "schedule": ["before 6am on monday"], + "packageRules": [ + { + "matchUpdateTypes": ["major"], + "groupName": "Major Updates", + "enabled": true + }, + { + "matchLanguages": ["golang"], + "groupName": "osv-scanner minor" + }, + { + "matchPaths": [".github/"], + "groupName": "workflows" + } + ] +} diff --git a/run_lints.sh b/run_lints.sh index f960060785b..5e11a4f7f9f 100755 --- a/run_lints.sh +++ b/run_lints.sh @@ -1,5 +1,5 @@ -#!/bin/bash +#!/usr/bin/env bash set -ex -go vet ./... \ No newline at end of file +go vet ./... diff --git a/run_tests.sh b/run_tests.sh index eabf582447f..afbe1c7c659 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e go test ./...