Class: Rules::UnpinnedActions

Inherits:
Base
  • Object
show all
Defined in:
lib/rules/unpinned_actions.rb

Constant Summary collapse

SHA_PATTERN =
/@[0-9a-f]{40}\b/
FIRST_PARTY =
%w[actions/ github/].freeze

Instance Method Summary collapse

Instance Method Details

#check(workflow) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/rules/unpinned_actions.rb', line 10

def check(workflow)
    findings = []
    workflow.uses_actions.each do |action|
        uses = action[:uses]
        next if uses.nil?
        next if uses.start_with?("./")
        next if uses.start_with?("docker://")
        next if uses.match?(SHA_PATTERN)

        first_party = FIRST_PARTY.any? { |prefix| uses.start_with?(prefix) }
        sev = first_party ? :medium : :critical

        findings << Finding.new(
            rule: name,
            severity: sev,
            file: workflow.filename,
            line: action[:line] || 0,
            code: "uses: #{uses}",
            message: "Action '#{uses}' is not SHA-pinned — tag references are mutable",
            fix: "Pin to a commit SHA: uses: #{uses.split('@').first}@<commit-sha> # #{uses.split('@').last}"
        )
    end
    findings
end

#descriptionObject



4
# File 'lib/rules/unpinned_actions.rb', line 4

def description = "Action referenced by tag instead of SHA pin"

#nameObject



3
# File 'lib/rules/unpinned_actions.rb', line 3

def name = "unpinned-actions"

#severityObject



5
# File 'lib/rules/unpinned_actions.rb', line 5

def severity = :critical