github.com/jaylevin/jenkins-library@v1.230.4/cmd/checkmarxExecuteScan_test.go (about) 1 package cmd 2 3 import ( 4 "archive/zip" 5 "bytes" 6 "encoding/json" 7 "fmt" 8 "io/ioutil" 9 "os" 10 "path/filepath" 11 "strconv" 12 "strings" 13 "testing" 14 "time" 15 16 "github.com/bmatcuk/doublestar" 17 18 "github.com/SAP/jenkins-library/pkg/checkmarx" 19 piperGithub "github.com/SAP/jenkins-library/pkg/github" 20 "github.com/stretchr/testify/assert" 21 ) 22 23 type fileInfo struct { 24 nam string // base name of the file 25 siz int64 // length in bytes for regular files; system-dependent for others 26 mod os.FileMode // file mode bits 27 modtime time.Time // modification time 28 dir bool // abbreviation for Mode().IsDir() 29 syss interface{} // underlying data source (can return nil) 30 } 31 32 func (fi fileInfo) IsDir() bool { 33 return fi.dir 34 } 35 func (fi fileInfo) Name() string { 36 return fi.nam 37 } 38 func (fi fileInfo) Size() int64 { 39 return fi.siz 40 } 41 func (fi fileInfo) ModTime() time.Time { 42 return fi.modtime 43 } 44 func (fi fileInfo) Mode() os.FileMode { 45 return fi.mod 46 } 47 func (fi fileInfo) Sys() interface{} { 48 return fi.syss 49 } 50 51 type systemMock struct { 52 response interface{} 53 isIncremental bool 54 isPublic bool 55 forceScan bool 56 createProject bool 57 previousPName string 58 getPresetsCalled bool 59 updateProjectConfigurationCalled bool 60 } 61 62 func (sys *systemMock) FilterPresetByName(_ []checkmarx.Preset, presetName string) checkmarx.Preset { 63 if presetName == "CX_Default" { 64 return checkmarx.Preset{ID: 16, Name: "CX_Default", OwnerName: "16"} 65 } 66 return checkmarx.Preset{ID: 10050, Name: "SAP_JS_Default", OwnerName: "16"} 67 } 68 func (sys *systemMock) FilterPresetByID([]checkmarx.Preset, int) checkmarx.Preset { 69 return checkmarx.Preset{ID: 10048, Name: "SAP_Default", OwnerName: "16"} 70 } 71 func (sys *systemMock) FilterProjectByName([]checkmarx.Project, string) checkmarx.Project { 72 return checkmarx.Project{ID: 1, Name: "Test", TeamID: "16", IsPublic: true} 73 } 74 func (sys *systemMock) GetProjectByID(projectID int) (checkmarx.Project, error) { 75 if projectID == 17 { 76 return checkmarx.Project{ID: 17, Name: "Test_PR-17", TeamID: "16", IsPublic: true}, nil 77 } 78 return checkmarx.Project{ID: 19, Name: "Test_PR-19", TeamID: "16", IsPublic: true}, nil 79 } 80 81 func (sys *systemMock) GetProjectsByNameAndTeam(projectName, teamID string) ([]checkmarx.Project, error) { 82 if !sys.createProject || sys.previousPName == projectName { 83 if strings.Contains(projectName, "PR-17") { 84 return []checkmarx.Project{{ID: 17, Name: projectName, TeamID: teamID, IsPublic: true}}, nil 85 } 86 return []checkmarx.Project{{ID: 19, Name: projectName, TeamID: teamID, IsPublic: true}}, nil 87 } 88 if projectName == "Test" { 89 return []checkmarx.Project{{ID: 1, Name: projectName, TeamID: teamID, IsPublic: true}}, nil 90 } 91 sys.previousPName = projectName 92 return []checkmarx.Project{}, fmt.Errorf("no project error") 93 } 94 func (sys *systemMock) FilterTeamByName(_ []checkmarx.Team, teamName string) (checkmarx.Team, error) { 95 if teamName == "OpenSource/Cracks/16" { 96 return checkmarx.Team{ID: json.RawMessage(`"16"`), FullName: "OpenSource/Cracks/16"}, nil 97 } 98 return checkmarx.Team{ID: json.RawMessage(`15`), FullName: "OpenSource/Cracks/15"}, nil 99 } 100 func (sys *systemMock) FilterTeamByID(_ []checkmarx.Team, teamID json.RawMessage) checkmarx.Team { 101 teamIDBytes, _ := teamID.MarshalJSON() 102 if bytes.Compare(teamIDBytes, []byte(`"16"`)) == 0 { 103 return checkmarx.Team{ID: json.RawMessage(`"16"`), FullName: "OpenSource/Cracks/16"} 104 } 105 return checkmarx.Team{ID: json.RawMessage(`15`), FullName: "OpenSource/Cracks/15"} 106 } 107 func (sys *systemMock) DownloadReport(int) ([]byte, error) { 108 return sys.response.([]byte), nil 109 } 110 func (sys *systemMock) GetReportStatus(int) (checkmarx.ReportStatusResponse, error) { 111 return checkmarx.ReportStatusResponse{Status: checkmarx.ReportStatus{ID: 2, Value: "Created"}}, nil 112 } 113 func (sys *systemMock) RequestNewReport(int, string) (checkmarx.Report, error) { 114 return checkmarx.Report{ReportID: 17}, nil 115 } 116 func (sys *systemMock) GetResults(int) checkmarx.ResultsStatistics { 117 return checkmarx.ResultsStatistics{} 118 } 119 func (sys *systemMock) GetScans(int) ([]checkmarx.ScanStatus, error) { 120 return []checkmarx.ScanStatus{{IsIncremental: true}, {IsIncremental: true}, {IsIncremental: true}, {IsIncremental: false}}, nil 121 } 122 func (sys *systemMock) GetScanStatusAndDetail(int) (string, checkmarx.ScanStatusDetail) { 123 return "Finished", checkmarx.ScanStatusDetail{Stage: "Step 1 of 25", Step: "Scan something"} 124 } 125 func (sys *systemMock) ScanProject(_ int, isIncrementalV, isPublicV, forceScanV bool) (checkmarx.Scan, error) { 126 sys.isIncremental = isIncrementalV 127 sys.isPublic = isPublicV 128 sys.forceScan = forceScanV 129 return checkmarx.Scan{ID: 16}, nil 130 } 131 func (sys *systemMock) UpdateProjectConfiguration(int, int, string) error { 132 sys.updateProjectConfigurationCalled = true 133 return nil 134 } 135 func (sys *systemMock) UpdateProjectExcludeSettings(int, string, string) error { 136 return nil 137 } 138 func (sys *systemMock) UploadProjectSourceCode(int, string) error { 139 return nil 140 } 141 func (sys *systemMock) CreateProject(string, string) (checkmarx.ProjectCreateResult, error) { 142 return checkmarx.ProjectCreateResult{ID: 20}, nil 143 } 144 func (sys *systemMock) CreateBranch(int, string) int { 145 return 18 146 } 147 func (sys *systemMock) GetShortDescription(int, int) (checkmarx.ShortDescription, error) { 148 return checkmarx.ShortDescription{Text: "dummyText"}, nil 149 } 150 func (sys *systemMock) GetPresets() []checkmarx.Preset { 151 sys.getPresetsCalled = true 152 return []checkmarx.Preset{{ID: 10078, Name: "SAP Java Default", OwnerName: "16"}, {ID: 10048, Name: "SAP JS Default", OwnerName: "16"}, {ID: 16, Name: "CX_Default", OwnerName: "16"}} 153 } 154 func (sys *systemMock) GetProjects() ([]checkmarx.Project, error) { 155 return []checkmarx.Project{{ID: 15, Name: "OtherTest", TeamID: "16"}, {ID: 1, Name: "Test", TeamID: "16"}}, nil 156 } 157 func (sys *systemMock) GetTeams() []checkmarx.Team { 158 return []checkmarx.Team{{ID: json.RawMessage(`"16"`), FullName: "OpenSource/Cracks/16"}, {ID: json.RawMessage(`15`), FullName: "OpenSource/Cracks/15"}} 159 } 160 161 type systemMockForExistingProject struct { 162 response interface{} 163 isIncremental bool 164 isPublic bool 165 forceScan bool 166 scanProjectCalled bool 167 } 168 169 func (sys *systemMockForExistingProject) FilterPresetByName([]checkmarx.Preset, string) checkmarx.Preset { 170 return checkmarx.Preset{ID: 10050, Name: "SAP_JS_Default", OwnerName: "16"} 171 } 172 func (sys *systemMockForExistingProject) FilterPresetByID([]checkmarx.Preset, int) checkmarx.Preset { 173 return checkmarx.Preset{ID: 10048, Name: "SAP_Default", OwnerName: "16"} 174 } 175 func (sys *systemMockForExistingProject) FilterProjectByName([]checkmarx.Project, string) checkmarx.Project { 176 return checkmarx.Project{ID: 1, Name: "TestExisting", TeamID: "16", IsPublic: true} 177 } 178 func (sys *systemMockForExistingProject) GetProjectByID(int) (checkmarx.Project, error) { 179 return checkmarx.Project{}, nil 180 } 181 func (sys *systemMockForExistingProject) GetProjectsByNameAndTeam(projectName, teamID string) ([]checkmarx.Project, error) { 182 return []checkmarx.Project{{ID: 19, Name: projectName, TeamID: teamID, IsPublic: true}}, nil 183 } 184 func (sys *systemMockForExistingProject) FilterTeamByName([]checkmarx.Team, string) (checkmarx.Team, error) { 185 return checkmarx.Team{ID: json.RawMessage(`"16"`), FullName: "OpenSource/Cracks/16"}, nil 186 } 187 func (sys *systemMockForExistingProject) FilterTeamByID([]checkmarx.Team, json.RawMessage) checkmarx.Team { 188 return checkmarx.Team{ID: json.RawMessage(`"15"`), FullName: "OpenSource/Cracks/15"} 189 } 190 func (sys *systemMockForExistingProject) DownloadReport(int) ([]byte, error) { 191 return sys.response.([]byte), nil 192 } 193 func (sys *systemMockForExistingProject) GetReportStatus(int) (checkmarx.ReportStatusResponse, error) { 194 return checkmarx.ReportStatusResponse{Status: checkmarx.ReportStatus{ID: 2, Value: "Created"}}, nil 195 } 196 func (sys *systemMockForExistingProject) RequestNewReport(int, string) (checkmarx.Report, error) { 197 return checkmarx.Report{ReportID: 17}, nil 198 } 199 func (sys *systemMockForExistingProject) GetResults(int) checkmarx.ResultsStatistics { 200 return checkmarx.ResultsStatistics{} 201 } 202 func (sys *systemMockForExistingProject) GetScans(int) ([]checkmarx.ScanStatus, error) { 203 return []checkmarx.ScanStatus{{IsIncremental: true}, {IsIncremental: true}, {IsIncremental: true}, {IsIncremental: false}}, nil 204 } 205 func (sys *systemMockForExistingProject) GetShortDescription(int, int) (checkmarx.ShortDescription, error) { 206 return checkmarx.ShortDescription{Text: "dummyText"}, nil 207 } 208 func (sys *systemMockForExistingProject) GetScanStatusAndDetail(int) (string, checkmarx.ScanStatusDetail) { 209 return "Finished", checkmarx.ScanStatusDetail{Stage: "", Step: ""} 210 } 211 func (sys *systemMockForExistingProject) ScanProject(_ int, isIncrementalV, isPublicV, forceScanV bool) (checkmarx.Scan, error) { 212 sys.scanProjectCalled = true 213 sys.isIncremental = isIncrementalV 214 sys.isPublic = isPublicV 215 sys.forceScan = forceScanV 216 return checkmarx.Scan{ID: 16}, nil 217 } 218 func (sys *systemMockForExistingProject) UpdateProjectConfiguration(int, int, string) error { 219 return nil 220 } 221 func (sys *systemMockForExistingProject) UpdateProjectExcludeSettings(int, string, string) error { 222 return nil 223 } 224 func (sys *systemMockForExistingProject) UploadProjectSourceCode(int, string) error { 225 return nil 226 } 227 func (sys *systemMockForExistingProject) CreateProject(string, string) (checkmarx.ProjectCreateResult, error) { 228 return checkmarx.ProjectCreateResult{}, fmt.Errorf("create project error") 229 } 230 func (sys *systemMockForExistingProject) CreateBranch(int, string) int { 231 return 0 232 } 233 func (sys *systemMockForExistingProject) GetPresets() []checkmarx.Preset { 234 return []checkmarx.Preset{{ID: 10078, Name: "SAP_Java_Default", OwnerName: "16"}, {ID: 10048, Name: "SAP_JS_Default", OwnerName: "16"}} 235 } 236 func (sys *systemMockForExistingProject) GetProjects() ([]checkmarx.Project, error) { 237 return []checkmarx.Project{{ID: 1, Name: "TestExisting", TeamID: "16"}}, nil 238 } 239 func (sys *systemMockForExistingProject) GetTeams() []checkmarx.Team { 240 return []checkmarx.Team{{ID: json.RawMessage(`"16"`), FullName: "OpenSource/Cracks/16"}, {ID: json.RawMessage(`"15"`), FullName: "OpenSource/Cracks/15"}} 241 } 242 243 type checkmarxExecuteScanUtilsMock struct { 244 errorOnFileInfoHeader bool 245 errorOnStat bool 246 errorOnOpen bool 247 errorOnWriteFile bool 248 errorOnPathMatch bool 249 workspace string 250 ghCreateIssueOptions *piperGithub.CreateIssueOptions 251 ghCreateIssueError error 252 } 253 254 func newCheckmarxExecuteScanUtilsMock() checkmarxExecuteScanUtilsMock { 255 return checkmarxExecuteScanUtilsMock{} 256 } 257 258 func (c checkmarxExecuteScanUtilsMock) GetWorkspace() string { 259 return c.workspace 260 } 261 262 func (c checkmarxExecuteScanUtilsMock) PathMatch(pattern, name string) (bool, error) { 263 if c.errorOnPathMatch { 264 return false, fmt.Errorf("error on PathMatch") 265 } 266 return doublestar.PathMatch(pattern, name) 267 } 268 269 func (c checkmarxExecuteScanUtilsMock) WriteFile(filename string, data []byte, perm os.FileMode) error { 270 if c.errorOnWriteFile { 271 return fmt.Errorf("error on WriteFile") 272 } 273 return ioutil.WriteFile(filename, data, perm) 274 } 275 276 func (c checkmarxExecuteScanUtilsMock) FileInfoHeader(fi os.FileInfo) (*zip.FileHeader, error) { 277 if c.errorOnFileInfoHeader { 278 return nil, fmt.Errorf("error on FileInfoHeader") 279 } 280 return zip.FileInfoHeader(fi) 281 } 282 283 func (c checkmarxExecuteScanUtilsMock) Stat(name string) (os.FileInfo, error) { 284 if c.errorOnStat { 285 return nil, fmt.Errorf("error on Stat") 286 } 287 return os.Stat(name) 288 } 289 290 func (c checkmarxExecuteScanUtilsMock) Open(name string) (*os.File, error) { 291 if c.errorOnOpen { 292 return nil, fmt.Errorf("error on Open") 293 } 294 return os.Open(name) 295 } 296 297 func (c checkmarxExecuteScanUtilsMock) CreateIssue(ghCreateIssueOptions *piperGithub.CreateIssueOptions) error { 298 if c.ghCreateIssueError != nil { 299 return c.ghCreateIssueError 300 } 301 c.ghCreateIssueOptions = ghCreateIssueOptions 302 return nil 303 } 304 305 func TestFilterFileGlob(t *testing.T) { 306 t.Parallel() 307 tt := []struct { 308 input string 309 fInfo fileInfo 310 expected bool 311 }{ 312 {input: filepath.Join("somepath", "node_modules", "someOther", "some.file"), fInfo: fileInfo{}, expected: true}, 313 {input: filepath.Join("somepath", "non_modules", "someOther", "some.go"), fInfo: fileInfo{}, expected: false}, 314 {input: filepath.Join(".xmake", "someOther", "some.go"), fInfo: fileInfo{}, expected: true}, 315 {input: filepath.Join("another", "vendor", "some.html"), fInfo: fileInfo{}, expected: false}, 316 {input: filepath.Join("another", "vendor", "some.pdf"), fInfo: fileInfo{}, expected: true}, 317 {input: filepath.Join("another", "vendor", "some.test"), fInfo: fileInfo{}, expected: true}, 318 {input: filepath.Join("some.test"), fInfo: fileInfo{}, expected: false}, 319 {input: filepath.Join("a", "b", "c"), fInfo: fileInfo{dir: true}, expected: false}, 320 } 321 322 for k, v := range tt { 323 result, err := isFileNotMatchingPattern([]string{"!**/node_modules/**", "!**/.xmake/**", "!**/*_test.go", "!**/vendor/**/*.go", "**/*.go", "**/*.html", "*.test"}, v.input, v.fInfo, newCheckmarxExecuteScanUtilsMock()) 324 assert.Equal(t, v.expected, result, fmt.Sprintf("wrong result for run %v", k)) 325 assert.NoError(t, err, "no error expected in run %v", k) 326 } 327 } 328 329 func TestFilterFileGlob_errorOnPathMatch(t *testing.T) { 330 t.Parallel() 331 332 utilsMock := newCheckmarxExecuteScanUtilsMock() 333 utilsMock.errorOnPathMatch = true 334 335 result, err := isFileNotMatchingPattern([]string{"!**/node_modules/**", "!**/.xmake/**", "!**/*_test.go", "!**/vendor/**/*.go", "**/*.go", "**/*.html", "*.test"}, filepath.Join("a", "b", "c"), fileInfo{}, utilsMock) 336 assert.Equal(t, false, result, fmt.Sprintf("wrong result")) 337 assert.EqualError(t, err, "Pattern **/node_modules/** could not get executed: error on PathMatch") 338 } 339 340 func TestZipFolder(t *testing.T) { 341 t.Parallel() 342 343 t.Run("zip files successfully", func(t *testing.T) { 344 t.Parallel() 345 dir, err := ioutil.TempDir("", "test zip files") 346 if err != nil { 347 t.Fatal("Failed to create temporary directory") 348 } 349 // clean up tmp dir 350 defer os.RemoveAll(dir) 351 352 err = ioutil.WriteFile(filepath.Join(dir, "abcd.go"), []byte("abcd.go"), 0700) 353 assert.NoError(t, err) 354 err = ioutil.WriteFile(filepath.Join(dir, "abcd.yaml"), []byte("abcd.yaml"), 0700) 355 assert.NoError(t, err) 356 err = os.Mkdir(filepath.Join(dir, "somepath"), 0700) 357 assert.NoError(t, err) 358 err = ioutil.WriteFile(filepath.Join(dir, "somepath", "abcd.txt"), []byte("somepath/abcd.txt"), 0700) 359 assert.NoError(t, err) 360 err = ioutil.WriteFile(filepath.Join(dir, "abcd_test.go"), []byte("abcd_test.go"), 0700) 361 assert.NoError(t, err) 362 err = ioutil.WriteFile(filepath.Join(dir, "abc_test.go"), []byte("abc_test.go"), 0700) 363 assert.NoError(t, err) 364 365 var zipFileMock bytes.Buffer 366 err = zipFolder(dir, &zipFileMock, []string{"!**/abc_test.txt", "!**/abcd.yaml", "**/abcd.*"}, newCheckmarxExecuteScanUtilsMock()) 367 assert.NoError(t, err) 368 369 zipString := zipFileMock.String() 370 371 //assert.Equal(t, 724, zipFileMock.Len(), "Expected length of 724, but got %v", zipFileMock.Len()) 372 assert.True(t, strings.Contains(zipString, "abcd.go"), "Expected 'abcd.go' contained") 373 assert.True(t, strings.Contains(zipString, filepath.Join("somepath", "abcd.txt")), "Expected 'somepath/abcd.txt' contained") 374 assert.False(t, strings.Contains(zipString, "abcd_test.go"), "Not expected 'abcd_test.go' contained") 375 assert.False(t, strings.Contains(zipString, "abcd.yaml"), "Not expected 'abcd.yaml' contained") 376 assert.False(t, strings.Contains(zipString, "abc_test.go"), "Not expected 'abc_test.go' contained") 377 }) 378 379 t.Run("error on query file info header", func(t *testing.T) { 380 t.Parallel() 381 dir, err := ioutil.TempDir("", "test zip files") 382 if err != nil { 383 t.Fatal("Failed to create temporary directory") 384 } 385 // clean up tmp dir 386 defer os.RemoveAll(dir) 387 388 err = ioutil.WriteFile(filepath.Join(dir, "abcd.go"), []byte("abcd.go"), 0700) 389 assert.NoError(t, err) 390 err = os.Mkdir(filepath.Join(dir, "somepath"), 0700) 391 assert.NoError(t, err) 392 err = ioutil.WriteFile(filepath.Join(dir, "somepath", "abcd.txt"), []byte("somepath/abcd.txt"), 0700) 393 assert.NoError(t, err) 394 err = ioutil.WriteFile(filepath.Join(dir, "abcd_test.go"), []byte("abcd_test.go"), 0700) 395 assert.NoError(t, err) 396 err = ioutil.WriteFile(filepath.Join(dir, "abc_test.go"), []byte("abc_test.go"), 0700) 397 assert.NoError(t, err) 398 399 var zipFileMock bytes.Buffer 400 mock := newCheckmarxExecuteScanUtilsMock() 401 mock.errorOnFileInfoHeader = true 402 err = zipFolder(dir, &zipFileMock, []string{"!**/abc_test.txt", "**/abcd.*"}, mock) 403 404 assert.EqualError(t, err, "error on FileInfoHeader") 405 }) 406 407 t.Run("error on os stat", func(t *testing.T) { 408 t.Parallel() 409 dir, err := ioutil.TempDir("", "test zip files") 410 if err != nil { 411 t.Fatal("Failed to create temporary directory") 412 } 413 // clean up tmp dir 414 defer os.RemoveAll(dir) 415 416 err = ioutil.WriteFile(filepath.Join(dir, "abcd.go"), []byte("abcd.go"), 0700) 417 assert.NoError(t, err) 418 err = os.Mkdir(filepath.Join(dir, "somepath"), 0700) 419 assert.NoError(t, err) 420 err = ioutil.WriteFile(filepath.Join(dir, "somepath", "abcd.txt"), []byte("somepath/abcd.txt"), 0700) 421 assert.NoError(t, err) 422 err = ioutil.WriteFile(filepath.Join(dir, "abcd_test.go"), []byte("abcd_test.go"), 0700) 423 assert.NoError(t, err) 424 err = ioutil.WriteFile(filepath.Join(dir, "abc_test.go"), []byte("abc_test.go"), 0700) 425 assert.NoError(t, err) 426 427 var zipFileMock bytes.Buffer 428 mock := newCheckmarxExecuteScanUtilsMock() 429 mock.errorOnStat = true 430 err = zipFolder(dir, &zipFileMock, []string{"!**/abc_test.txt", "**/abcd.*"}, mock) 431 432 assert.NoError(t, err) 433 }) 434 435 t.Run("error on os Open", func(t *testing.T) { 436 t.Parallel() 437 dir, err := ioutil.TempDir("", "test zip files") 438 if err != nil { 439 t.Fatal("Failed to create temporary directory") 440 } 441 // clean up tmp dir 442 defer os.RemoveAll(dir) 443 444 err = ioutil.WriteFile(filepath.Join(dir, "abcd.go"), []byte("abcd.go"), 0700) 445 assert.NoError(t, err) 446 err = os.Mkdir(filepath.Join(dir, "somepath"), 0700) 447 assert.NoError(t, err) 448 err = ioutil.WriteFile(filepath.Join(dir, "somepath", "abcd.txt"), []byte("somepath/abcd.txt"), 0700) 449 assert.NoError(t, err) 450 err = ioutil.WriteFile(filepath.Join(dir, "abcd_test.go"), []byte("abcd_test.go"), 0700) 451 assert.NoError(t, err) 452 err = ioutil.WriteFile(filepath.Join(dir, "abc_test.go"), []byte("abc_test.go"), 0700) 453 assert.NoError(t, err) 454 455 var zipFileMock bytes.Buffer 456 mock := newCheckmarxExecuteScanUtilsMock() 457 mock.errorOnOpen = true 458 err = zipFolder(dir, &zipFileMock, []string{"!**/abc_test.txt", "**/abcd.*"}, mock) 459 460 assert.EqualError(t, err, "error on Open") 461 }) 462 } 463 464 func TestGetDetailedResults(t *testing.T) { 465 t.Parallel() 466 467 t.Run("success case", func(t *testing.T) { 468 t.Parallel() 469 sys := &systemMock{response: []byte(`<?xml version="1.0" encoding="utf-8"?> 470 <CxXMLResults InitiatorName="admin" Owner="admin" ScanId="1000005" ProjectId="2" ProjectName="Project 1" TeamFullPathOnReportDate="CxServer" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2" ScanStart="Sunday, December 3, 2017 4:50:34 PM" Preset="Checkmarx Default" ScanTime="00h:03m:18s" LinesOfCodeScanned="6838" FilesScanned="34" ReportCreationTime="Sunday, December 3, 2017 6:13:45 PM" Team="CxServer" CheckmarxVersion="8.6.0" ScanComments="" ScanType="Incremental" SourceOrigin="LocalPath" Visibility="Public"> 471 <Query id="430" categories="PCI DSS v3.2;PCI DSS (3.2) - 6.5.1 - Injection flaws - particularly SQL injection,OWASP Top 10 2013;A1-Injection,FISMA 2014;System And Information Integrity,NIST SP 800-53;SI-10 Information Input Validation (P1),OWASP Top 10 2017;A1-Injection" cweId="89" name="SQL_Injection" group="CSharp_High_Risk" Severity="High" Language="CSharp" LanguageHash="1363215419077432" LanguageChangeDate="2017-12-03T00:00:00.0000000" SeverityIndex="3" QueryPath="CSharp\Cx\CSharp High Risk\SQL Injection Version:0" QueryVersionCode="430"> 472 <Result NodeId="10000050002" FileName="bookstore/Login.cs" Status="Recurrent" Line="179" Column="103" FalsePositive="False" Severity="High" AssignToUser="" state="0" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="3"> 473 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 474 </Result> 475 <Result NodeId="10000050003" FileName="bookstore/Login.cs" Status="Recurrent" Line="180" Column="10" FalsePositive="False" Severity="High" AssignToUser="" state="1" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="3"> 476 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 477 </Result> 478 <Result NodeId="10000050004" FileName="bookstore/Login.cs" Status="Recurrent" Line="181" Column="190" FalsePositive="True" Severity="Medium" AssignToUser="" state="2" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="2"> 479 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 480 </Result> 481 <Result NodeId="10000050005" FileName="bookstore/Login.cs" Status="Recurrent" Line="181" Column="190" FalsePositive="True" Severity="Low" AssignToUser="" state="3" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="2"> 482 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 483 </Result> 484 <Result NodeId="10000050006" FileName="bookstore/Login.cs" Status="Recurrent" Line="181" Column="190" FalsePositive="True" Severity="Low" AssignToUser="" state="4" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="2"> 485 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 486 </Result> 487 </Query> 488 </CxXMLResults>`)} 489 dir, err := ioutil.TempDir("", "test detailed results") 490 if err != nil { 491 t.Fatal("Failed to create temporary directory") 492 } 493 // clean up tmp dir 494 defer os.RemoveAll(dir) 495 result, err := getDetailedResults(sys, filepath.Join(dir, "abc.xml"), 2635, newCheckmarxExecuteScanUtilsMock()) 496 assert.NoError(t, err, "error occurred but none expected") 497 assert.Equal(t, "2", result["ProjectId"], "Project ID incorrect") 498 assert.Equal(t, "Project 1", result["ProjectName"], "Project name incorrect") 499 assert.Equal(t, 2, result["High"].(map[string]int)["Issues"], "Number of High issues incorrect") 500 assert.Equal(t, 2, result["High"].(map[string]int)["NotFalsePositive"], "Number of High NotFalsePositive issues incorrect") 501 assert.Equal(t, 1, result["Medium"].(map[string]int)["Issues"], "Number of Medium issues incorrect") 502 assert.Equal(t, 0, result["Medium"].(map[string]int)["NotFalsePositive"], "Number of Medium NotFalsePositive issues incorrect") 503 }) 504 505 t.Run("error on write file", func(t *testing.T) { 506 t.Parallel() 507 sys := &systemMock{response: []byte(`<?xml version="1.0" encoding="utf-8"?> 508 <CxXMLResults InitiatorName="admin" Owner="admin" ScanId="1000005" ProjectId="2" ProjectName="Project 1" TeamFullPathOnReportDate="CxServer" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2" ScanStart="Sunday, December 3, 2017 4:50:34 PM" Preset="Checkmarx Default" ScanTime="00h:03m:18s" LinesOfCodeScanned="6838" FilesScanned="34" ReportCreationTime="Sunday, December 3, 2017 6:13:45 PM" Team="CxServer" CheckmarxVersion="8.6.0" ScanComments="" ScanType="Incremental" SourceOrigin="LocalPath" Visibility="Public"> 509 <Query id="430" categories="PCI DSS v3.2;PCI DSS (3.2) - 6.5.1 - Injection flaws - particularly SQL injection,OWASP Top 10 2013;A1-Injection,FISMA 2014;System And Information Integrity,NIST SP 800-53;SI-10 Information Input Validation (P1),OWASP Top 10 2017;A1-Injection" cweId="89" name="SQL_Injection" group="CSharp_High_Risk" Severity="High" Language="CSharp" LanguageHash="1363215419077432" LanguageChangeDate="2017-12-03T00:00:00.0000000" SeverityIndex="3" QueryPath="CSharp\Cx\CSharp High Risk\SQL Injection Version:0" QueryVersionCode="430"> 510 <Result NodeId="10000050002" FileName="bookstore/Login.cs" Status="Recurrent" Line="179" Column="103" FalsePositive="False" Severity="High" AssignToUser="" state="0" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="3"> 511 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 512 </Result> 513 <Result NodeId="10000050003" FileName="bookstore/Login.cs" Status="Recurrent" Line="180" Column="10" FalsePositive="False" Severity="High" AssignToUser="" state="1" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="3"> 514 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 515 </Result> 516 <Result NodeId="10000050004" FileName="bookstore/Login.cs" Status="Recurrent" Line="181" Column="190" FalsePositive="True" Severity="Medium" AssignToUser="" state="2" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="2"> 517 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 518 </Result> 519 <Result NodeId="10000050005" FileName="bookstore/Login.cs" Status="Recurrent" Line="181" Column="190" FalsePositive="True" Severity="Low" AssignToUser="" state="3" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="2"> 520 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 521 </Result> 522 <Result NodeId="10000050006" FileName="bookstore/Login.cs" Status="Recurrent" Line="181" Column="190" FalsePositive="True" Severity="Low" AssignToUser="" state="4" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="2"> 523 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 524 </Result> 525 </Query> 526 </CxXMLResults>`)} 527 dir, err := ioutil.TempDir("", "test detailed results") 528 if err != nil { 529 t.Fatal("Failed to create temporary directory") 530 } 531 // clean up tmp dir 532 defer os.RemoveAll(dir) 533 utils := newCheckmarxExecuteScanUtilsMock() 534 utils.errorOnWriteFile = true 535 _, err = getDetailedResults(sys, filepath.Join(dir, "abc.xml"), 2635, utils) 536 assert.EqualError(t, err, "failed to write file: error on WriteFile") 537 }) 538 } 539 540 func TestRunScan(t *testing.T) { 541 t.Parallel() 542 543 sys := &systemMockForExistingProject{response: []byte(`<?xml version="1.0" encoding="utf-8"?><CxXMLResults />`)} 544 options := checkmarxExecuteScanOptions{ProjectName: "TestExisting", VulnerabilityThresholdUnit: "absolute", FullScanCycle: "2", Incremental: true, FullScansScheduled: true, Preset: "10048", TeamID: "16", VulnerabilityThresholdEnabled: true, GeneratePdfReport: true} 545 workspace, err := ioutil.TempDir("", "workspace1") 546 if err != nil { 547 t.Fatal("Failed to create temporary workspace directory") 548 } 549 // clean up tmp dir 550 defer os.RemoveAll(workspace) 551 err = ioutil.WriteFile(filepath.Join(workspace, "abcd.go"), []byte("abcd.go"), 0700) 552 assert.NoError(t, err) 553 options.FilterPattern = "**/abcd.go" 554 555 influx := checkmarxExecuteScanInflux{} 556 557 utilsMock := newCheckmarxExecuteScanUtilsMock() 558 utilsMock.workspace = workspace 559 560 err = runScan(options, sys, &influx, utilsMock) 561 assert.NoError(t, err, "error occurred but none expected") 562 assert.Equal(t, false, sys.isIncremental, "isIncremental has wrong value") 563 assert.Equal(t, true, sys.isPublic, "isPublic has wrong value") 564 assert.Equal(t, true, sys.forceScan, "forceScan has wrong value") 565 assert.Equal(t, true, sys.scanProjectCalled, "ScanProject was not invoked") 566 } 567 568 func TestRunScan_nonNumeralPreset(t *testing.T) { 569 t.Parallel() 570 571 sys := &systemMockForExistingProject{response: []byte(`<?xml version="1.0" encoding="utf-8"?><CxXMLResults />`)} 572 options := checkmarxExecuteScanOptions{ProjectName: "TestExisting", VulnerabilityThresholdUnit: "absolute", FullScanCycle: "2", Incremental: true, FullScansScheduled: true, Preset: "SAP_JS_Default", TeamID: "16", VulnerabilityThresholdEnabled: true, GeneratePdfReport: true} 573 workspace, err := ioutil.TempDir("", "workspace1") 574 if err != nil { 575 t.Fatal("Failed to create temporary workspace directory") 576 } 577 // clean up tmp dir 578 defer os.RemoveAll(workspace) 579 err = ioutil.WriteFile(filepath.Join(workspace, "abcd.go"), []byte("abcd.go"), 0700) 580 assert.NoError(t, err) 581 options.FilterPattern = "**/abcd.go" 582 583 influx := checkmarxExecuteScanInflux{} 584 585 utilsMock := newCheckmarxExecuteScanUtilsMock() 586 utilsMock.workspace = workspace 587 588 err = runScan(options, sys, &influx, utilsMock) 589 assert.NoError(t, err, "error occurred but none expected") 590 } 591 592 func TestRunOptimizedScan(t *testing.T) { 593 t.Parallel() 594 595 sys := &systemMockForExistingProject{response: []byte(`<?xml version="1.0" encoding="utf-8"?><CxXMLResults />`)} 596 options := checkmarxExecuteScanOptions{IsOptimizedAndScheduled: true, ProjectName: "TestExisting", VulnerabilityThresholdUnit: "absolute", FullScanCycle: "1", Incremental: true, FullScansScheduled: true, Preset: "10048", TeamID: "16", VulnerabilityThresholdEnabled: true, GeneratePdfReport: true} 597 workspace, err := ioutil.TempDir("", "workspace1") 598 if err != nil { 599 t.Fatal("Failed to create temporary workspace directory") 600 } 601 // clean up tmp dir 602 defer os.RemoveAll(workspace) 603 err = ioutil.WriteFile(filepath.Join(workspace, "abcd.go"), []byte("abcd.go"), 0700) 604 assert.NoError(t, err) 605 options.FilterPattern = "**/abcd.go" 606 607 influx := checkmarxExecuteScanInflux{} 608 609 utilsMock := newCheckmarxExecuteScanUtilsMock() 610 utilsMock.workspace = workspace 611 612 err = runScan(options, sys, &influx, utilsMock) 613 assert.NoError(t, err, "error occurred but none expected") 614 assert.Equal(t, false, sys.isIncremental, "isIncremental has wrong value") 615 assert.Equal(t, true, sys.isPublic, "isPublic has wrong value") 616 assert.Equal(t, true, sys.forceScan, "forceScan has wrong value") 617 assert.Equal(t, true, sys.scanProjectCalled, "ScanProject was not invoked") 618 } 619 620 func TestSetPresetForProjectWithIDProvided(t *testing.T) { 621 t.Parallel() 622 623 sys := &systemMock{} 624 err := setPresetForProject(sys, 12345, 16, "testProject", "CX_Default", "") 625 assert.NoError(t, err, "error occurred but none expected") 626 assert.Equal(t, false, sys.getPresetsCalled, "GetPresets was called") 627 assert.Equal(t, true, sys.updateProjectConfigurationCalled, "UpdateProjectConfiguration was not called") 628 } 629 630 func TestSetPresetForProjectWithNameProvided(t *testing.T) { 631 t.Parallel() 632 633 sys := &systemMock{} 634 presetID, _ := strconv.Atoi("CX_Default") 635 err := setPresetForProject(sys, 12345, presetID, "testProject", "CX_Default", "") 636 assert.NoError(t, err, "error occurred but none expected") 637 assert.Equal(t, true, sys.getPresetsCalled, "GetPresets was not called") 638 assert.Equal(t, true, sys.updateProjectConfigurationCalled, "UpdateProjectConfiguration was not called") 639 } 640 641 func TestVerifyOnly(t *testing.T) { 642 t.Parallel() 643 644 sys := &systemMockForExistingProject{response: []byte(`<?xml version="1.0" encoding="utf-8"?><CxXMLResults />`)} 645 options := checkmarxExecuteScanOptions{VerifyOnly: true, ProjectName: "TestExisting", VulnerabilityThresholdUnit: "absolute", FullScanCycle: "2", Incremental: true, FullScansScheduled: true, Preset: "10048", TeamName: "OpenSource/Cracks/15", VulnerabilityThresholdEnabled: true, GeneratePdfReport: true} 646 workspace, err := ioutil.TempDir("", "workspace1") 647 if err != nil { 648 t.Fatal("Failed to create temporary workspace directory") 649 } 650 // clean up tmp dir 651 defer os.RemoveAll(workspace) 652 653 influx := checkmarxExecuteScanInflux{} 654 655 utilsMock := newCheckmarxExecuteScanUtilsMock() 656 utilsMock.workspace = workspace 657 658 err = runScan(options, sys, &influx, utilsMock) 659 assert.NoError(t, err, "error occurred but none expected") 660 assert.Equal(t, false, sys.scanProjectCalled, "ScanProject was invoked but shouldn't") 661 } 662 663 func TestVerifyOnly_errorOnWriteFileDoesNotBlock(t *testing.T) { 664 t.Parallel() 665 666 sys := &systemMockForExistingProject{response: []byte(`<?xml version="1.0" encoding="utf-8"?><CxXMLResults />`)} 667 options := checkmarxExecuteScanOptions{VerifyOnly: true, ProjectName: "TestExisting", VulnerabilityThresholdUnit: "absolute", FullScanCycle: "2", Incremental: true, FullScansScheduled: true, Preset: "10048", TeamName: "OpenSource/Cracks/15", VulnerabilityThresholdEnabled: true, GeneratePdfReport: true} 668 workspace, err := ioutil.TempDir("", "workspace1") 669 if err != nil { 670 t.Fatal("Failed to create temporary workspace directory") 671 } 672 // clean up tmp dir 673 defer os.RemoveAll(workspace) 674 675 influx := checkmarxExecuteScanInflux{} 676 677 utilsMock := newCheckmarxExecuteScanUtilsMock() 678 utilsMock.workspace = workspace 679 utilsMock.errorOnWriteFile = true 680 681 err = runScan(options, sys, &influx, utilsMock) 682 assert.EqualError(t, err, "scan, upload, and result validation returned an error: project TestExisting not compliant: failed to get detailed results: failed to write file: error on WriteFile") 683 } 684 685 func TestRunScanWOtherCycle(t *testing.T) { 686 t.Parallel() 687 688 sys := &systemMock{response: []byte(`<?xml version="1.0" encoding="utf-8"?><CxXMLResults />`), createProject: true} 689 options := checkmarxExecuteScanOptions{VulnerabilityThresholdUnit: "percentage", FullScanCycle: "3", Incremental: true, FullScansScheduled: true, Preset: "123", TeamID: "16", VulnerabilityThresholdEnabled: true, GeneratePdfReport: true} 690 workspace, err := ioutil.TempDir("", "workspace2") 691 if err != nil { 692 t.Fatal("Failed to create temporary workspace directory") 693 } 694 // clean up tmp dir 695 defer os.RemoveAll(workspace) 696 err = ioutil.WriteFile(filepath.Join(workspace, "abcd.go"), []byte("abcd.go"), 0700) 697 assert.NoError(t, err) 698 options.FilterPattern = "**/abcd.go" 699 700 influx := checkmarxExecuteScanInflux{} 701 702 utilsMock := newCheckmarxExecuteScanUtilsMock() 703 utilsMock.workspace = workspace 704 705 err = runScan(options, sys, &influx, utilsMock) 706 assert.NoError(t, err, "error occurred but none expected") 707 assert.Equal(t, true, sys.isIncremental, "isIncremental has wrong value") 708 assert.Equal(t, true, sys.isPublic, "isPublic has wrong value") 709 assert.Equal(t, true, sys.forceScan, "forceScan has wrong value") 710 } 711 712 func TestRunScanErrorInZip(t *testing.T) { 713 t.Parallel() 714 715 sys := &systemMock{response: []byte(`<?xml version="1.0" encoding="utf-8"?><CxXMLResults />`), createProject: true} 716 options := checkmarxExecuteScanOptions{VulnerabilityThresholdUnit: "percentage", FullScanCycle: "3", Incremental: true, FullScansScheduled: true, Preset: "123", TeamID: "16", VulnerabilityThresholdEnabled: true, GeneratePdfReport: true} 717 workspace, err := ioutil.TempDir("", "workspace2") 718 if err != nil { 719 t.Fatal("Failed to create temporary workspace directory") 720 } 721 // clean up tmp dir 722 defer os.RemoveAll(workspace) 723 724 influx := checkmarxExecuteScanInflux{} 725 726 utilsMock := newCheckmarxExecuteScanUtilsMock() 727 utilsMock.workspace = workspace 728 utilsMock.errorOnFileInfoHeader = true 729 730 err = runScan(options, sys, &influx, utilsMock) 731 assert.EqualError(t, err, "scan, upload, and result validation returned an error: failed to zip workspace files: failed to compact folder: error on FileInfoHeader") 732 } 733 734 func TestRunScanForPullRequest(t *testing.T) { 735 t.Parallel() 736 737 sys := &systemMock{response: []byte(`<?xml version="1.0" encoding="utf-8"?><CxXMLResults />`)} 738 options := checkmarxExecuteScanOptions{PullRequestName: "PR-19", ProjectName: "Test", VulnerabilityThresholdUnit: "percentage", FullScanCycle: "3", Incremental: true, FullScansScheduled: true, Preset: "123", TeamID: "16", VulnerabilityThresholdEnabled: true, GeneratePdfReport: true, AvoidDuplicateProjectScans: false} 739 workspace, err := ioutil.TempDir("", "workspace3") 740 if err != nil { 741 t.Fatal("Failed to create temporary workspace directory") 742 } 743 // clean up tmp dir 744 defer os.RemoveAll(workspace) 745 err = ioutil.WriteFile(filepath.Join(workspace, "abcd.go"), []byte("abcd.go"), 0700) 746 assert.NoError(t, err) 747 options.FilterPattern = "**/abcd.go" 748 749 influx := checkmarxExecuteScanInflux{} 750 751 utilsMock := newCheckmarxExecuteScanUtilsMock() 752 utilsMock.workspace = workspace 753 754 err = runScan(options, sys, &influx, utilsMock) 755 assert.Equal(t, true, sys.isIncremental, "isIncremental has wrong value") 756 assert.Equal(t, true, sys.isPublic, "isPublic has wrong value") 757 assert.Equal(t, true, sys.forceScan, "forceScan has wrong value") 758 } 759 760 func TestRunScanForPullRequestProjectNew(t *testing.T) { 761 t.Parallel() 762 763 sys := &systemMock{response: []byte(`<?xml version="1.0" encoding="utf-8"?><CxXMLResults />`), createProject: true} 764 options := checkmarxExecuteScanOptions{PullRequestName: "PR-17", ProjectName: "Test", AvoidDuplicateProjectScans: true, VulnerabilityThresholdUnit: "percentage", FullScanCycle: "3", Incremental: true, FullScansScheduled: true, Preset: "10048", TeamName: "OpenSource/Cracks/15", VulnerabilityThresholdEnabled: true, GeneratePdfReport: true} 765 workspace, err := ioutil.TempDir("", "workspace4") 766 if err != nil { 767 t.Fatal("Failed to create temporary workspace directory") 768 } 769 // clean up tmp dir 770 defer os.RemoveAll(workspace) 771 err = ioutil.WriteFile(filepath.Join(workspace, "abcd.go"), []byte("abcd.go"), 0700) 772 assert.NoError(t, err) 773 options.FilterPattern = "**/abcd.go" 774 775 influx := checkmarxExecuteScanInflux{} 776 777 utilsMock := newCheckmarxExecuteScanUtilsMock() 778 utilsMock.workspace = workspace 779 780 err = runScan(options, sys, &influx, utilsMock) 781 assert.NoError(t, err, "Unexpected error caught") 782 assert.Equal(t, true, sys.isIncremental, "isIncremental has wrong value") 783 assert.Equal(t, true, sys.isPublic, "isPublic has wrong value") 784 assert.Equal(t, false, sys.forceScan, "forceScan has wrong value") 785 } 786 787 func TestRunScanForPullRequestProjectNew_nonNumeralPreset(t *testing.T) { 788 t.Parallel() 789 790 sys := &systemMock{response: []byte(`<?xml version="1.0" encoding="utf-8"?><CxXMLResults />`), createProject: true} 791 options := checkmarxExecuteScanOptions{PullRequestName: "PR-17", ProjectName: "Test", AvoidDuplicateProjectScans: true, VulnerabilityThresholdUnit: "percentage", FullScanCycle: "3", Incremental: true, FullScansScheduled: true, Preset: "SAP_JS_Default", TeamName: "OpenSource/Cracks/15", VulnerabilityThresholdEnabled: true, GeneratePdfReport: true} 792 workspace, err := ioutil.TempDir("", "workspace4") 793 if err != nil { 794 t.Fatal("Failed to create temporary workspace directory") 795 } 796 // clean up tmp dir 797 defer os.RemoveAll(workspace) 798 err = ioutil.WriteFile(filepath.Join(workspace, "abcd.go"), []byte("abcd.go"), 0700) 799 assert.NoError(t, err) 800 options.FilterPattern = "**/abcd.go" 801 802 influx := checkmarxExecuteScanInflux{} 803 804 utilsMock := newCheckmarxExecuteScanUtilsMock() 805 utilsMock.workspace = workspace 806 807 err = runScan(options, sys, &influx, utilsMock) 808 assert.NoError(t, err, "error occurred but none expected") 809 } 810 811 func TestRunScanHighViolationPercentage(t *testing.T) { 812 t.Parallel() 813 814 sys := &systemMock{response: []byte(`<?xml version="1.0" encoding="utf-8"?> 815 <CxXMLResults InitiatorName="admin" Owner="admin" ScanId="1000005" ProjectId="2" ProjectName="Project 1" TeamFullPathOnReportDate="CxServer" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2" ScanStart="Sunday, December 3, 2017 4:50:34 PM" Preset="Checkmarx Default" ScanTime="00h:03m:18s" LinesOfCodeScanned="6838" FilesScanned="34" ReportCreationTime="Sunday, December 3, 2017 6:13:45 PM" Team="CxServer" CheckmarxVersion="8.6.0" ScanComments="" ScanType="Incremental" SourceOrigin="LocalPath" Visibility="Public"> 816 <Query id="430" categories="PCI DSS v3.2;PCI DSS (3.2) - 6.5.1 - Injection flaws - particularly SQL injection,OWASP Top 10 2013;A1-Injection,FISMA 2014;System And Information Integrity,NIST SP 800-53;SI-10 Information Input Validation (P1),OWASP Top 10 2017;A1-Injection" cweId="89" name="SQL_Injection" group="CSharp_High_Risk" Severity="High" Language="CSharp" LanguageHash="1363215419077432" LanguageChangeDate="2017-12-03T00:00:00.0000000" SeverityIndex="3" QueryPath="CSharp\Cx\CSharp High Risk\SQL Injection Version:0" QueryVersionCode="430"> 817 <Result NodeId="10000050002" FileName="bookstore/Login.cs" Status="Recurrent" Line="179" Column="103" FalsePositive="False" Severity="High" AssignToUser="" state="0" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="3"> 818 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 819 </Result> 820 <Result NodeId="10000050003" FileName="bookstore/Login.cs" Status="Recurrent" Line="180" Column="10" FalsePositive="False" Severity="High" AssignToUser="" state="0" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="3"> 821 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 822 </Result> 823 <Result NodeId="10000050004" FileName="bookstore/Login.cs" Status="Recurrent" Line="181" Column="190" FalsePositive="True" Severity="Medium" AssignToUser="" state="0" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="2"> 824 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 825 </Result> 826 <Result NodeId="10000050005" FileName="bookstore/Login.cs" Status="Recurrent" Line="181" Column="190" FalsePositive="True" Severity="Low" AssignToUser="" state="0" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="2"> 827 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 828 </Result> 829 <Result NodeId="10000050006" FileName="bookstore/Login.cs" Status="Recurrent" Line="181" Column="190" FalsePositive="True" Severity="Low" AssignToUser="" state="0" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="2"> 830 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 831 </Result> 832 </Query> 833 </CxXMLResults>`)} 834 options := checkmarxExecuteScanOptions{VulnerabilityThresholdUnit: "percentage", VulnerabilityThresholdResult: "FAILURE", VulnerabilityThresholdHigh: 100, FullScanCycle: "10", FullScansScheduled: true, Preset: "10048", TeamID: "16", VulnerabilityThresholdEnabled: true, GeneratePdfReport: true} 835 workspace, err := ioutil.TempDir("", "workspace5") 836 if err != nil { 837 t.Fatal("Failed to create temporary workspace directory") 838 } 839 // clean up tmp dir 840 defer os.RemoveAll(workspace) 841 err = ioutil.WriteFile(filepath.Join(workspace, "abcd.go"), []byte("abcd.go"), 0700) 842 assert.NoError(t, err) 843 options.FilterPattern = "**/abcd.go" 844 845 influx := checkmarxExecuteScanInflux{} 846 847 utilsMock := newCheckmarxExecuteScanUtilsMock() 848 utilsMock.workspace = workspace 849 850 err = runScan(options, sys, &influx, utilsMock) 851 assert.Contains(t, fmt.Sprint(err), "the project is not compliant", "Expected different error") 852 } 853 854 func TestRunScanHighViolationAbsolute(t *testing.T) { 855 t.Parallel() 856 857 sys := &systemMock{response: []byte(`<?xml version="1.0" encoding="utf-8"?> 858 <CxXMLResults InitiatorName="admin" Owner="admin" ScanId="1000005" ProjectId="2" ProjectName="Project 1" TeamFullPathOnReportDate="CxServer" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2" ScanStart="Sunday, December 3, 2017 4:50:34 PM" Preset="Checkmarx Default" ScanTime="00h:03m:18s" LinesOfCodeScanned="6838" FilesScanned="34" ReportCreationTime="Sunday, December 3, 2017 6:13:45 PM" Team="CxServer" CheckmarxVersion="8.6.0" ScanComments="" ScanType="Incremental" SourceOrigin="LocalPath" Visibility="Public"> 859 <Query id="430" categories="PCI DSS v3.2;PCI DSS (3.2) - 6.5.1 - Injection flaws - particularly SQL injection,OWASP Top 10 2013;A1-Injection,FISMA 2014;System And Information Integrity,NIST SP 800-53;SI-10 Information Input Validation (P1),OWASP Top 10 2017;A1-Injection" cweId="89" name="SQL_Injection" group="CSharp_High_Risk" Severity="High" Language="CSharp" LanguageHash="1363215419077432" LanguageChangeDate="2017-12-03T00:00:00.0000000" SeverityIndex="3" QueryPath="CSharp\Cx\CSharp High Risk\SQL Injection Version:0" QueryVersionCode="430"> 860 <Result NodeId="10000050002" FileName="bookstore/Login.cs" Status="Recurrent" Line="179" Column="103" FalsePositive="True" Severity="High" AssignToUser="" state="0" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="3"> 861 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 862 </Result> 863 <Result NodeId="10000050003" FileName="bookstore/Login.cs" Status="Recurrent" Line="180" Column="10" FalsePositive="True" Severity="High" AssignToUser="" state="0" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="3"> 864 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 865 </Result> 866 <Result NodeId="10000050004" FileName="bookstore/Login.cs" Status="Recurrent" Line="181" Column="190" FalsePositive="True" Severity="Medium" AssignToUser="" state="0" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="2"> 867 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 868 </Result> 869 <Result NodeId="10000050005" FileName="bookstore/Login.cs" Status="Recurrent" Line="181" Column="190" FalsePositive="False" Severity="Low" AssignToUser="" state="0" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="2"> 870 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 871 </Result> 872 <Result NodeId="10000050006" FileName="bookstore/Login.cs" Status="Recurrent" Line="181" Column="190" FalsePositive="False" Severity="Low" AssignToUser="" state="0" Remark="" DeepLink="http://WIN2K12-TEMP/CxWebClient/ViewerMain.aspx?scanid=1000005&projectid=2&pathid=2" SeverityIndex="2"> 873 <Path ResultId="1000005" PathId="2" SimilarityId="1765812516"/> 874 </Result> 875 </Query> 876 </CxXMLResults>`)} 877 options := checkmarxExecuteScanOptions{VulnerabilityThresholdUnit: "absolute", VulnerabilityThresholdResult: "FAILURE", VulnerabilityThresholdLow: 1, FullScanCycle: "10", FullScansScheduled: true, Preset: "10048", TeamID: "16", VulnerabilityThresholdEnabled: true, GeneratePdfReport: true} 878 workspace, err := ioutil.TempDir("", "workspace6") 879 if err != nil { 880 t.Fatal("Failed to create temporary workspace directory") 881 } 882 // clean up tmp dir 883 defer os.RemoveAll(workspace) 884 err = ioutil.WriteFile(filepath.Join(workspace, "abcd.go"), []byte("abcd.go"), 0700) 885 assert.NoError(t, err) 886 options.FilterPattern = "**/abcd.go" 887 888 influx := checkmarxExecuteScanInflux{} 889 890 utilsMock := newCheckmarxExecuteScanUtilsMock() 891 utilsMock.workspace = workspace 892 893 err = runScan(options, sys, &influx, utilsMock) 894 assert.Contains(t, fmt.Sprint(err), "the project is not compliant", "Expected different error") 895 } 896 897 func TestEnforceThresholds(t *testing.T) { 898 t.Parallel() 899 900 results := map[string]interface{}{} 901 results["High"] = map[string]int{} 902 results["Medium"] = map[string]int{} 903 results["Low"] = map[string]int{} 904 905 results["High"].(map[string]int)["NotFalsePositive"] = 10 906 results["Medium"].(map[string]int)["NotFalsePositive"] = 10 907 results["Low"].(map[string]int)["NotFalsePositive"] = 10 908 results["Low"].(map[string]int)["NotExploitable"] = 0 909 results["Low"].(map[string]int)["Confirmed"] = 0 910 911 results["High"].(map[string]int)["Issues"] = 10 912 results["Medium"].(map[string]int)["Issues"] = 10 913 results["Low"].(map[string]int)["Issues"] = 10 914 915 t.Run("percentage high violation", func(t *testing.T) { 916 t.Parallel() 917 918 options := checkmarxExecuteScanOptions{VulnerabilityThresholdUnit: "percentage", VulnerabilityThresholdHigh: 100, VulnerabilityThresholdEnabled: true} 919 insecure, insecureResults, neutralResults := enforceThresholds(options, results) 920 921 assert.Equal(t, true, insecure, "Expected results to be insecure but where not") 922 assert.Equal(t, 1, len(insecureResults), fmt.Sprintf("Unexpected number of results: %v", insecureResults)) 923 assert.Equal(t, 2, len(neutralResults), fmt.Sprintf("Unexpected number of results: %v", neutralResults)) 924 }) 925 926 t.Run("absolute high violation", func(t *testing.T) { 927 t.Parallel() 928 929 options := checkmarxExecuteScanOptions{VulnerabilityThresholdUnit: "absolute", VulnerabilityThresholdHigh: 5, VulnerabilityThresholdEnabled: true} 930 insecure, insecureResults, neutralResults := enforceThresholds(options, results) 931 932 assert.Equal(t, true, insecure, "Expected results to be insecure but where not") 933 assert.Equal(t, 3, len(insecureResults), fmt.Sprintf("Unexpected number of results: %v", insecureResults)) 934 assert.Equal(t, 0, len(neutralResults), fmt.Sprintf("Unexpected number of results: %v", neutralResults)) 935 }) 936 937 t.Run("percentage medium violation", func(t *testing.T) { 938 t.Parallel() 939 940 options := checkmarxExecuteScanOptions{VulnerabilityThresholdUnit: "percentage", VulnerabilityThresholdMedium: 100, VulnerabilityThresholdEnabled: true} 941 insecure, insecureResults, neutralResults := enforceThresholds(options, results) 942 943 assert.Equal(t, true, insecure, "Expected results to be insecure but where not") 944 assert.Equal(t, 1, len(insecureResults), fmt.Sprintf("Unexpected number of results: %v", insecureResults)) 945 assert.Equal(t, 2, len(neutralResults), fmt.Sprintf("Unexpected number of results: %v", neutralResults)) 946 }) 947 948 t.Run("absolute medium violation", func(t *testing.T) { 949 t.Parallel() 950 951 options := checkmarxExecuteScanOptions{VulnerabilityThresholdUnit: "absolute", VulnerabilityThresholdMedium: 5, VulnerabilityThresholdEnabled: true} 952 insecure, insecureResults, neutralResults := enforceThresholds(options, results) 953 954 assert.Equal(t, true, insecure, "Expected results to be insecure but where not") 955 assert.Equal(t, 3, len(insecureResults), fmt.Sprintf("Unexpected number of results: %v", insecureResults)) 956 assert.Equal(t, 0, len(neutralResults), fmt.Sprintf("Unexpected number of results: %v", neutralResults)) 957 }) 958 959 t.Run("percentage low violation", func(t *testing.T) { 960 t.Parallel() 961 962 options := checkmarxExecuteScanOptions{VulnerabilityThresholdUnit: "percentage", VulnerabilityThresholdLow: 100, VulnerabilityThresholdEnabled: true} 963 insecure, insecureResults, neutralResults := enforceThresholds(options, results) 964 965 assert.Equal(t, true, insecure, "Expected results to be insecure but where not") 966 assert.Equal(t, 1, len(insecureResults), fmt.Sprintf("Unexpected number of results: %v", insecureResults)) 967 assert.Equal(t, 2, len(neutralResults), fmt.Sprintf("Unexpected number of results: %v", neutralResults)) 968 }) 969 970 t.Run("absolute low violation", func(t *testing.T) { 971 t.Parallel() 972 973 options := checkmarxExecuteScanOptions{VulnerabilityThresholdUnit: "absolute", VulnerabilityThresholdLow: 5, VulnerabilityThresholdEnabled: true} 974 insecure, insecureResults, neutralResults := enforceThresholds(options, results) 975 976 assert.Equal(t, true, insecure, "Expected results to be insecure but where not") 977 assert.Equal(t, 3, len(insecureResults), fmt.Sprintf("Unexpected number of results: %v", insecureResults)) 978 assert.Equal(t, 0, len(neutralResults), fmt.Sprintf("Unexpected number of results: %v", neutralResults)) 979 }) 980 981 t.Run("percentage no violation", func(t *testing.T) { 982 t.Parallel() 983 984 options := checkmarxExecuteScanOptions{VulnerabilityThresholdUnit: "percentage", VulnerabilityThresholdLow: 0, VulnerabilityThresholdEnabled: true} 985 insecure, insecureResults, neutralResults := enforceThresholds(options, results) 986 987 assert.Equal(t, false, insecure, "Expected results to be insecure but where not") 988 assert.Equal(t, 0, len(insecureResults), fmt.Sprintf("Unexpected number of results: %v", insecureResults)) 989 assert.Equal(t, 3, len(neutralResults), fmt.Sprintf("Unexpected number of results: %v", neutralResults)) 990 }) 991 992 t.Run("absolute no violation", func(t *testing.T) { 993 t.Parallel() 994 995 options := checkmarxExecuteScanOptions{VulnerabilityThresholdUnit: "absolute", VulnerabilityThresholdLow: 15, VulnerabilityThresholdMedium: 15, VulnerabilityThresholdHigh: 15, VulnerabilityThresholdEnabled: true} 996 insecure, insecureResults, neutralResults := enforceThresholds(options, results) 997 998 assert.Equal(t, false, insecure, "Expected results to be insecure but where not") 999 assert.Equal(t, 0, len(insecureResults), fmt.Sprintf("Unexpected number of results: %v", insecureResults)) 1000 assert.Equal(t, 3, len(neutralResults), fmt.Sprintf("Unexpected number of results: %v", neutralResults)) 1001 }) 1002 } 1003 1004 func TestLoadPreset(t *testing.T) { 1005 t.Parallel() 1006 1007 sys := &systemMock{} 1008 1009 t.Run("resolve via name", func(t *testing.T) { 1010 t.Parallel() 1011 1012 preset, err := loadPreset(sys, "SAP_JS_Default") 1013 assert.NoError(t, err, "Expected success but failed") 1014 assert.Equal(t, "SAP_JS_Default", preset.Name, "Expected result but got none") 1015 }) 1016 1017 t.Run("error case", func(t *testing.T) { 1018 t.Parallel() 1019 1020 preset, err := loadPreset(sys, "") 1021 assert.Contains(t, fmt.Sprint(err), "preset SAP_JS_Default not found", "Expected different error") 1022 assert.Equal(t, 0, preset.ID, "Expected result but got none") 1023 }) 1024 } 1025 1026 func TestPreventInfiniteLoop(t *testing.T) { 1027 t.Parallel() 1028 1029 utils := checkmarxExecuteScanUtilsBundle{ 1030 workspace: "abc", 1031 } 1032 1033 assert.Equal(t, "abc", utils.GetWorkspace(), "Wrong workspace has been loaded") 1034 }