@@ -206,6 +206,7 @@ func TestFindings(t *testing.T) {
206206 Line : 30 ,
207207 Details : "Detected usage of `npm`" ,
208208 LOTPTool : "npm" ,
209+ LOTPTargets : []string {"package.json" },
209210 EventTriggers : []string {"push" , "pull_request_target" },
210211 ReferencedSecrets : []string {},
211212 },
@@ -232,6 +233,7 @@ func TestFindings(t *testing.T) {
232233 Line : 60 ,
233234 Details : "Detected usage of `pre-commit`" ,
234235 LOTPTool : "pre-commit" ,
236+ LOTPTargets : []string {".pre-commit-config.yaml" },
235237 EventTriggers : []string {"push" , "pull_request_target" },
236238 ReferencedSecrets : []string {},
237239 },
@@ -271,6 +273,7 @@ func TestFindings(t *testing.T) {
271273 Line : 13 ,
272274 Details : "Detected usage of `npm`" ,
273275 LOTPTool : "npm" ,
276+ LOTPTargets : []string {"package.json" },
274277 EventTriggers : []string {"workflow_run" },
275278 ReferencedSecrets : []string {},
276279 },
@@ -460,60 +463,65 @@ func TestFindings(t *testing.T) {
460463 RuleId : "untrusted_checkout_exec" ,
461464 Purl : purl ,
462465 Meta : results.FindingMeta {
463- Path : "azure-pipelines-2.yml" ,
464- Line : 13 ,
465- Job : "" ,
466- Step : "1" ,
467- Details : "Detected usage of `bash`" ,
468- LOTPTool : "bash" ,
466+ Path : "azure-pipelines-2.yml" ,
467+ Line : 13 ,
468+ Job : "" ,
469+ Step : "1" ,
470+ Details : "Detected usage of `bash`" ,
471+ LOTPTool : "bash" ,
472+ LOTPTargets : []string {"script.sh" },
469473 },
470474 },
471475 {
472476 RuleId : "untrusted_checkout_exec" ,
473477 Purl : purl ,
474478 Meta : results.FindingMeta {
475- Path : "azure-pipelines-2.yml" ,
476- Line : 14 ,
477- Job : "" ,
478- Step : "2" ,
479- Details : "Detected usage of `npm`" ,
480- LOTPTool : "npm" ,
479+ Path : "azure-pipelines-2.yml" ,
480+ Line : 14 ,
481+ Job : "" ,
482+ Step : "2" ,
483+ Details : "Detected usage of `npm`" ,
484+ LOTPTool : "npm" ,
485+ LOTPTargets : []string {"package.json" },
481486 },
482487 },
483488 {
484489 RuleId : "untrusted_checkout_exec" ,
485490 Purl : purl ,
486491 Meta : results.FindingMeta {
487- Path : "azure-pipelines-4.yml" ,
488- Line : 10 ,
489- Job : "" ,
490- Step : "1" ,
491- Details : "Detected usage of `bash`" ,
492- LOTPTool : "bash" ,
492+ Path : "azure-pipelines-4.yml" ,
493+ Line : 10 ,
494+ Job : "" ,
495+ Step : "1" ,
496+ Details : "Detected usage of `bash`" ,
497+ LOTPTool : "bash" ,
498+ LOTPTargets : []string {"script.sh" },
493499 },
494500 },
495501 {
496502 RuleId : "untrusted_checkout_exec" ,
497503 Purl : purl ,
498504 Meta : results.FindingMeta {
499- Path : "azure-pipelines-4.yml" ,
500- Line : 11 ,
501- Job : "" ,
502- Step : "2" ,
503- Details : "Detected usage of `npm`" ,
504- LOTPTool : "npm" ,
505+ Path : "azure-pipelines-4.yml" ,
506+ Line : 11 ,
507+ Job : "" ,
508+ Step : "2" ,
509+ Details : "Detected usage of `npm`" ,
510+ LOTPTool : "npm" ,
511+ LOTPTargets : []string {"package.json" },
505512 },
506513 },
507514 {
508515 RuleId : "untrusted_checkout_exec" ,
509516 Purl : purl ,
510517 Meta : results.FindingMeta {
511- Path : ".tekton/pipeline-as-code-tekton.yml" ,
512- Line : 43 ,
513- Job : "vale" ,
514- Step : "0" ,
515- Details : "Detected usage of `vale`" ,
516- LOTPTool : "vale" ,
518+ Path : ".tekton/pipeline-as-code-tekton.yml" ,
519+ Line : 43 ,
520+ Job : "vale" ,
521+ Step : "0" ,
522+ Details : "Detected usage of `vale`" ,
523+ LOTPTool : "vale" ,
524+ LOTPTargets : []string {".vale.ini" },
517525 },
518526 },
519527 {
@@ -565,6 +573,34 @@ func TestFindings(t *testing.T) {
565573 },
566574 },
567575 // test_new_fields.yml findings
576+ {
577+ RuleId : "untrusted_checkout_exec" ,
578+ Purl : purl ,
579+ Meta : results.FindingMeta {
580+ Path : ".github/workflows/test_new_fields.yml" ,
581+ Line : 39 ,
582+ Job : "vulnerable_checkout" ,
583+ Details : "Detected usage of `bash`" ,
584+ LOTPTool : "bash" ,
585+ LOTPTargets : []string {"scripts/build.sh" , "scripts/verify.sh" },
586+ EventTriggers : []string {"pull_request_target" },
587+ ReferencedSecrets : []string {"API_KEY" , "DATABASE_PASSWORD" , "DEPLOY_TOKEN" , "ENABLE_BUILD" },
588+ },
589+ },
590+ {
591+ RuleId : "untrusted_checkout_exec" ,
592+ Purl : purl ,
593+ Meta : results.FindingMeta {
594+ Path : ".github/workflows/test_new_fields.yml" ,
595+ Line : 39 ,
596+ Job : "vulnerable_checkout" ,
597+ Details : "Detected usage of `chmod`" ,
598+ LOTPTool : "chmod" ,
599+ LOTPTargets : []string {"scripts/build.sh" },
600+ EventTriggers : []string {"pull_request_target" },
601+ ReferencedSecrets : []string {"API_KEY" , "DATABASE_PASSWORD" , "DEPLOY_TOKEN" , "ENABLE_BUILD" },
602+ },
603+ },
568604 {
569605 RuleId : "injection" ,
570606 Purl : purl ,
@@ -595,6 +631,7 @@ func TestFindings(t *testing.T) {
595631 Job : "vulnerable_checkout" ,
596632 Details : "Detected usage of `npm`" ,
597633 LOTPTool : "npm" ,
634+ LOTPTargets : []string {"package.json" },
598635 EventTriggers : []string {"pull_request_target" },
599636 ReferencedSecrets : []string {"API_KEY" , "DATABASE_PASSWORD" , "DEPLOY_TOKEN" , "ENABLE_BUILD" },
600637 },
@@ -744,18 +781,32 @@ func TestStructuredFindingFields(t *testing.T) {
744781 // Test lotp_tool and referenced_secrets fields
745782 var lotpFinding * results.Finding
746783 for idx , f := range scannedPackage .FindingsResults .Findings {
747- if f .RuleId == "untrusted_checkout_exec" && f .Meta .Path == ".github/workflows/test_new_fields.yml" {
784+ if f .RuleId == "untrusted_checkout_exec" && f .Meta .Path == ".github/workflows/test_new_fields.yml" && f . Meta . LOTPTool == "npm" {
748785 lotpFinding = & scannedPackage .FindingsResults .Findings [idx ]
749786 break
750787 }
751788 }
752789 assert .NotNil (t , lotpFinding , "Expected to find untrusted_checkout_exec finding for test_new_fields.yml" )
753790 if lotpFinding != nil {
754791 assert .Equal (t , "npm" , lotpFinding .Meta .LOTPTool , "LOTPTool should be 'npm'" )
792+ assert .Equal (t , []string {"package.json" }, lotpFinding .Meta .LOTPTargets , "LOTPTargets should resolve npm to package.json" )
755793 assert .Contains (t , lotpFinding .Meta .ReferencedSecrets , "API_KEY" )
756794 assert .Contains (t , lotpFinding .Meta .ReferencedSecrets , "DATABASE_PASSWORD" )
757795 assert .Contains (t , lotpFinding .Meta .ReferencedSecrets , "DEPLOY_TOKEN" )
758796 assert .Contains (t , lotpFinding .Meta .ReferencedSecrets , "ENABLE_BUILD" )
759797 assert .NotContains (t , lotpFinding .Meta .ReferencedSecrets , "GITHUB_TOKEN" , "GITHUB_TOKEN should be excluded" )
760798 }
799+
800+ var bashMultiTargetFinding * results.Finding
801+ for idx , f := range scannedPackage .FindingsResults .Findings {
802+ if f .RuleId == "untrusted_checkout_exec" && f .Meta .Path == ".github/workflows/test_new_fields.yml" && f .Meta .LOTPTool == "bash" {
803+ bashMultiTargetFinding = & scannedPackage .FindingsResults .Findings [idx ]
804+ break
805+ }
806+ }
807+ assert .NotNil (t , bashMultiTargetFinding , "Expected to find bash finding with multiple targets" )
808+ if bashMultiTargetFinding != nil {
809+ assert .Equal (t , []string {"scripts/build.sh" , "scripts/verify.sh" }, bashMultiTargetFinding .Meta .LOTPTargets ,
810+ "LOTPTargets should contain all .sh files from the run block, deduplicated and sorted" )
811+ }
761812}
0 commit comments