11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# File 'lib/rules/build_publish_same_job.rb', line 11
def check(workflow)
findings = []
workflow.jobs.each do |job_id, job|
steps = workflow.steps(job)
has_install = steps.any? { |s| s["run"]&.match?(INSTALL_PATTERNS) }
has_publish = steps.any? { |s| s["run"]&.match?(PUBLISH_PATTERNS) }
next unless has_install && has_publish
job_env = job["env"]&.to_s || ""
step_envs = steps.map { |s| (s["env"] || {}).to_s }.join(" ")
all_env = job_env + step_envs
if all_env.match?(PUBLISH_SECRETS) || all_env.match?(/secrets\./)
line = workflow.line_of(/#{job_id}:/)
findings << finding(workflow,
line: line || 0,
code: "job: #{job_id}",
message: "Build and publish in same job — a compromised dependency could exfiltrate publish credentials",
fix: "Split into separate build (read-only) and publish (with secrets) jobs connected via artifacts"
)
end
end
findings
end
|