fix(security): prevent unauthorized secret expansion in socket payloads#4184
Merged
Merged
Conversation
khassel
approved these changes
Jun 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR attempts to fix the unauthorized secret expansion vulnerability reported in GHSA-q4gh-4ffp-5cg8.
Previously, if a module sent a payload through the socket containing any
**SECRET_FOO**placeholder, the server would unconditionally expand it with the real environment variable. This meant a manipulated module could theoretically extract secrets that belonged to other modules.To prevent this, the expansion logic is now much stricter and scoped to the individual module:
app.js, we now store a copy of the redacted config (global.configRedacted) to keep track of which module uses which secrets.node_helper.js, before handling a socket notification, we build a specific "allow-list" (Set) of secrets that are actually present in the calling module's config.replaceSecretPlaceholderinserver_functions.jswas updated to accept thisSetand will now only expand placeholders that the module is explicitly authorized to know. Unlisted placeholders are safely ignored.I also updated the unit tests to cover the new allow-list behavior.
Since this security stuff is tricky and gives me headaches all the time, I've added more comments than usual.
I've tried several ways to make it a little simpler, but unfortunately, I couldn't come up with anything easier than that. I'd appreciate it if someone could take a critical look at the logic to make sure I didn't miss anything!