Module: Rules::GuardPatterns

Included in:
GithubScriptInjection, ShellInjectionExpr, ShellInjectionJq, WorkflowDispatchInjection
Defined in:
lib/rules/concerns/guard_patterns.rb

Constant Summary collapse

SAFE_TRIGGERS =
%w[
    workflow_dispatch schedule push workflow_call release
    deployment deployment_status create delete
    page_build watch fork star gollum
].freeze
JOB_PROPERTIES =
%w[
    steps runs-on env strategy permissions outputs concurrency
    services needs container timeout-minutes if name defaults
].freeze
DANGEROUS_CONTEXTS =
%w[
    github.event.pull_request.title
    github.event.pull_request.body
    github.event.pull_request.head.ref
    github.event.pull_request.head.label
    github.event.issue.title
    github.event.issue.body
    github.event.comment.body
    github.event.review.body
    github.event.discussion.title
    github.event.discussion.body
    github.event.workflow_run.head_branch
    github.head_ref
].freeze

Instance Method Summary collapse

Instance Method Details

#guarded_by_safe_event?(workflow, line_num) ⇒ Boolean

Returns:

  • (Boolean)


40
41
42
# File 'lib/rules/concerns/guard_patterns.rb', line 40

def guarded_by_safe_event?(workflow, line_num)
    guarded_by_step_if?(workflow, line_num) || guarded_by_job_if?(workflow, line_num)
end

#safe_trigger_only?(workflow) ⇒ Boolean

Returns:

  • (Boolean)


29
30
31
32
33
34
35
36
37
38
# File 'lib/rules/concerns/guard_patterns.rb', line 29

def safe_trigger_only?(workflow)
    trigger_names = case workflow.triggers
    when Hash then workflow.triggers.keys.map(&:to_s)
    when Array then workflow.triggers.map(&:to_s)
    when String then [workflow.triggers]
    else []
    end

    trigger_names.any? && trigger_names.all? { |t| SAFE_TRIGGERS.include?(t) }
end

#strip_inline_comment(line) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/rules/concerns/guard_patterns.rb', line 44

def strip_inline_comment(line)
    in_single_quote = false
    in_double_quote = false

    i = 0
    while i < line.length
        char = line[i]

        if char == "'" && !in_double_quote
            in_single_quote = !in_single_quote
        elsif char == '"' && !in_single_quote
            in_double_quote = !in_double_quote
        elsif char == '#' && !in_single_quote && !in_double_quote
            # Only strip if preceded by whitespace (or at start of line content)
            if i == 0 || line[i - 1] =~ /\s/
                return line[0...i].rstrip
            end
        end

        i += 1
    end

    line
end