Skip to content
New issue

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

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

Already on GitHub? # to your account

gitleaks:bugfix - updating formatter to gitleaks v8 #1010

Merged
merged 1 commit into from
Mar 7, 2022
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 e2e/analysis/test_case.go
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,7 @@ func NewTestCase() []*TestCase {
fmt.Sprintf("{HORUSEC_CLI} %s - %s is finished in analysisID:", tools.GitLeaks, languages.Leaks),
fmt.Sprintf("{HORUSEC_CLI} Running %s - %s", tools.HorusecEngine, languages.Leaks),
fmt.Sprintf("{HORUSEC_CLI} %s - %s is finished in analysisID:", tools.HorusecEngine, languages.Leaks),
fmt.Sprintf("{HORUSEC_CLI} The current path it's not a valid git repository"),
},
OutputsNotContains: []string{
fmt.Sprintf("{HORUSEC_CLI} Something error went wrong in %s tool", tools.GitLeaks),
Expand Down
3 changes: 2 additions & 1 deletion internal/controllers/analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -452,5 +452,6 @@ func (a *Analyzer) isWarning(err string) bool {
return strings.Contains(err, messages.MsgErrorPacketJSONNotFound) ||
strings.Contains(err, messages.MsgErrorYarnLockNotFound) ||
strings.Contains(err, messages.MsgErrorGemLockNotFound) ||
strings.Contains(err, messages.MsgErrorNotFoundRequirementsTxt)
strings.Contains(err, messages.MsgErrorNotFoundRequirementsTxt) ||
strings.Contains(err, messages.MsgWarnPathIsInvalidGitRepository)
}
2 changes: 1 addition & 1 deletion internal/enums/images/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const (
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"
Leaks = "horuszup/horusec-leaks:v1.2.0"
PHP = "horuszup/horusec-php:v1.0.1"
Python = "horuszup/horusec-python:v1.0.0"
Ruby = "horuszup/horusec-ruby:v1.1.1"
Expand Down
1 change: 1 addition & 0 deletions internal/helpers/messages/warn.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,5 @@ const (
// TODO: Remove MsgWarnAnalysisContainsOutdatedHash before release v2.10.0
MsgWarnAnalysisContainsOutdatedHash = "{HORUSEC_CLI} YOUR CONFIGURATION FILE CONTAINS SOME HASHES THAT WILL NO " +
"LONGER BE VALID AS OF v2.10.0 IS RELEASED. PLEASE UPDATE YOUR CONFIGURATION FILE WITH THE FOLLOWING HASHES:"
MsgWarnPathIsInvalidGitRepository = "{HORUSEC_CLI} The current path it's not a valid git repository"
)
2 changes: 1 addition & 1 deletion internal/services/formatters/leaks/deployments/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

FROM zricethezav/gitleaks:v8.2.7
FROM zricethezav/gitleaks:v8.3.0

COPY ./internal/services/formatters/leaks/deployments/rules.toml /rules/rules.toml

Expand Down
16 changes: 9 additions & 7 deletions internal/services/formatters/leaks/gitleaks/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//nolint
package gitleaks

// CMD contains the necessary code to execute Gitleaks inside the container. The 'git config diff.renames 0' command
// it's necessary to avoid the 'inexact rename detection was skipped due to too many files' error in big projects.
const CMD = `
{{WORK_DIR}}
if ! gitleaks --config-path /rules/rules.toml --path . --leaks-exit-code 0 --format json --report /tmp/leaks-result.json &> /tmp/leaks-runner-output.txt; then
echo /tmp/leaks-runner-output.txt
else
cat /tmp/leaks-result.json
fi
{{WORK_DIR}}
git config diff.renames 0
if ! gitleaks detect -c /rules/rules.toml -f json -r /tmp/leaks.json --exit-code 0 &> /tmp/leaks-output.txt; then
cat /tmp/leaks-output.txt
else
cat /tmp/leaks.json
fi
`
105 changes: 50 additions & 55 deletions internal/services/formatters/leaks/gitleaks/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package gitleaks
import (
"encoding/json"
"errors"
"strconv"
"strings"

"github.com/ZupIT/horusec-devkit/pkg/entities/vulnerability"
Expand All @@ -29,7 +30,6 @@ import (
"github.com/ZupIT/horusec/internal/enums/images"
"github.com/ZupIT/horusec/internal/helpers/messages"
"github.com/ZupIT/horusec/internal/services/formatters"
"github.com/ZupIT/horusec/internal/services/formatters/leaks/gitleaks/entities"
vulnhash "github.com/ZupIT/horusec/internal/utils/vuln_hash"
)

Expand Down Expand Up @@ -62,78 +62,73 @@ func (f *Formatter) startGitLeaks(projectSubPath string) (string, error) {
return output, err
}

return output, f.formatOutputGitLeaks(output)
if err := f.checkOutputErrors(output); err != nil {
return output, err
}

return output, f.parseOutput(output)
}

func (f *Formatter) formatOutputGitLeaks(output string) error {
if output == "" || (len(output) >= 4 && output[:4] == "null") {
func (f *Formatter) getDockerConfig(projectSubPath string) *dockerEntities.AnalysisData {
analysisData := &dockerEntities.AnalysisData{
CMD: f.AddWorkDirInCmd(CMD, projectSubPath, tools.GitLeaks),
Language: languages.Leaks,
}

return analysisData.SetImage(f.GetCustomImageByLanguage(languages.Leaks), images.Leaks)
}

func (f *Formatter) parseOutput(output string) error {
issues := make([]*Issue, 0)

if err := json.Unmarshal([]byte(output), &issues); err != nil {
return err
}

if len(issues) == 0 {
logger.LogDebugWithLevel(messages.MsgDebugOutputEmpty,
map[string]interface{}{"tool": tools.GitLeaks.ToString()})
f.setGitLeaksOutPutInHorusecAnalysis([]entities.Issue{})
return nil
}

issues, err := f.parseOutputToIssues(output)
if err != nil {
return err
}
f.forEachIssueCreateNewVuln(issues)

f.setGitLeaksOutPutInHorusecAnalysis(issues)
return nil
}

func (f *Formatter) parseOutputToIssues(output string) ([]entities.Issue, error) {
var issues []entities.Issue
err := json.Unmarshal([]byte(output), &issues)
if err != nil && strings.Contains(err.Error(), "invalid character") {
err = errors.New(output)
func (f *Formatter) forEachIssueCreateNewVuln(issues []*Issue) {
for _, issue := range issues {
f.AddNewVulnerabilityIntoAnalysis(f.newVulnerability(issue))
}
return issues, err
}

func (f *Formatter) setGitLeaksOutPutInHorusecAnalysis(issues []entities.Issue) {
for key := range issues {
vuln := f.setupVulnerabilitiesSeveritiesGitLeaks(&issues[key])
f.AddNewVulnerabilityIntoAnalysis(vuln)
//nolint:funlen // necessary to be long
func (f *Formatter) newVulnerability(issue *Issue) *vulnerability.Vulnerability {
vuln := &vulnerability.Vulnerability{
Language: languages.Leaks,
SecurityTool: tools.GitLeaks,
Severity: severities.Critical,
RuleID: vulnhash.HashRuleID(issue.Description),
Details: issue.Description,
Code: f.GetCodeWithMaxCharacters(issue.Secret, 0),
File: issue.File,
Line: strconv.Itoa(issue.StartLine),
Column: strconv.Itoa(issue.StartColumn),
CommitAuthor: issue.Author,
CommitMessage: f.GetCodeWithMaxCharacters(issue.Message, 0),
CommitEmail: issue.Email,
CommitDate: issue.Date,
CommitHash: issue.Commit,
}
}

func (f *Formatter) setupVulnerabilitiesSeveritiesGitLeaks(issue *entities.Issue) (
vulnerabilitySeverity *vulnerability.Vulnerability,
) {
vulnerabilitySeverity = f.getDefaultSeverity()
vulnerabilitySeverity.Severity = severities.Critical
vulnerabilitySeverity.RuleID = vulnhash.HashRuleID(issue.Rule)
vulnerabilitySeverity.Details = issue.Rule
vulnerabilitySeverity.Code = f.GetCodeWithMaxCharacters(issue.Line, 0)
vulnerabilitySeverity.File = issue.File
vulnerabilitySeverity = vulnhash.Bind(vulnerabilitySeverity)
return f.setCommitAuthor(vulnerabilitySeverity, issue)
}

func (f *Formatter) setCommitAuthor(vuln *vulnerability.Vulnerability,
issue *entities.Issue,
) *vulnerability.Vulnerability {
vuln.CommitAuthor = issue.Author
vuln.CommitMessage = strings.ReplaceAll(issue.CommitMessage, "\n", "")
vuln.CommitEmail = issue.Email
vuln.CommitDate = issue.Date
vuln.CommitHash = issue.Commit
return vuln
return vulnhash.Bind(vuln)
}

func (f *Formatter) getDockerConfig(projectSubPath string) *dockerEntities.AnalysisData {
analysisData := &dockerEntities.AnalysisData{
CMD: f.AddWorkDirInCmd(CMD, projectSubPath, tools.GitLeaks),
Language: languages.Leaks,
func (f *Formatter) checkOutputErrors(output string) error {
if strings.Contains(output, "fatal: not a git repository") ||
strings.Contains(output, "fatal: cannot chdir to") {
return errors.New(messages.MsgWarnPathIsInvalidGitRepository)
}

return analysisData.SetImage(f.GetCustomImageByLanguage(languages.Leaks), images.Leaks)
}

func (f *Formatter) getDefaultSeverity() *vulnerability.Vulnerability {
vulnerabilitySeverity := &vulnerability.Vulnerability{}
vulnerabilitySeverity.Language = languages.Leaks
vulnerabilitySeverity.SecurityTool = tools.GitLeaks
return vulnerabilitySeverity
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package entities
package gitleaks

type Issue struct {
Line string `json:"line"`
Offender string `json:"offender"`
Commit string `json:"commit"`
Repo string `json:"repo"`
Rule string `json:"rule"`
CommitMessage string `json:"commitMessage"`
Author string `json:"author"`
Email string `json:"email"`
File string `json:"file"`
Date string `json:"date"`
Tags string `json:"tags"`
Description string
StartLine int
EndLine int
StartColumn int
EndColumn int
Match string
Secret string
File string
Commit string
Entropy int
Author string
Email string
Date string
Message string
}