Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

nancy:chore - Error not handled by Horusec in Nancy tool #906

Merged
merged 1 commit into from
Dec 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
fetch-depth: 0
- name: security
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HORUSEC_CLI_REPOSITORY_AUTHORIZATION: ${{ secrets.HORUSEC_CLI_REPOSITORY_AUTHORIZATION }}
HORUSEC_CLI_HORUSEC_API_URI: ${{ secrets.HORUSEC_CLI_HORUSEC_API_URI }}
HORUSEC_CLI_REPOSITORY_NAME: ${{ secrets.HORUSEC_CLI_REPOSITORY_NAME }}
Expand Down
2 changes: 1 addition & 1 deletion internal/enums/images/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const (
Csharp = "horuszup/horusec-csharp:v1.1.0"
Elixir = "horuszup/horusec-elixir:v1.1.0"
Generic = "horuszup/horusec-generic:v1.1.0"
Go = "horuszup/horusec-go:v1.2.0"
Go = "horuszup/horusec-go:v1.2.1"
HCL = "horuszup/horusec-hcl:v1.1.0"
Javascript = "horuszup/horusec-js:v1.2.0"
Leaks = "horuszup/horusec-leaks:v1.1.0"
Expand Down
7 changes: 7 additions & 0 deletions internal/helpers/messages/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ const (
MsgErrorGemLockNotFound = "{HORUSEC_CLI} Error It looks like your project doesn't have a gemfile.lock file, " +
"it would be a good idea to commit it so horusec can check for vulnerabilities"
MsgErrorGetFilenameByExt = "Could not get filename by extension: "
MsgErrorNancyRateLimit = `{HORUSEC_CLI} Nancy tool failed to query the GitHub API for updates.
This is most likely due to GitHub rate-limiting on unauthenticated requests.
To make authenticated requests please:
1. Generate a token at https://github.com/settings/tokens
2. Set the token by setting the GITHUB_TOKEN environment variable.
Instructions for generating a token can be found at:
https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line. `
)

// Block of messages usage into log of the level error
Expand Down
2 changes: 1 addition & 1 deletion internal/services/formatters/go/deployments/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ FROM golang:1.17.5-alpine

RUN apk add curl

RUN curl -fsSL https://github.com/sonatype-nexus-community/nancy/releases/download/v1.0.28/nancy-v1.0.28-linux-amd64 -o /bin/nancy
RUN curl -fsSL https://github.com/sonatype-nexus-community/nancy/releases/download/v1.0.29/nancy-v1.0.29-linux-amd64 -o /bin/nancy
RUN chmod +x /bin/nancy

RUN wget -O - -q https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s v2.8.1
22 changes: 17 additions & 5 deletions internal/services/formatters/go/nancy/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package nancy

import (
"encoding/json"
"errors"
"os"
"path/filepath"
"strings"

Expand All @@ -34,8 +36,10 @@ import (
)

const (
goModulesExt = ".mod"
goSumExt = ".sum"
goModulesExt = ".mod"
goSumExt = ".sum"
rateLimitValidation = "this is most likely due to github rate-limiting on unauthenticated requests"
rateLimitPrefix = "error: failed to query the github api for updates"
)

type Formatter struct {
Expand All @@ -54,8 +58,13 @@ func (f *Formatter) StartAnalysis(projectSubPath string) {
return
}

output, err := f.startNancy(projectSubPath)
f.SetAnalysisError(err, tools.Nancy, output, projectSubPath)
if os.Getenv("GITHUB_TOKEN") == "" {
logger.LogWarnWithLevel(messages.MsgErrorNancyRateLimit)
} else {
output, err := f.startNancy(projectSubPath)
f.SetAnalysisError(err, tools.Nancy, output, projectSubPath)
}

f.LogDebugWithReplace(messages.MsgDebugToolFinishAnalysis, tools.Nancy, languages.Go)
}

Expand All @@ -66,10 +75,13 @@ func (f *Formatter) startNancy(projectSubPath string) (string, error) {
if err != nil {
return output, err
}

if output == "" {
return output, nil
}
if strings.Contains(strings.ToLower(output), rateLimitPrefix) &&
strings.Contains(strings.ToLower(output), rateLimitValidation) {
return "", errors.New(messages.MsgErrorNancyRateLimit)
}

return output, f.processOutput(output, projectSubPath)
}
Expand Down
92 changes: 92 additions & 0 deletions internal/services/formatters/go/nancy/formatter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package nancy

import (
"errors"
"os"
"path/filepath"
"testing"

Expand All @@ -27,12 +28,14 @@ import (

"github.com/ZupIT/horusec/config"
"github.com/ZupIT/horusec/internal/entities/toolsconfig"
"github.com/ZupIT/horusec/internal/helpers/messages"
"github.com/ZupIT/horusec/internal/services/formatters"
"github.com/ZupIT/horusec/internal/utils/testutil"
)

func TestParseOutput(t *testing.T) {
t.Run("should success parse output to analysis", func(t *testing.T) {
_ = os.Setenv("GITHUB_TOKEN", "1243567890")
analysis := new(analysis.Analysis)

cfg := config.New()
Expand Down Expand Up @@ -75,6 +78,7 @@ func TestParseOutput(t *testing.T) {
})

t.Run("should success parse output empty to analysis", func(t *testing.T) {
_ = os.Setenv("GITHUB_TOKEN", "1243567890")
analysis := new(analysis.Analysis)

cfg := config.New()
Expand All @@ -92,6 +96,7 @@ func TestParseOutput(t *testing.T) {
})

t.Run("should add error on analysis when parsing invalid output", func(t *testing.T) {
_ = os.Setenv("GITHUB_TOKEN", "1243567890")
analysis := new(analysis.Analysis)

cfg := config.New()
Expand All @@ -108,7 +113,45 @@ func TestParseOutput(t *testing.T) {
assert.True(t, analysis.HasErrors(), "Expected errors on analysis")
})

t.Run("should not run nancy tool because not exists environment", func(t *testing.T) {
_ = os.Setenv("GITHUB_TOKEN", "")
analysis := new(analysis.Analysis)

cfg := config.New()

dockerAPIControllerMock := testutil.NewDockerMock()
dockerAPIControllerMock.On("SetAnalysisID")
dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(outputRateLimit, nil)

service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, cfg)

formatter := NewFormatter(service)
formatter.StartAnalysis("")

assert.False(t, analysis.HasErrors(), "Expected errors on analysis")
})

t.Run("should add error on analysis when output return rate limit requests", func(t *testing.T) {
_ = os.Setenv("GITHUB_TOKEN", "1243567890")
analysis := new(analysis.Analysis)

cfg := config.New()

dockerAPIControllerMock := testutil.NewDockerMock()
dockerAPIControllerMock.On("SetAnalysisID")
dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(outputRateLimit, nil)

service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, cfg)

formatter := NewFormatter(service)
formatter.StartAnalysis("")

assert.True(t, analysis.HasErrors(), "Expected errors on analysis")
assert.Equal(t, messages.MsgErrorNancyRateLimit, analysis.Errors)
})

t.Run("should add error on analysis when something went wrong executing container", func(t *testing.T) {
_ = os.Setenv("GITHUB_TOKEN", "1243567890")
analysis := new(analysis.Analysis)

dockerAPIControllerMock := testutil.NewDockerMock()
Expand All @@ -126,6 +169,7 @@ func TestParseOutput(t *testing.T) {
})

t.Run("should not execute tool because it's ignored", func(t *testing.T) {
_ = os.Setenv("GITHUB_TOKEN", "1243567890")
analysis := new(analysis.Analysis)

dockerAPIControllerMock := testutil.NewDockerMock()
Expand Down Expand Up @@ -221,3 +265,51 @@ const output = `
]
}
`

const outputRateLimit = `Error: Failed to query the GitHub API for updates.

This is most likely due to GitHub rate-limiting on unauthenticated requests.

To make authenticated requests please:

1. Generate a token at https://github.com/settings/tokens
2. Set the token by either adding it to your ~/.gitconfig or
setting the GITHUB_TOKEN environment variable.

Instructions for generating a token can be found at:
https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/

We call the GitHub releases API to look for new releases.
More information about that API can be found here: https://developer.github.com/v3/repos/releases/

: Get \"https://api.github.com/repos/sonatype-nexus-community/nancy/releases\": net/http: TLS handshake timeout

For more information, check the log file at /root/.ossindex/nancy.combined.log
nancy version: 1.0.28

Usage:
nancy sleuth [flags]

Examples:
go list -json -deps | nancy sleuth --username your_user --token your_token
nancy sleuth -p Gopkg.lock --username your_user --token your_token

Flags:
-e, --exclude-vulnerability CveListFlag Comma separated list of CVEs or OSS Index IDs to exclude (default [])
-x, --exclude-vulnerability-file string Path to a file containing newline separated CVEs or OSS Index IDs to be excluded (default \"./.nancy-ignore\")
-h, --help help for sleuth
-n, --no-color indicate output should not be colorized
-o, --output string Styling for output format. json, json-pretty, text, csv (default \"text\")

Global Flags:
-v, -- count Set log level, multiple v's is more verbose
-d, --db-cache-path string Specify an alternate path for caching responses from OSS Inde, example: /tmp
--loud indicate output should include non-vulnerable packages
-p, --path string Specify a path to a dep Gopkg.lock file for scanning
-q, --quiet indicate output should contain only packages with vulnerabilities (default true)
--skip-update-check Skip the check for updates.
-t, --token string Specify OSS Index API token for request
-u, --username string Specify OSS Index username for request
-V, --version Get the version

go list -m: dmitri.shuralyov.com/gpu/mtl@v0.0.0-20190408044501-666a987793e9: Get \"https://proxy.golang.org/dmitri.shuralyov.com/gpu/mtl/@v/v0.0.0-20190408044501-666a987793e9.mod\": net/http: TLS handshake timeout`