Skip to content

[static-analysis] RGS-012: Secret Exfiltration via Outbound HTTP Request (4 workflows) #30534

@github-actions

Description

@github-actions

Runner-Guard Security Finding

Rule: RGS-012 — Secret Exfiltration via Outbound HTTP Request
Severity: High
Affected Workflows: 4
Total Findings: 8

Description

Runner-Guard's source-to-sink taint analysis detected run: blocks containing outbound HTTP request commands (curl, wget, etc.) targeting non-GitHub domains in job contexts that have access to secrets or publishing capabilities.

This pattern is a strong indicator of credential exfiltration — the primary objective of most GitHub Actions supply-chain attacks. Attackers who achieve code execution in a CI runner use outbound HTTP to exfiltrate stolen secrets to attacker-controlled infrastructure.

Impact

  • Sensitive secrets, tokens, or deployment credentials may be sent to external domains
  • Any external HTTP request combined with secrets access is a high-confidence risk indicator
  • The combination of untrusted event triggers + outbound HTTP + secrets access creates a full exfiltration path

Affected Workflows

Workflow File Line Context
daily-model-inventory daily-model-inventory.lock.yml (see run logs) Outbound HTTP + secrets access
docs-noob-tester docs-noob-tester.lock.yml 462 Outbound HTTP to non-GitHub domain
unbloat-docs unbloat-docs.lock.yml 549 curl to localhost (dev server readiness check)
visual-regression-checker visual-regression-checker.lock.yml 405, 739 curl to localhost (dev server readiness)

Sample Finding (unbloat-docs.lock.yml:549)

- name: Wait for documentation server readiness
  run: |
    STATUS=""
    for i in $(seq 1 45); do
      STATUS=$(curl -s -o /dev/null -w "%{http_code}" (localhost/redacted)
      [ "$STATUS" = "200" ] && echo "Server ready" && break
      sleep 3
    done

Note: The localhost curl calls are likely false positives (health checks against a local dev server), but they fire in jobs that also have access to secrets — which triggers RGS-012's taint analysis.

Remediation

  1. Review each flagged workflow — distinguish between:
    • localhost HTTP calls (health checks — likely false positives)
    • External domain HTTP calls (higher risk — audit carefully)
  2. For localhost calls: Consider suppressing the finding with a runner-guard annotation, or restructure the job to separate the HTTP check from the secrets-access context
  3. For external domain calls: Verify the domain is trusted and the request does not include secret values in headers, body, or query parameters
  4. Principle of least privilege: Split jobs so that secrets-bearing jobs do not also make arbitrary outbound HTTP calls
  5. Network controls: Consider adding firewall rules to restrict outbound HTTP from runner jobs to known-good domains only

False Positive Assessment

Based on the flagged step names ("Wait for documentation server readiness", "Wait for dev server"), most findings appear to be localhost health check polls — a common CI pattern for waiting on a local dev server. These are likely false positives for actual exfiltration, but the pattern is correct to flag because:

  • The same job also has write permissions / secrets access
  • A compromised action could swap localhost for an external endpoint

Recommendation: Confirm these are localhost calls, then add appropriate suppressions.


Detected by runner-guard v2.6.0 — CI/CD source-to-sink vulnerability scanner
Workflow run: https://github.com/github/gh-aw/actions/runs/25418588621

Generated by Static Analysis Report · ● 451.6K ·

  • expires on May 13, 2026, 5:53 AM UTC

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions