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

brakeman:fix - search for Gemfile's before start analysis #877

Merged
merged 1 commit into from
Dec 21, 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
2 changes: 1 addition & 1 deletion internal/helpers/messages/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const (
MsgDebugConfigFileRunningOnPath = "{HORUSEC_CLI} Config file running on path: "
MsgDebugFolderOrFileIgnored = "{HORUSEC_CLI} The file or folder was ignored to send analysis:"
MsgDebugShowConfigs = "{HORUSEC_CLI} The current configuration for this analysis are:"
MsgDebugShowWorkdir = "{HORUSEC_CLI} The workdir setup for run in path:"
MsgDebugShowWorkdir = "{HORUSEC_CLI} Using path %s as workdir to run tool %s"
MsgDebugToolIgnored = "{HORUSEC_CLI} The tool was ignored for run in this analysis: "
MsgDebugVulnHashToFix = "{HORUSEC_CLI} Vulnerability Hash expected to be FIXED: "
MsgDebugDockerImageDoesNotExists = "{HORUSEC_CLI} Image %s does not exists. Pulling from registry"
Expand Down
7 changes: 6 additions & 1 deletion internal/services/formatters/ruby/brakeman/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/ZupIT/horusec/internal/enums/images"
"github.com/ZupIT/horusec/internal/helpers/messages"
"github.com/ZupIT/horusec/internal/services/formatters"
fileutils "github.com/ZupIT/horusec/internal/utils/file"
vulnhash "github.com/ZupIT/horusec/internal/utils/vuln_hash"
)

Expand Down Expand Up @@ -118,7 +119,11 @@ func (f *Formatter) newVulnerability(output *warning, projectSubPath string) *vu

func (f *Formatter) getDockerConfig(projectSubPath string) *docker.AnalysisData {
analysisData := &docker.AnalysisData{
CMD: f.AddWorkDirInCmd(CMD, projectSubPath, tools.Brakeman),
CMD: f.AddWorkDirInCmd(
CMD,
fileutils.GetSubPathByFilename(f.GetConfigProjectPath(), projectSubPath, "Gemfile"),
tools.Brakeman,
),
Language: languages.Ruby,
}

Expand Down
19 changes: 11 additions & 8 deletions internal/services/formatters/ruby/brakeman/formatter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,11 @@ func TestParseBrakemanOutput(t *testing.T) {
t.Run("Should success parse output to analysis", func(t *testing.T) {
analysis := new(analysis.Analysis)

cfg := config.New()
cfg.ProjectPath = testutil.CreateHorusecAnalysisDirectory(t, analysis, testutil.RubyExample1)

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

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

formatter := NewFormatter(service)
formatter.StartAnalysis("")
Expand Down Expand Up @@ -68,7 +65,7 @@ func TestParseBrakemanOutput(t *testing.T) {
dockerAPIControllerMock.On("SetAnalysisID")
dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return("", nil)

service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, config.New())
service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, newTestConfig(t, analysis))

formatter := NewFormatter(service)
formatter.StartAnalysis("")
Expand All @@ -86,7 +83,7 @@ func TestParseBrakemanOutput(t *testing.T) {

dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(output, nil)

service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, config.New())
service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, newTestConfig(t, analysis))

formatter := NewFormatter(service)
formatter.StartAnalysis("")
Expand All @@ -101,7 +98,7 @@ func TestParseBrakemanOutput(t *testing.T) {
dockerAPIControllerMock.On("SetAnalysisID")
dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return("invalid output", nil)

service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, config.New())
service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, newTestConfig(t, analysis))

formatter := NewFormatter(service)
formatter.StartAnalysis("")
Expand All @@ -116,7 +113,7 @@ func TestParseBrakemanOutput(t *testing.T) {
dockerAPIControllerMock.On("SetAnalysisID")
dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return("", errors.New("test"))

service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, config.New())
service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, newTestConfig(t, analysis))

formatter := NewFormatter(service)
formatter.StartAnalysis("")
Expand All @@ -143,6 +140,12 @@ func TestParseBrakemanOutput(t *testing.T) {
})
}

func newTestConfig(t *testing.T, analysis *analysis.Analysis) *config.Config {
cfg := config.New()
cfg.ProjectPath = testutil.CreateHorusecAnalysisDirectory(t, analysis, testutil.RubyExample)
return cfg
}

const outputMock = `
{
"warnings": [
Expand Down
2 changes: 1 addition & 1 deletion internal/services/formatters/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (s *Service) AddWorkDirInCmd(cmd, projectSubPath string, tool tools.Tool) s
// Since the command will run inside a Docker container we need
// to convert any Windows slash (\) to Unix slash (/).
projectSubPath = filepath.ToSlash(projectSubPath)
logger.LogDebugWithLevel(messages.MsgDebugShowWorkdir, tool.ToString(), projectSubPath)
logger.LogDebugWithLevel(fmt.Sprintf(messages.MsgDebugShowWorkdir, projectSubPath, tool.ToString()))
return strings.ReplaceAll(cmd, "{{WORK_DIR}}", fmt.Sprintf("cd %s", projectSubPath))
}

Expand Down
32 changes: 24 additions & 8 deletions internal/utils/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,20 @@ func GetPathFromFilename(filename, basePath string) string {
return filePath
}

func isSameExtensions(filename, path string) bool {
filenameExt := filepath.Ext(filename)
basePathExt := filepath.Ext(path)
return filenameExt == basePathExt
// GetSubPathByFilename works like GetSubPathByExtension but for filenames.
//
// The value returned will be the first path that contains a file with a given
// filename, otherwise will return an empty string.
func GetSubPathByFilename(projectPath, subPath, filename string) string {
pathToWalk := joinProjectPathWithSubPath(projectPath, subPath)
logger.LogDebugWithLevel(fmt.Sprintf("Seaching for files with %s name on %s", filename, pathToWalk))

if path := GetPathFromFilename(filename, pathToWalk); path != "" {
logger.LogDebugWithLevel(fmt.Sprintf("Found file %s on %s", filename, path))
return filepath.Dir(path)
}

return ""
}

// ReplacePathSeparator replace slashes from path to OS specific.
Expand Down Expand Up @@ -115,10 +125,6 @@ func GetSubPathByExtension(projectPath, subPath, ext string) (extensionPath stri
return ""
}

func buildPattern(ext string) string {
return "*" + ext
}

// relativeDirIfPathMatch return relative directory of path based on projectPath
// if path extension match ext.
func relativeDirIfPathMatch(projectPath, path, ext string) string {
Expand Down Expand Up @@ -316,3 +322,13 @@ func CreateAndWriteFile(input, filename string) error {
_, err = file.WriteString(input)
return err
}

func isSameExtensions(filename, path string) bool {
filenameExt := filepath.Ext(filename)
basePathExt := filepath.Ext(path)
return filenameExt == basePathExt
}

func buildPattern(ext string) string {
return "*" + ext
}