Fix potential OS command injection in clean.js#3335
Open
DongZifan wants to merge 1 commit into
Open
Conversation
|
❌ Author of the following commits did not sign a Contributor Agreement: Please, read and sign the above mentioned agreement if you want to contribute to this project |
|
A documentation preview will be available soon. Request a new doc build by commenting
If your PR continues to fail for an unknown reason, the doc build pipeline may be broken. Elastic employees can check the pipeline status here. |
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.
Command Injection Reproduction Notes for
clean.jsSummary
Hello,
I am writing to report a potential Git Argument Injection vulnerability in the following file:
docs/preview/clean.jsThe issue appears when remote branch names are extracted via a loose regular expression and subsequently used to construct Git command arrays that are executed via
child_process.execFile(...). Under certain conditions, specially crafted branch names provided in the remote Git repository may allow unintended Git option execution on the host system. This could potentially lead to arbitrary code execution or arbitrary file read/write risks, depending on how the input is parsed by the Git executable.Root Cause
The issue is caused by unsafe argument construction and missing option terminators in the following functions:
Reproduction Material
A minimal reproduction script is provided in:
poc_clean.jspoc_clean.js
This Proof of Concept (PoC) is intended to demonstrate that external input (remote branch names) can reach dangerous command execution logic through the vulnerable code path.
What the PoC Does
The PoC performs a minimal end-to-end trigger of the vulnerable code path:
child_process.execFileto monitor the arguments passed to Git.Cleanermodule and invokes the cleanup process (cleaner.run()).show-ref --headsstep, the mocked Git repository returns a maliciously crafted branch name:--upload-pack=calc.exe_123.heads_to_prssuccessfully matches and extracts this malicious branch name..pr.branchvalue is passed as an element into the command array for git show (and potentiallygit push) viaexec_git(...).In the provided example, the injected payload is crafted so that, if executed by a real Git binary, it would trigger the
--upload-packoption. In the PoC, it intercepts the malicious argument and simulates opening the Calculator application. This serves as a visible indicator that external input can reach the OS command execution sink without proper sanitization.Example Payload
The PoC uses the following payload for the malicious branch name:
How to Run
Run from the project root:
Expected Output
When the PoC runs, you should see output similar to:
In the vulnerable version, after the crafted remote branch is processed, the local machine will launch the Calculator application (simulated in the PoC) as a benign demonstration effect.
This shows that the attacker-controlled branch name value can influence Git command execution behavior through the vulnerable
exec_gitpath.Patch Explanation
This branch also includes a patched version of clean.js intended to mitigate the Git argument injection risk described above.
What the patch changes
The patch adds strict validation and correct POSIX command argument termination before branch-related values are used by the following functions:
heads_to_prs(heads)prAge(pr)deleteBranch(pr)In the vulnerable version, attacker-controlled values such as:
pr.branchcould reach
child_process.execFile('git', ...)as unintended options.The patched version introduces input checks and proper command terminators before these values are passed into command execution logic.
Validation introduced by the patch
For Git branch names, the patch ensures that:
heads_to_prsstrictly validates the commit hash and the branch characters, allowing only alphanumeric characters, underscores, dots, and hyphens.(?!-)is used in the regex to explicitly prevent branch names from starting with a hyphen-.pr.branch.startsWith('-')) is added todeleteBranchas an ultimate safeguard to throw an error if an invalid branch name reaches the deletion phase.pr.branchinprAge([..., "--date=unix", "--", pr.branch]).If validation fails or attempts to parse malicious options occur, the branch is safely ignored or securely terminated instead of being parsed as an unintended Git option.