diff --git a/internal/services/formatters/javascript/npmaudit/formatter_test.go b/internal/services/formatters/javascript/npmaudit/formatter_test.go index b4d55c64f..32be147b2 100644 --- a/internal/services/formatters/javascript/npmaudit/formatter_test.go +++ b/internal/services/formatters/javascript/npmaudit/formatter_test.go @@ -69,7 +69,7 @@ func TestNpmAuditParseOutput(t *testing.T) { assert.False(t, analysis.HasErrors(), "Expected no errors on analysis") }) - t.Run("Should add error on analysos when parse output with not found error", func(t *testing.T) { + t.Run("Should add error on analysis when parse output with not found error", func(t *testing.T) { analysis := new(analysis.Analysis) dockerAPIControllerMock := testutil.NewDockerMock() diff --git a/internal/services/formatters/javascript/yarnaudit/entities/finding.go b/internal/services/formatters/javascript/yarnaudit/finding.go similarity index 94% rename from internal/services/formatters/javascript/yarnaudit/entities/finding.go rename to internal/services/formatters/javascript/yarnaudit/finding.go index f9c3d6610..c26a9172f 100644 --- a/internal/services/formatters/javascript/yarnaudit/entities/finding.go +++ b/internal/services/formatters/javascript/yarnaudit/finding.go @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -package entities +package yarnaudit -type Finding struct { +type finding struct { Version string `json:"version"` } diff --git a/internal/services/formatters/javascript/yarnaudit/formatter.go b/internal/services/formatters/javascript/yarnaudit/formatter.go index 3636db902..8dbe3a0e9 100644 --- a/internal/services/formatters/javascript/yarnaudit/formatter.go +++ b/internal/services/formatters/javascript/yarnaudit/formatter.go @@ -29,11 +29,10 @@ import ( "github.com/ZupIT/horusec-devkit/pkg/enums/tools" "github.com/ZupIT/horusec-devkit/pkg/utils/logger" - dockerEntities "github.com/ZupIT/horusec/internal/entities/docker" + "github.com/ZupIT/horusec/internal/entities/docker" "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/javascript/yarnaudit/entities" vulnhash "github.com/ZupIT/horusec/internal/utils/vuln_hash" ) @@ -45,7 +44,7 @@ type Formatter struct { func NewFormatter(service formatters.IService) formatters.IFormatter { return &Formatter{ IService: service, - modules: map[string]bool{}, + modules: make(map[string]bool), } } @@ -71,8 +70,8 @@ func (f *Formatter) startYarnAudit(projectSubPath string) (string, error) { return output, f.parseOutput(output, projectSubPath) } -func (f *Formatter) getDockerConfig(projectSubPath string) *dockerEntities.AnalysisData { - analysisData := &dockerEntities.AnalysisData{ +func (f *Formatter) getDockerConfig(projectSubPath string) *docker.AnalysisData { + analysisData := &docker.AnalysisData{ CMD: f.GetConfigCMDByFileExtension(projectSubPath, CMD, "yarn.lock", tools.YarnAudit), Language: languages.Javascript, } @@ -95,74 +94,69 @@ func (f *Formatter) parseOutput(containerOutput, projectSubPath string) error { } func (f *Formatter) VerifyErrors(containerOutput string) error { - if f.IsNotFoundError(containerOutput) { + if f.isNotFoundError(containerOutput) { return errors.New(messages.MsgErrorYarnLockNotFound) } - if f.IsRunningError(containerOutput) { + if f.isRunningError(containerOutput) { return errors.New(messages.MsgErrorYarnProcess + containerOutput) } return nil } -func (f *Formatter) IsNotFoundError(containerOutput string) bool { +func (f *Formatter) isNotFoundError(containerOutput string) bool { return strings.Contains(containerOutput, "ERROR_YARN_LOCK_NOT_FOUND") } -func (f *Formatter) IsRunningError(containerOutput string) bool { +func (f *Formatter) isRunningError(containerOutput string) bool { return strings.Contains(containerOutput, "ERROR_RUNNING_YARN_AUDIT") } -func (f *Formatter) newContainerOutputFromString(containerOutput string) (output *entities.Output, err error) { +func (f *Formatter) newContainerOutputFromString(containerOutput string) (output *yarnOutput, err error) { if containerOutput == "" { logger.LogDebugWithLevel(messages.MsgDebugOutputEmpty, - map[string]interface{}{"tool": tools.YarnAudit.ToString()}) - return &entities.Output{}, nil + map[string]interface{}{"tool": tools.YarnAudit.ToString()}, + ) + return &yarnOutput{}, nil } return output, json.Unmarshal([]byte(containerOutput), &output) } -func (f *Formatter) processOutput(output *entities.Output, projectSubPath string) { +func (f *Formatter) processOutput(output *yarnOutput, projectSubPath string) { for _, advisory := range output.Advisories { if f.notContainsModule(advisory.ModuleName) { advisoryPointer := advisory - f.AddNewVulnerabilityIntoAnalysis(f.setVulnerabilitySeverityData(&advisoryPointer, projectSubPath)) + f.AddNewVulnerabilityIntoAnalysis(f.newVulnerability(&advisoryPointer, projectSubPath)) } } } -func (f *Formatter) setVulnerabilitySeverityData( - output *entities.Issue, projectSubPath string) *vulnerability.Vulnerability { - data := f.getDefaultVulnerabilitySeverity(projectSubPath) - data.Severity = output.GetSeverity() - data.Details = output.Overview - data.Code = output.ModuleName - data.Line = f.getVulnerabilityLineByName(data.Code, output.GetVersion(), data.File) - data = vulnhash.Bind(data) - return f.SetCommitAuthor(data) -} - -func (f *Formatter) getDefaultVulnerabilitySeverity(projectSubPath string) *vulnerability.Vulnerability { - vulnerabilitySeverity := &vulnerability.Vulnerability{} - vulnerabilitySeverity.SecurityTool = tools.YarnAudit - vulnerabilitySeverity.Language = languages.Javascript - vulnerabilitySeverity.File = f.GetFilepathFromFilename("yarn.lock", projectSubPath) - return vulnerabilitySeverity +func (f *Formatter) newVulnerability(output *issue, projectSubPath string) *vulnerability.Vulnerability { + vuln := &vulnerability.Vulnerability{ + SecurityTool: tools.YarnAudit, + Language: languages.Javascript, + File: f.GetFilepathFromFilename("yarn.lock", projectSubPath), + Severity: output.getSeverity(), + Details: output.Overview, + Code: output.ModuleName, + } + vuln.Line = f.getVulnerabilityLineByName(vuln.Code, output.getVersion(), vuln.File) + return f.SetCommitAuthor(vulnhash.Bind(vuln)) } -func (f *Formatter) getVulnerabilityLineByName(module, version, file string) string { - fileExisting, err := os.Open(filepath.Join(f.GetConfigProjectPath(), file)) +func (f *Formatter) getVulnerabilityLineByName(module, version, filename string) string { + file, err := os.Open(filepath.Join(f.GetConfigProjectPath(), filename)) if err != nil { return "" } defer func() { - logger.LogErrorWithLevel(messages.MsgErrorDeferFileClose, fileExisting.Close()) + logger.LogErrorWithLevel(messages.MsgErrorDeferFileClose, file.Close()) }() - return f.getLine(module, version, bufio.NewScanner(fileExisting)) + return f.getLine(module, version, bufio.NewScanner(file)) } func (f *Formatter) getLine(module, version string, scanner *bufio.Scanner) string { @@ -180,7 +174,7 @@ func (f *Formatter) getLine(module, version string, scanner *bufio.Scanner) stri } func (f *Formatter) validateIfExistNameInScannerText(scannerText, module, version string) bool { - for _, name := range f.mapPossibleExistingNames(module, version) { + for _, name := range f.possibleExistingNames(module, version) { if strings.Contains(strings.ToLower(scannerText), name) { return true } @@ -189,7 +183,7 @@ func (f *Formatter) validateIfExistNameInScannerText(scannerText, module, versio return false } -func (f *Formatter) mapPossibleExistingNames(module, version string) []string { +func (f *Formatter) possibleExistingNames(module, version string) []string { return []string{ strings.ToLower(fmt.Sprintf("%s@%s", module, version)), strings.ToLower(fmt.Sprintf("%s@~%s", module, version)), diff --git a/internal/services/formatters/javascript/yarnaudit/formatter_test.go b/internal/services/formatters/javascript/yarnaudit/formatter_test.go index a5fade0c8..dd5e7758a 100644 --- a/internal/services/formatters/javascript/yarnaudit/formatter_test.go +++ b/internal/services/formatters/javascript/yarnaudit/formatter_test.go @@ -18,149 +18,314 @@ import ( "errors" "testing" - entitiesAnalysis "github.com/ZupIT/horusec-devkit/pkg/entities/analysis" + "github.com/ZupIT/horusec-devkit/pkg/entities/analysis" + "github.com/ZupIT/horusec-devkit/pkg/enums/languages" "github.com/ZupIT/horusec-devkit/pkg/enums/tools" "github.com/stretchr/testify/assert" - cliConfig "github.com/ZupIT/horusec/config" + "github.com/ZupIT/horusec/config" "github.com/ZupIT/horusec/internal/entities/toolsconfig" - "github.com/ZupIT/horusec/internal/entities/workdir" "github.com/ZupIT/horusec/internal/services/formatters" "github.com/ZupIT/horusec/internal/utils/testutil" ) -func TestParseOutputYarn(t *testing.T) { - t.Run("Should run analysis with no errors", func(t *testing.T) { - analysis := &entitiesAnalysis.Analysis{} +func TestYarnAuditParseOutput(t *testing.T) { + t.Run("should add 1 vulnerabilities on analysis with no errors", func(t *testing.T) { + analysis := new(analysis.Analysis) + dockerAPIControllerMock := testutil.NewDockerMock() dockerAPIControllerMock.On("SetAnalysisID") - - config := &cliConfig.Config{} - config.WorkDir = &workdir.WorkDir{} - - output := "{\"advisories\":[{\"findings\":[{\"version\":\"4.0.0\",\"paths\":[\"express\"]}],\"id\":8,\"created\":\"2015-10-17T19:41:46.382Z\",\"updated\":\"2018-02-22T21:55:47.925Z\",\"deleted\":null,\"title\":\"No Charset in Content-Type Header\",\"found_by\":{\"name\":\"Pawe\u0142 Ha\u0142drzy\u0144ski\"},\"reported_by\":{\"name\":\"Pawe\u0142 Ha\u0142drzy\u0144ski\"},\"module_name\":\"express\",\"cves\":[\"CVE-2014-6393\"],\"vulnerable_versions\":\"<3.11 || >= 4 <4.5\",\"patched_versions\":\">=3.11 <4 || >=4.5\",\"overview\":\"Vulnerable versions of express do not specify a charset field in the content-type header while displaying 400 level response messages. The lack of enforcing user's browser to set correct charset, could be leveraged by an attacker to perform a cross-site scripting attack, using non-standard encodings, like UTF-7.\",\"recommendation\":\"For express 3.x, update express to version 3.11 or later.\\nFor express 4.x, update express to version 4.5 or later. \",\"references\":\"\",\"access\":\"public\",\"severity\":\"low\",\"cwe\":\"CWE-79\",\"metadata\":{\"module_type\":\"Network.Library\",\"exploitability\":2,\"affected_components\":\"\"},\"url\":\"https://npmjs.com/advisories/8\"},{\"findings\":[{\"version\":\"4.0.0\",\"paths\":[\"express\"]}],\"id\":8,\"created\":\"2015-10-17T19:41:46.382Z\",\"updated\":\"2018-02-22T21:55:47.925Z\",\"deleted\":null,\"title\":\"No Charset in Content-Type Header\",\"found_by\":{\"name\":\"Pawe\u0142 Ha\u0142drzy\u0144ski\"},\"reported_by\":{\"name\":\"Pawe\u0142 Ha\u0142drzy\u0144ski\"},\"module_name\":\"express\",\"cves\":[\"CVE-2014-6393\"],\"vulnerable_versions\":\"<3.11 || >= 4 <4.5\",\"patched_versions\":\">=3.11 <4 || >=4.5\",\"overview\":\"Vulnerable versions of express do not specify a charset field in the content-type header while displaying 400 level response messages. The lack of enforcing user's browser to set correct charset, could be leveraged by an attacker to perform a cross-site scripting attack, using non-standard encodings, like UTF-7.\",\"recommendation\":\"For express 3.x, update express to version 3.11 or later.\\nFor express 4.x, update express to version 4.5 or later. \",\"references\":\"\",\"access\":\"public\",\"severity\":\"moderate\",\"cwe\":\"CWE-79\",\"metadata\":{\"module_type\":\"Network.Library\",\"exploitability\":2,\"affected_components\":\"\"},\"url\":\"https://npmjs.com/advisories/8\"},{\"findings\":[{\"version\":\"4.0.0\",\"paths\":[\"express\"]}],\"id\":8,\"created\":\"2015-10-17T19:41:46.382Z\",\"updated\":\"2018-02-22T21:55:47.925Z\",\"deleted\":null,\"title\":\"No Charset in Content-Type Header\",\"found_by\":{\"name\":\"Pawe\u0142 Ha\u0142drzy\u0144ski\"},\"reported_by\":{\"name\":\"Pawe\u0142 Ha\u0142drzy\u0144ski\"},\"module_name\":\"express\",\"cves\":[\"CVE-2014-6393\"],\"vulnerable_versions\":\"<3.11 || >= 4 <4.5\",\"patched_versions\":\">=3.11 <4 || >=4.5\",\"overview\":\"Vulnerable versions of express do not specify a charset field in the content-type header while displaying 400 level response messages. The lack of enforcing user's browser to set correct charset, could be leveraged by an attacker to perform a cross-site scripting attack, using non-standard encodings, like UTF-7.\",\"recommendation\":\"For express 3.x, update express to version 3.11 or later.\\nFor express 4.x, update express to version 4.5 or later. \",\"references\":\"\",\"access\":\"public\",\"severity\":\"high\",\"cwe\":\"CWE-79\",\"metadata\":{\"module_type\":\"Network.Library\",\"exploitability\":2,\"affected_components\":\"\"},\"url\":\"https://npmjs.com/advisories/8\"},{\"findings\":[{\"version\":\"4.0.0\",\"paths\":[\"express\"]}],\"id\":8,\"created\":\"2015-10-17T19:41:46.382Z\",\"updated\":\"2018-02-22T21:55:47.925Z\",\"deleted\":null,\"title\":\"No Charset in Content-Type Header\",\"found_by\":{\"name\":\"Pawe\u0142 Ha\u0142drzy\u0144ski\"},\"reported_by\":{\"name\":\"Pawe\u0142 Ha\u0142drzy\u0144ski\"},\"module_name\":\"express\",\"cves\":[\"CVE-2014-6393\"],\"vulnerable_versions\":\"<3.11 || >= 4 <4.5\",\"patched_versions\":\">=3.11 <4 || >=4.5\",\"overview\":\"Vulnerable versions of express do not specify a charset field in the content-type header while displaying 400 level response messages. The lack of enforcing user's browser to set correct charset, could be leveraged by an attacker to perform a cross-site scripting attack, using non-standard encodings, like UTF-7.\",\"recommendation\":\"For express 3.x, update express to version 3.11 or later.\\nFor express 4.x, update express to version 4.5 or later. \",\"references\":\"\",\"access\":\"public\",\"severity\":\"test\",\"cwe\":\"CWE-79\",\"metadata\":{\"module_type\":\"Network.Library\",\"exploitability\":2,\"affected_components\":\"\"},\"url\":\"https://npmjs.com/advisories/8\"}],\"metadata\":{\"vulnerabilities\":{\"info\":0,\"low\":6,\"moderate\":6,\"high\":7,\"critical\":0},\"dependencies\":27,\"devDependencies\":0,\"optionalDependencies\":0,\"totalDependencies\":27}}" - dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(output, nil) - service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, config) + service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, newTestConfig(t, analysis)) formatter := NewFormatter(service) - formatter.StartAnalysis("") + assert.Len(t, analysis.AnalysisVulnerabilities, 1) - }) - t.Run("Should run analysis with output empty", func(t *testing.T) { - analysis := &entitiesAnalysis.Analysis{} - dockerAPIControllerMock := testutil.NewDockerMock() - dockerAPIControllerMock.On("SetAnalysisID") + for _, v := range analysis.AnalysisVulnerabilities { + vuln := v.Vulnerability + + assert.Equal(t, tools.YarnAudit, vuln.SecurityTool) + assert.Equal(t, languages.Javascript, vuln.Language) + assert.NotEmpty(t, vuln.Details, "Expected not empty details") + assert.NotEmpty(t, vuln.Code, "Expected not empty code") + assert.NotEmpty(t, vuln.File, "Expected not empty file name") + assert.NotEmpty(t, vuln.Line, "Expected not empty line") + assert.NotEmpty(t, vuln.Severity, "Expected not empty severity") - config := &cliConfig.Config{} - config.WorkDir = &workdir.WorkDir{} + } + }) - output := "" + t.Run("Should parse output empty with no errors", func(t *testing.T) { + analysis := new(analysis.Analysis) - dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(output, nil) + dockerAPIControllerMock := testutil.NewDockerMock() + dockerAPIControllerMock.On("SetAnalysisID") + dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return("", nil) - service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, config) + service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, newTestConfig(t, analysis)) formatter := NewFormatter(service) - formatter.StartAnalysis("") + assert.Len(t, analysis.AnalysisVulnerabilities, 0) + assert.False(t, analysis.HasErrors(), "Expected no errors on analysis") }) - t.Run("Should parse output with not found error", func(t *testing.T) { - analysis := &entitiesAnalysis.Analysis{} + t.Run("Should add error on analysis with not found error", func(t *testing.T) { + analysis := new(analysis.Analysis) + dockerAPIControllerMock := testutil.NewDockerMock() dockerAPIControllerMock.On("SetAnalysisID") + dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return("ERROR_YARN_LOCK_NOT_FOUND", nil) - config := &cliConfig.Config{} - config.WorkDir = &workdir.WorkDir{} - - output := "ERROR_YARN_LOCK_NOT_FOUND" - - dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(output, nil) - - service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, config) - + service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, newTestConfig(t, analysis)) formatter := NewFormatter(service) - formatter.StartAnalysis("") + assert.Len(t, analysis.AnalysisVulnerabilities, 0) + assert.True(t, analysis.HasErrors(), "Expected errors on analysis") }) - t.Run("Should parse output with audit error", func(t *testing.T) { - analysis := &entitiesAnalysis.Analysis{} + t.Run("Should add error on analysis with audit error", func(t *testing.T) { + analysis := new(analysis.Analysis) + dockerAPIControllerMock := testutil.NewDockerMock() dockerAPIControllerMock.On("SetAnalysisID") + dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return("ERROR_RUNNING_YARN_AUDIT", nil) - config := &cliConfig.Config{} - config.WorkDir = &workdir.WorkDir{} + service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, newTestConfig(t, analysis)) + formatter := NewFormatter(service) + formatter.StartAnalysis("") - output := "ERROR_RUNNING_YARN_AUDIT" + assert.Len(t, analysis.AnalysisVulnerabilities, 0) + assert.True(t, analysis.HasErrors(), "Expected errors on analysis") + }) - dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return(output, nil) + t.Run("Should add error on analysis when parse invalid output", func(t *testing.T) { + analysis := new(analysis.Analysis) - service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, config) + dockerAPIControllerMock := testutil.NewDockerMock() + dockerAPIControllerMock.On("SetAnalysisID") + dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return("invalid", nil) + service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, newTestConfig(t, analysis)) formatter := NewFormatter(service) - formatter.StartAnalysis("") - assert.Len(t, analysis.AnalysisVulnerabilities, 0) + + assert.True(t, analysis.HasErrors(), "Expected no errors on analysis") }) - t.Run("Should return error when executing container", func(t *testing.T) { - analysis := &entitiesAnalysis.Analysis{} + t.Run("should add error of executing container on analysis", func(t *testing.T) { + analysis := new(analysis.Analysis) + dockerAPIControllerMock := testutil.NewDockerMock() dockerAPIControllerMock.On("SetAnalysisID") dockerAPIControllerMock.On("CreateLanguageAnalysisContainer").Return("", errors.New("test")) - config := &cliConfig.Config{} - config.WorkDir = &workdir.WorkDir{} - - service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, config) - + service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, newTestConfig(t, analysis)) formatter := NewFormatter(service) - formatter.StartAnalysis("") + assert.Len(t, analysis.AnalysisVulnerabilities, 0) + assert.True(t, analysis.HasErrors(), "Expected errors on analysis") }) t.Run("Should not execute tool because it's ignored", func(t *testing.T) { - analysis := &entitiesAnalysis.Analysis{} + analysis := new(analysis.Analysis) dockerAPIControllerMock := testutil.NewDockerMock() - config := &cliConfig.Config{} - config.ToolsConfig = toolsconfig.ToolsConfig{ + cfg := newTestConfig(t, analysis) + cfg.ToolsConfig = toolsconfig.ToolsConfig{ tools.YarnAudit: toolsconfig.Config{ IsToIgnore: true, }, } - service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, config) + service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, cfg) formatter := NewFormatter(service) - formatter.StartAnalysis("") }) } -func TestParseOutputNpm(t *testing.T) { - t.Run("Should return error when invalid output", func(t *testing.T) { - analysis := &entitiesAnalysis.Analysis{} - dockerAPIControllerMock := testutil.NewDockerMock() - dockerAPIControllerMock.On("SetAnalysisID") - - config := &cliConfig.Config{} - config.WorkDir = &workdir.WorkDir{} - - service := formatters.NewFormatterService(analysis, dockerAPIControllerMock, config) - - formatter := Formatter{ - service, - map[string]bool{}, - } +func newTestConfig(t *testing.T, analysiss *analysis.Analysis) *config.Config { + cfg := config.New() + cfg.ProjectPath = testutil.CreateHorusecAnalysisDirectory(t, analysiss, testutil.JavaScriptExample2) + return cfg +} - err := formatter.parseOutput("invalid output", "") - assert.Error(t, err) - assert.Len(t, analysis.AnalysisVulnerabilities, 0) - }) +const output = ` +{ + "advisories": [ + { + "findings": [ + { + "version": "4.0.0", + "paths": [ + "express" + ] + } + ], + "id": 8, + "created": "2015-10-17T19:41:46.382Z", + "updated": "2018-02-22T21:55:47.925Z", + "deleted": null, + "title": "No Charset in Content-Type Header", + "found_by": { + "name": "Paweł Hałdrzyński" + }, + "reported_by": { + "name": "Paweł Hałdrzyński" + }, + "module_name": "express", + "cves": [ + "CVE-2014-6393" + ], + "vulnerable_versions": "<3.11 || >= 4 <4.5", + "patched_versions": ">=3.11 <4 || >=4.5", + "overview": "Vulnerable versions of express do not specify a charset field in the content-type header while displaying 400 level response messages. The lack of enforcing user's browser to set correct charset, could be leveraged by an attacker to perform a cross-site scripting attack, using non-standard encodings, like UTF-7.", + "recommendation": "For express 3.x, update express to version 3.11 or later.\nFor express 4.x, update express to version 4.5 or later. ", + "references": "", + "access": "public", + "severity": "low", + "cwe": "CWE-79", + "metadata": { + "module_type": "Network.Library", + "exploitability": 2, + "affected_components": "" + }, + "url": "https://npmjs.com/advisories/8" + }, + { + "findings": [ + { + "version": "4.0.0", + "paths": [ + "express" + ] + } + ], + "id": 8, + "created": "2015-10-17T19:41:46.382Z", + "updated": "2018-02-22T21:55:47.925Z", + "deleted": null, + "title": "No Charset in Content-Type Header", + "found_by": { + "name": "Paweł Hałdrzyński" + }, + "reported_by": { + "name": "Paweł Hałdrzyński" + }, + "module_name": "express", + "cves": [ + "CVE-2014-6393" + ], + "vulnerable_versions": "<3.11 || >= 4 <4.5", + "patched_versions": ">=3.11 <4 || >=4.5", + "overview": "Vulnerable versions of express do not specify a charset field in the content-type header while displaying 400 level response messages. The lack of enforcing user's browser to set correct charset, could be leveraged by an attacker to perform a cross-site scripting attack, using non-standard encodings, like UTF-7.", + "recommendation": "For express 3.x, update express to version 3.11 or later.\nFor express 4.x, update express to version 4.5 or later. ", + "references": "", + "access": "public", + "severity": "moderate", + "cwe": "CWE-79", + "metadata": { + "module_type": "Network.Library", + "exploitability": 2, + "affected_components": "" + }, + "url": "https://npmjs.com/advisories/8" + }, + { + "findings": [ + { + "version": "4.0.0", + "paths": [ + "express" + ] + } + ], + "id": 8, + "created": "2015-10-17T19:41:46.382Z", + "updated": "2018-02-22T21:55:47.925Z", + "deleted": null, + "title": "No Charset in Content-Type Header", + "found_by": { + "name": "Paweł Hałdrzyński" + }, + "reported_by": { + "name": "Paweł Hałdrzyński" + }, + "module_name": "express", + "cves": [ + "CVE-2014-6393" + ], + "vulnerable_versions": "<3.11 || >= 4 <4.5", + "patched_versions": ">=3.11 <4 || >=4.5", + "overview": "Vulnerable versions of express do not specify a charset field in the content-type header while displaying 400 level response messages. The lack of enforcing user's browser to set correct charset, could be leveraged by an attacker to perform a cross-site scripting attack, using non-standard encodings, like UTF-7.", + "recommendation": "For express 3.x, update express to version 3.11 or later.\nFor express 4.x, update express to version 4.5 or later. ", + "references": "", + "access": "public", + "severity": "high", + "cwe": "CWE-79", + "metadata": { + "module_type": "Network.Library", + "exploitability": 2, + "affected_components": "" + }, + "url": "https://npmjs.com/advisories/8" + }, + { + "findings": [ + { + "version": "4.0.0", + "paths": [ + "express" + ] + } + ], + "id": 8, + "created": "2015-10-17T19:41:46.382Z", + "updated": "2018-02-22T21:55:47.925Z", + "deleted": null, + "title": "No Charset in Content-Type Header", + "found_by": { + "name": "Paweł Hałdrzyński" + }, + "reported_by": { + "name": "Paweł Hałdrzyński" + }, + "module_name": "express", + "cves": [ + "CVE-2014-6393" + ], + "vulnerable_versions": "<3.11 || >= 4 <4.5", + "patched_versions": ">=3.11 <4 || >=4.5", + "overview": "Vulnerable versions of express do not specify a charset field in the content-type header while displaying 400 level response messages. The lack of enforcing user's browser to set correct charset, could be leveraged by an attacker to perform a cross-site scripting attack, using non-standard encodings, like UTF-7.", + "recommendation": "For express 3.x, update express to version 3.11 or later.\nFor express 4.x, update express to version 4.5 or later. ", + "references": "", + "access": "public", + "severity": "test", + "cwe": "CWE-79", + "metadata": { + "module_type": "Network.Library", + "exploitability": 2, + "affected_components": "" + }, + "url": "https://npmjs.com/advisories/8" + } + ], + "metadata": { + "vulnerabilities": { + "info": 0, + "low": 6, + "moderate": 6, + "high": 7, + "critical": 0 + }, + "dependencies": 27, + "devDependencies": 0, + "optionalDependencies": 0, + "totalDependencies": 27 + } } +` diff --git a/internal/services/formatters/javascript/yarnaudit/entities/issue.go b/internal/services/formatters/javascript/yarnaudit/issue.go similarity index 84% rename from internal/services/formatters/javascript/yarnaudit/entities/issue.go rename to internal/services/formatters/javascript/yarnaudit/issue.go index 546355d0f..3ffba30c4 100644 --- a/internal/services/formatters/javascript/yarnaudit/entities/issue.go +++ b/internal/services/formatters/javascript/yarnaudit/issue.go @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -package entities +package yarnaudit import ( "github.com/ZupIT/horusec-devkit/pkg/enums/severities" ) -type Issue struct { - Findings []Finding `json:"findings"` +type issue struct { + Findings []finding `json:"findings"` ID int `json:"id"` ModuleName string `json:"module_name"` VulnerableVersions string `json:"vulnerable_versions"` @@ -27,11 +27,11 @@ type Issue struct { Overview string `json:"overview"` } -func (i *Issue) GetSeverity() severities.Severity { +func (i *issue) getSeverity() severities.Severity { return i.mapSeverities()[i.Severity] } -func (i *Issue) mapSeverities() map[string]severities.Severity { +func (i *issue) mapSeverities() map[string]severities.Severity { return map[string]severities.Severity{ "critical": severities.Critical, "high": severities.High, @@ -42,7 +42,7 @@ func (i *Issue) mapSeverities() map[string]severities.Severity { } } -func (i *Issue) GetVersion() string { +func (i *issue) getVersion() string { if len(i.Findings) > 0 { return i.Findings[0].Version } diff --git a/internal/services/formatters/javascript/yarnaudit/entities/issue_test.go b/internal/services/formatters/javascript/yarnaudit/issue_test.go similarity index 72% rename from internal/services/formatters/javascript/yarnaudit/entities/issue_test.go rename to internal/services/formatters/javascript/yarnaudit/issue_test.go index 2a38df6bb..43d4ff5b4 100644 --- a/internal/services/formatters/javascript/yarnaudit/entities/issue_test.go +++ b/internal/services/formatters/javascript/yarnaudit/issue_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package entities +package yarnaudit import ( "testing" @@ -23,61 +23,61 @@ import ( func TestGetVersion(t *testing.T) { t.Run("should return finding version", func(t *testing.T) { - issue := Issue{ - Findings: []Finding{ + issue := issue{ + Findings: []finding{ { Version: "test", }, }, } - assert.Equal(t, "test", issue.GetVersion()) + assert.Equal(t, "test", issue.getVersion()) }) t.Run("should return no version", func(t *testing.T) { - issue := Issue{} - assert.Empty(t, issue.GetVersion()) + issue := issue{} + assert.Empty(t, issue.getVersion()) }) } func TestGetSeverity(t *testing.T) { t.Run("should return a low severity", func(t *testing.T) { - issue := Issue{ + issue := issue{ Severity: "low", } - assert.Equal(t, severities.Low, issue.GetSeverity()) + assert.Equal(t, severities.Low, issue.getSeverity()) }) t.Run("should return a medium severity", func(t *testing.T) { - issue := Issue{ + issue := issue{ Severity: "moderate", } - assert.Equal(t, severities.Medium, issue.GetSeverity()) + assert.Equal(t, severities.Medium, issue.getSeverity()) }) t.Run("should return a critical severity", func(t *testing.T) { - issue := Issue{ + issue := issue{ Severity: "critical", } - assert.Equal(t, severities.Critical, issue.GetSeverity()) + assert.Equal(t, severities.Critical, issue.getSeverity()) }) t.Run("should return a info severity", func(t *testing.T) { - issue := Issue{ + issue := issue{ Severity: "info", } - assert.Equal(t, severities.Info, issue.GetSeverity()) + assert.Equal(t, severities.Info, issue.getSeverity()) }) t.Run("should return a unknown severity", func(t *testing.T) { - issue := Issue{ + issue := issue{ Severity: "", } - assert.Equal(t, severities.Unknown, issue.GetSeverity()) + assert.Equal(t, severities.Unknown, issue.getSeverity()) }) } diff --git a/internal/services/formatters/javascript/yarnaudit/entities/metadata.go b/internal/services/formatters/javascript/yarnaudit/metadata.go similarity index 86% rename from internal/services/formatters/javascript/yarnaudit/entities/metadata.go rename to internal/services/formatters/javascript/yarnaudit/metadata.go index 4d637abe8..a35a90405 100644 --- a/internal/services/formatters/javascript/yarnaudit/entities/metadata.go +++ b/internal/services/formatters/javascript/yarnaudit/metadata.go @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -package entities +package yarnaudit -type Metadata struct { - Vulnerabilities Vulnerabilities `json:"vulnerabilities"` +type metadata struct { + Vulnerabilities vulnerabilities `json:"vulnerabilities"` } diff --git a/internal/services/formatters/javascript/yarnaudit/entities/output.go b/internal/services/formatters/javascript/yarnaudit/output.go similarity index 83% rename from internal/services/formatters/javascript/yarnaudit/entities/output.go rename to internal/services/formatters/javascript/yarnaudit/output.go index af5ebd0b4..4316a67db 100644 --- a/internal/services/formatters/javascript/yarnaudit/entities/output.go +++ b/internal/services/formatters/javascript/yarnaudit/output.go @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package entities +package yarnaudit -type Output struct { - Advisories []Issue `json:"advisories"` - Metadata Metadata `json:"metadata"` +type yarnOutput struct { + Advisories []issue `json:"advisories"` + Metadata metadata `json:"metadata"` } diff --git a/internal/services/formatters/javascript/yarnaudit/entities/vulnerabilities.go b/internal/services/formatters/javascript/yarnaudit/vulnerabilities.go similarity index 94% rename from internal/services/formatters/javascript/yarnaudit/entities/vulnerabilities.go rename to internal/services/formatters/javascript/yarnaudit/vulnerabilities.go index 7fc6ea94a..e423e21cd 100644 --- a/internal/services/formatters/javascript/yarnaudit/entities/vulnerabilities.go +++ b/internal/services/formatters/javascript/yarnaudit/vulnerabilities.go @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package entities +package yarnaudit -type Vulnerabilities struct { +type vulnerabilities struct { Info int `json:"info"` Low int `json:"low"` Moderate int `json:"moderate"`