GitHub Actions runner modifies secrets containing $ characters when used in double-quoted shell commands
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 6.3k
- Forks
- 1.4k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 24
Description
Describe the bug
When using GitHub Actions secrets containing $ characters inside a run: step with shell commands, the interaction between GitHub expression substitution (${{ secrets.SECRET }}) and shell variable expansion can lead to unexpected behavior.
For example, a secret containing:
UHh&**&$k8748848923jhHH
used as:
run: |
keytool -list -v \
-keystore release-key.jks \
-storepass "${{ secrets.KEYSTORE_PASSWORD }}"
resulted in the shell interpreting $k8748848923jhHH as a shell variable, causing the actual value passed to keytool to differ from the stored secret.
The issue was resolved by using single quotes:
run: |
keytool -list -v \
-keystore release-key.jks \
-storepass '${{ secrets.KEYSTORE_PASSWORD }}'
I understand this behavior is due to shell semantics, but it is not obvious that secrets containing $ characters can be modified when used inside double-quoted shell strings. It would be helpful if the documentation explicitly warned about this scenario.
To Reproduce
- Create a repository secret named
TEST_SECRETwith a value containing a$character, for example:
abc$xyz123
- Create a workflow step:
- name: Test Secret
run: |
echo "Length: $(echo -n "${{ secrets.TEST_SECRET }}" | wc -c)"
-
Observe that the shell may interpret the portion after
$as a variable expansion, resulting in a different value being passed. -
Modify the workflow to use single quotes:
- name: Test Secret
run: |
echo 'Length: $(echo -n "${{ secrets.TEST_SECRET }}" | wc -c)'
or use environment variables appropriately.
Expected behavior
GitHub Actions documentation should clearly warn users that secrets containing shell-special characters such as $ may be interpreted by the shell when used directly inside double-quoted strings in run: steps.
Providing guidance or examples for safely handling such secrets would help prevent difficult-to-diagnose issues.
Runner Version and Platform
- Runner: GitHub-hosted runner (
ubuntu-latest) - OS: Ubuntu (GitHub-hosted runner environment)
What's not working?
Secrets containing $ characters used directly in shell commands with double quotes can be unexpectedly altered due to shell variable expansion, leading to failures in commands that rely on exact secret values.
Example failure:
keytool error: java.io.IOException: keystore password was incorrect
Caused by: java.security.UnrecoverableKeyException:
failed to decrypt safe contents entry:
javax.crypto.BadPaddingException:
Given final block not properly padded.
The issue was resolved by changing:
-storepass "${{ secrets.KEYSTORE_PASSWORD }}"
to:
-storepass '${{ secrets.KEYSTORE_PASSWORD }}'
Job Log Output
Relevant output:
keytool error: java.io.IOException: keystore password was incorrect
java.io.IOException: keystore password was incorrect
at java.base/sun.security.pkcs12.PKCS12KeyStore.engineLoad(...)
Caused by: java.security.UnrecoverableKeyException:
failed to decrypt safe contents entry:
javax.crypto.BadPaddingException:
Given final block not properly padded.
The keystore file itself was verified to be correct using SHA256 hashes, and the issue was isolated to shell interpretation of the secret value.
Runner and Worker's Diagnostic Logs
No runner diagnostics suggest a runner malfunction. The behavior appears to be due to shell expansion semantics. This report is intended as a documentation improvement request to help users avoid this pitfall.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the GitHub Actions documentation for workflow run steps and secret usage, then verify the reported behavior with the provided shell examples. Document the risk of shell-special characters in directly interpolated secrets and show safe handling guidance, including the single-quoted example; the documentation should clearly explain how to avoid altered secret values.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bash, github-actions, yaml
- Domain
- ci-cd, documentation
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100