Repository navigation
fix(security): escape user-controlled values across command-injection sinks (quote sweep) - #4873
Merged
Merged
Conversation
…mand injection Wrap S3 credential flags (getS3Credentials + destination.testConnection), the listBackupFiles search path, and every restore backupPath/backupFile with shell-quote's quote() so $(), backticks, quotes and spaces in destination fields or backupFile can no longer break out of the rclone shell commands.
Add VOLUME_NAME_REGEX (Docker volume-name format) and enforce it on volumeName in create/update/runManually — a legit volume name never contains shell metacharacters, so this blocks injection across every docker run/rm/rclone sink at once. Escape the user-supplied backupFileName and the mount volumeName in database rebuild with quote().
… invocations quote() the user-derived paths that reach the shell in file mounts (mount.ts, docker getCreateFileCommand), patch repo read (repoPath/filePath), certificate create/remove (certificatePath), and the remote scheduled command (containerId/shellType/command/logPath), so $(), backticks and traversal in these fields can no longer inject commands.
writeTraefikConfigRemote piped the stringified YAML through echo '...' where a single quote in any label/host/serviceName broke out (GHSA-478p). Encode it as base64 like the other writers, and quote() every configPath used in remote rm/cat/redirect commands (including the input.path-derived ones).
Contributor
Author
|
Added two more sinks to complete GHSA-fgh8 and GHSA-q9qw:
|
This was referenced Aug 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.
Sweeps the remaining OS-command-injection sinks where user-controlled values reached a shell unescaped, applying
shell-quote'squote()(or strict validation where a shell arg cannot be quoted). Closes a batch of same-root-cause advisories at once.Families fixed
rclone / S3 — every value in
getS3Credentials(and the duplicated block indestination.testConnection) now goes throughquote(); thelistBackupFilessearch path, allrestore/*.tsbackup paths, the mongo restore file names, and the web-server restore file are quoted too. (GHSA-5vjv, GHSA-2xjq, GHSA-f7mp, GHSA-f6x8, GHSA-p2c7 area.)volumeName — added
VOLUME_NAME_REGEX(Docker volume-name format) enforced onvolumeNamein create/update/runManually. A legit volume name never contains shell metacharacters, so this blocks injection across everydocker run -v,docker volume rm, filter and rclone sink at once. The user-suppliedbackupFileNameand the mountvolumeNamein database rebuild are quoted. (GHSA-w223, GHSA-xqjr, GHSA-74xw.)file-path-to-shell — quoted the user-derived paths reaching the shell in file mounts (
mount.ts,getCreateFileCommand), patch-repo read (repoPath/filePath), and certificate create/remove (certificatePath). (GHSA-56g6, GHSA-q9qw, GHSA-fgh8 area.)schedule remote exec — quoted
containerId,shellType,commandandlogPathin the remotedocker execscheduled-command path (the local path already used argv).traefik remote write —
writeTraefikConfigRemotenow base64-encodes the YAML instead of piping it throughecho ...(a single quote in any label/host/serviceName broke out — GHSA-478p / p787 residual), and everyconfigPathin remoterm/cat/redirect commands (including theinput.path-derived ones) is quoted.Notes
changePassword(databaseUser + old credential) is intentionally not in this PR — it interpolates into both a shell and a nested SQL context and needs the env-var pattern with its own runtime verification; it will follow in a separate PR.quote([value])for values already typedstring, andquote([value ?? ""])for nullable ones.Cold typecheck (server + app) and biome pass.