Skip to content

Commit 4d52b8e

Browse files
feat(findings): include 'event_triggers' in finding metadata (#233)
* feat(findings): include 'event_triggers' in finding metadata Signed-off-by: Bryce Thuilot <[email protected]> * Rego linting with opa fmt --write . --------- Signed-off-by: Bryce Thuilot <[email protected]> Co-authored-by: François Proulx <[email protected]>
1 parent eaa5c38 commit 4d52b8e

12 files changed

+164
-121
lines changed

opa/rego/rules/debug_enabled.rego

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ is_debug_enabled(var) if {
5252
results contains poutine.finding(rule, pkg.purl, {
5353
"path": workflow.path,
5454
"details": var.name,
55+
"event_triggers": [event | event := workflow.events[i].name],
5556
}) if {
5657
pkg := input.packages[_]
5758
workflow := pkg.github_actions_workflows[_]
@@ -64,6 +65,7 @@ results contains poutine.finding(rule, pkg.purl, {
6465
"job": job.id,
6566
"details": var.name,
6667
"line": job.lines.start,
68+
"event_triggers": [event | event := workflow.events[i].name],
6769
}) if {
6870
pkg := input.packages[_]
6971
workflow := pkg.github_actions_workflows[_]
@@ -78,6 +80,7 @@ results contains poutine.finding(rule, pkg.purl, {
7880
"step": step_id,
7981
"details": var.name,
8082
"line": step.lines.start,
83+
"event_triggers": [event | event := workflow.events[i].name],
8184
}) if {
8285
pkg := input.packages[_]
8386
workflow := pkg.github_actions_workflows[_]

opa/rego/rules/default_permissions_on_risky_events.rego

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# METADATA
22
# title: Default permissions used on risky events
33
# description: |-
4-
# The workflow and some of its jobs do not explicitely define permissions
4+
# The workflow and some of its jobs do not explicitely define permissions
55
# and the workflow triggers on events that are typically used to run builds from forks.
6-
# Because no permissions is set, the workflow inherits the default permissions
6+
# Because no permissions is set, the workflow inherits the default permissions
77
# configured on the repository or the organization.
88
# custom:
99
# level: warning
@@ -20,7 +20,10 @@ github.events contains event if some event in {
2020
"issue_comment",
2121
}
2222

23-
results contains poutine.finding(rule, pkg.purl, {"path": workflow.path}) if {
23+
results contains poutine.finding(rule, pkg.purl, {
24+
"path": workflow.path,
25+
"event_triggers": [event | event := workflow.events[j].name],
26+
}) if {
2427
pkg := input.packages[_]
2528
workflow = pkg.github_actions_workflows[_]
2629
job := workflow.jobs[_]
@@ -31,7 +34,10 @@ results contains poutine.finding(rule, pkg.purl, {"path": workflow.path}) if {
3134
utils.empty(job.permissions)
3235
}
3336

34-
results contains poutine.finding(rule, pkg.purl, {"path": workflow.path}) if {
37+
results contains poutine.finding(rule, pkg.purl, {
38+
"path": workflow.path,
39+
"event_triggers": [event | event := workflow.events[j].name],
40+
}) if {
3541
pkg := input.packages[_]
3642
workflow = pkg.github_actions_workflows[_]
3743
job := workflow.jobs[_]

opa/rego/rules/if_always_true.rego

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ if_conditions[pkg.purl] contains {
3333
"path": workflow.path,
3434
"line": object.get(job.lines, "if", 0),
3535
"job": job.id,
36+
"event_triggers": [event | event := workflow.events[j].name],
3637
} if {
3738
pkg := input.packages[_]
3839
workflow = pkg.github_actions_workflows[_]
@@ -47,6 +48,7 @@ if_conditions[pkg.purl] contains {
4748
"line": object.get(step.lines, "if", 0),
4849
"job": job.id,
4950
"step": step_id,
51+
"event_triggers": [event | event := workflow.events[j].name],
5052
} if {
5153
pkg := input.packages[_]
5254
workflow = pkg.github_actions_workflows[_]

opa/rego/rules/injection.rego

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# METADATA
22
# title: Injection with Arbitrary External Contributor Input
33
# description: |-
4-
# The pipeline contains an injection into bash or JavaScript with an expression
5-
# that can contain user input. Prefer placing the expression in an environment variable
4+
# The pipeline contains an injection into bash or JavaScript with an expression
5+
# that can contain user input. Prefer placing the expression in an environment variable
66
# instead of interpolating it directly into a script.
77
# related_resources:
88
# - https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
@@ -33,6 +33,7 @@ results contains poutine.finding(rule, pkg.purl, {
3333
"job": job.id,
3434
"step": i,
3535
"details": sprintf("Sources: %s", [concat(" ", exprs)]),
36+
"event_triggers": [event | event := workflow.events[j].name],
3637
}) if {
3738
pkg = input.packages[_]
3839
workflow = pkg.github_actions_workflows[_]
@@ -47,6 +48,7 @@ results contains poutine.finding(rule, pkg.purl, {
4748
"line": line,
4849
"step": i,
4950
"details": sprintf("Sources: %s", [concat(" ", exprs)]),
51+
"event_triggers": [event | event := action.events[j].name],
5052
}) if {
5153
pkg = input.packages[_]
5254
action := pkg.github_actions_metadata[_]
@@ -113,19 +115,17 @@ results contains poutine.finding(rule, pkg.purl, {
113115
"path": pipeline.path,
114116
"job": task.name,
115117
"step": step_idx,
116-
"line": step.lines["start"],
118+
"line": step.lines.start,
117119
"details": sprintf("Sources: %s", [concat(" ", exprs)]),
118120
}) if {
119-
pkg := input.packages[_]
120-
pipeline := pkg.pipeline_as_code_tekton[_]
121-
contains(pipeline.api_version, "tekton.dev")
122-
pipeline.kind == "PipelineRun"
123-
contains(pipeline.metadata.annotations["pipelinesascode.tekton.dev/on-event"], "pull_request")
124-
task := pipeline.spec.pipeline_spec.tasks[_]
125-
step := task.task_spec.steps[step_idx]
126-
127-
exprs := pipeline_as_code_tekton_injections(step.script)
128-
count(exprs) > 0
121+
pkg := input.packages[_]
122+
pipeline := pkg.pipeline_as_code_tekton[_]
123+
contains(pipeline.api_version, "tekton.dev")
124+
pipeline.kind == "PipelineRun"
125+
contains(pipeline.metadata.annotations["pipelinesascode.tekton.dev/on-event"], "pull_request")
126+
task := pipeline.spec.pipeline_spec.tasks[_]
127+
step := task.task_spec.steps[step_idx]
128+
129+
exprs := pipeline_as_code_tekton_injections(step.script)
130+
count(exprs) > 0
129131
}
130-
131-

opa/rego/rules/job_all_secrets.rego

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# METADATA
22
# title: Workflow job exposes all secrets
33
# description: |-
4-
# The GitHub Actions Runner attempts to keep in memory only the secrets
5-
# that are necessary to execute a workflow job.
6-
# If a job converts the secrets object to JSON or accesses it using an expression,
4+
# The GitHub Actions Runner attempts to keep in memory only the secrets
5+
# that are necessary to execute a workflow job.
6+
# If a job converts the secrets object to JSON or accesses it using an expression,
77
# all secrets will be retained in memory for the duration of the job.
88
# custom:
99
# level: warning
@@ -18,6 +18,7 @@ results contains poutine.finding(rule, pkg.purl, {
1818
"path": workflow.path,
1919
"job": job.id,
2020
"line": job.lines.start,
21+
"event_triggers": [event | event := workflow.events[i].name],
2122
}) if {
2223
pkg := input.packages[_]
2324
workflow := pkg.github_actions_workflows[_]

opa/rego/rules/known_vulnerability_in_build_component.rego

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ results contains poutine.finding(rule, pkg.purl, {
3434
"step": i,
3535
"osv_id": advisory.osv_id,
3636
"details": sprintf("Package: %s", [advisory.package_name]),
37+
"event_triggers": [event | event := workflow.events[j].name],
3738
}) if {
3839
pkg = input.packages[_]
3940
workflow = pkg.github_actions_workflows[_]

opa/rego/rules/pr_runs_on_self_hosted.rego

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ results contains poutine.finding(rule, pkg.purl, {
3030
"job": job.id,
3131
"line": job.lines.runs_on,
3232
"details": sprintf("runs-on: %s", [concat(", ", job.runs_on)]),
33+
"event_triggers": [event | event := workflow.events[i].name],
3334
}) if {
3435
pkg := input.packages[_]
3536
workflow = pkg.github_actions_workflows[_]

opa/rego/rules/unpinnable_action.rego

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# METADATA
22
# title: Unpinnable CI component used
33
# description: |-
4-
# Pinning this GitHub Action is likely ineffective
4+
# Pinning this GitHub Action is likely ineffective
55
# as it depends on other mutable supply chain components.
66
# custom:
77
# level: note

opa/rego/rules/untrusted_checkout_exec.rego

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ results contains poutine.finding(rule, pkg_purl, {
5151
"path": workflow_path,
5252
"line": step.lines.run,
5353
"details": sprintf("Detected usage of `%s`", [cmd]),
54+
"event_triggers": workflow_events,
5455
}) if {
55-
[pkg_purl, workflow_path, step] := _steps_after_untrusted_checkout[_]
56+
[pkg_purl, workflow_path, workflow_events, step] := _steps_after_untrusted_checkout[_]
5657
regex.match(
5758
sprintf("([^a-z]|^)(%v)", [concat("|", build_commands[cmd])]),
5859
step.run,
@@ -63,24 +64,27 @@ results contains poutine.finding(rule, pkg_purl, {
6364
"path": workflow_path,
6465
"line": step.lines.uses,
6566
"details": sprintf("Detected usage the GitHub Action `%s`", [step.action]),
67+
"event_triggers": workflow_events,
6668
}) if {
67-
[pkg_purl, workflow_path, step] := _steps_after_untrusted_checkout[_]
69+
[pkg_purl, workflow_path, workflow_events, step] := _steps_after_untrusted_checkout[_]
6870
build_github_actions[step.action]
6971
}
7072

71-
_steps_after_untrusted_checkout contains [pkg.purl, workflow.path, s.step] if {
73+
_steps_after_untrusted_checkout contains [pkg.purl, workflow.path, events, s.step] if {
7274
pkg := input.packages[_]
7375
workflow := pkg.github_actions_workflows[_]
7476

7577
utils.filter_workflow_events(workflow, github.events)
7678

79+
events := [event | event := workflow.events[i].name]
7780
pr_checkout := utils.find_pr_checkouts(workflow)[_]
7881
s := utils.workflow_steps_after(pr_checkout)[_]
7982
}
8083

81-
_steps_after_untrusted_checkout contains [pkg_purl, workflow.path, s.step] if {
84+
_steps_after_untrusted_checkout contains [pkg_purl, workflow.path, events, s.step] if {
8285
[pkg_purl, workflow] := _workflows_runs_from_pr[_]
8386

87+
events := [event | event := workflow.events[i].name]
8488
pr_checkout := utils.find_pr_checkouts(workflow)[_]
8589
s := utils.workflow_steps_after(pr_checkout)[_]
8690
}
@@ -142,17 +146,17 @@ results contains poutine.finding(rule, pkg.purl, {
142146
"path": pipeline.path,
143147
"job": task.name,
144148
"step": step_idx,
145-
"line": step.lines["script"],
149+
"line": step.lines.script,
146150
"details": sprintf("Detected usage of `%s`", [cmd]),
147151
}) if {
148-
pkg := input.packages[_]
149-
pipeline := pkg.pipeline_as_code_tekton[_]
150-
contains(pipeline.api_version, "tekton.dev")
151-
pipeline.kind == "PipelineRun"
152-
contains(pipeline.metadata.annotations["pipelinesascode.tekton.dev/on-event"], "pull_request")
153-
contains(pipeline.metadata.annotations["pipelinesascode.tekton.dev/task"], "git-clone")
154-
task := pipeline.spec.pipeline_spec.tasks[_]
155-
step := task.task_spec.steps[step_idx]
152+
pkg := input.packages[_]
153+
pipeline := pkg.pipeline_as_code_tekton[_]
154+
contains(pipeline.api_version, "tekton.dev")
155+
pipeline.kind == "PipelineRun"
156+
contains(pipeline.metadata.annotations["pipelinesascode.tekton.dev/on-event"], "pull_request")
157+
contains(pipeline.metadata.annotations["pipelinesascode.tekton.dev/task"], "git-clone")
158+
task := pipeline.spec.pipeline_spec.tasks[_]
159+
step := task.task_spec.steps[step_idx]
156160
regex.match(
157161
sprintf("([^a-z]|^)(%v)", [concat("|", build_commands[cmd])]),
158162
step.script,

opa/rego/rules/unverified_script_exec.rego

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ _scripts[pkg.purl] contains {
4040
"job": job.id,
4141
"line": step.lines.run,
4242
"details": details,
43+
"event_triggers": [event | event := workflow.events[j].name],
4344
} if {
4445
pkg := input.packages[_]
4546
workflow := pkg.github_actions_workflows[_]

0 commit comments

Comments
 (0)