Skip to content

Commit

Permalink
gitleaks:bugfix - updating formatter to gitleaks v8 (#1010)
Browse files Browse the repository at this point in the history
When the v8 version of gitaleks was released, the way to do an analysis
and the output of that analysis changed. This pr updates the formatter
to the new format and updates gitleaks to v8.3.0. It also contains some
improvements in the formatter code.

Signed-off-by: Nathan Martins <nathan.martins@zup.com.br>
  • Loading branch information
nathanmartinszup authored Mar 7, 2022
1 parent 078aff2 commit 29c7330
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 77 deletions.
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
}

0 comments on commit 29c7330

Please sign in to comment.