Skip to content

encode commands in base64 to reduce quote bugs#477

Open
mrshmllow wants to merge 3 commits intotrunkfrom
marshmallow/p-putkoutmxzzm
Open

encode commands in base64 to reduce quote bugs#477
mrshmllow wants to merge 3 commits intotrunkfrom
marshmallow/p-putkoutmxzzm

Conversation

@mrshmllow
Copy link
Copy Markdown
Member

@mrshmllow mrshmllow commented Apr 30, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Command execution is now encoded to improve reliability across diverse shell environments.
    • Privilege escalation is applied consistently when configured, fixing cases where it was previously ignored.
    • Authentication/notification messages now reflect whether an escalation command is configured.
  • Documentation

    • Changelog updated to document these changes and clarify release notes.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

📝 Walkthrough

Walkthrough

Updates CHANGELOG.md and changes command execution in two modules to Base64-encode composed shell payloads and pipe decoded bytes into the shell; privilege-escalation selection/logging now uses arguments.privilege_escalation_command, and a fix ensures deployment.privilegeEscalationCommand is applied consistently.

Changes

Cohort / File(s) Summary
Changelog
CHANGELOG.md
Updated [Unreleased] notes: records that executed commands are now Base64-encoded; notes a fix for deployment.privilegeEscalationCommand not being consistently applied.
Non-Interactive Command Execution
crates/core/src/commands/noninteractive.rs
Assembled command_string is Base64-encoded; when keep_stdin_open is false the code executes via a wrapper `sh -c 'echo {encoded}
PTY Command Execution
crates/core/src/commands/pty/mod.rs
PTy paths use the same Base64 encode/decode-and-execute pipeline. Authentication warning/logging now depends on arguments.privilege_escalation_command and includes the escalation command and raw arguments.command_string. keep_stdin_open bypasses the decode pipeline and executes the command string directly.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as "Caller"
    participant Args as "arguments"
    participant Escal as "PrivilegeEscalation Shell\n(when provided)"
    participant Shell as "Shell (sh)"
    participant Bash as "bash (decoder target)"

    Caller->>Args: provide command_string, keep_stdin_open, privilege_escalation_command
    alt privilege_escalation_command present
        Args->>Escal: build wrapper
        alt keep_stdin_open
            Escal->>Escal: execute direct command_string
        else keep stdin closed
            Escal->>Bash: run "echo <base64> | base64 -d | bash"
        end
    else no escalation
        Args->>Shell: build wrapper
        alt keep_stdin_open
            Shell->>Shell: execute direct command_string
        else keep stdin closed
            Shell->>Bash: run "echo <base64> | base64 -d | bash"
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐇 I wrapped the hop in base64 thread,
Echoed, decoded, then softly led.
Privilege climbs with tidy art,
A rabbit's nod to safer start. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: encoding commands in base64 to address quote-related bugs.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch marshmallow/p-putkoutmxzzm

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added rust Pull requests that update rust code release PRs against main labels Apr 30, 2026
@mrshmllow mrshmllow force-pushed the marshmallow/p-putkoutmxzzm branch from e21c62f to 9120399 Compare April 30, 2026 00:48
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/core/src/commands/pty/mod.rs`:
- Around line 336-341: The PTY path hardcodes "sudo -u root --" when
arguments.is_elevated() is true; change it to use the configured privilege
escalation string from arguments.privilege_escalation_command instead. Update
the branch that calls command.arg(...) inside the arguments.is_elevated()
condition to build the escalation prefix from
arguments.privilege_escalation_command (preserving the trailing "-- bash -c
'echo {encoded} | base64 -d | bash'" behavior), so interactive PTY runs use the
same configured escalation command as noninterative code paths (refer to
arguments.is_elevated(), arguments.privilege_escalation_command, and the
command.arg(...) invocation).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 82ac4df2-e7cd-4ecd-bcd1-c2f0b2ed9801

📥 Commits

Reviewing files that changed from the base of the PR and between bf92f65 and e965d13.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • crates/core/src/commands/noninteractive.rs
  • crates/core/src/commands/pty/mod.rs

Comment thread crates/core/src/commands/pty/mod.rs Outdated
@mrshmllow mrshmllow force-pushed the marshmallow/p-putkoutmxzzm branch from e965d13 to b8d2f76 Compare April 30, 2026 03:15
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CHANGELOG.md`:
- Around line 1-10: The file CHANGELOG.md was accidentally replaced with CI job
output; restore it to be a proper changelog entry that documents the PR’s change
(the base64 encoding change for shell commands to reduce quote-related bugs).
Replace the CI lines with a concise release note that includes: a short summary
sentence mentioning "base64 encoding for shell commands", the rationale (avoids
quote/escaping issues), the user-facing impact or migration steps (how to
decode/run encoded commands or any flag/API change), and reference affected
areas/components (the shell command construction logic and any CLI/runner that
sends shell commands). Ensure the entry is dated/versioned consistently with
existing changelog style.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5812472c-004d-4dd4-9d2e-c7f27eb1669a

📥 Commits

Reviewing files that changed from the base of the PR and between e965d13 and b8d2f76.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • crates/core/src/commands/noninteractive.rs
  • crates/core/src/commands/pty/mod.rs

Comment thread CHANGELOG.md Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/core/src/commands/pty/mod.rs`:
- Around line 337-340: The privilege-escalation command is being applied twice:
once by prefixing the whole invocation from
arguments.privilege_escalation_command and again inside the shell string passed
to command.arg (you can see both references to {escalation_command} surrounding
the inner bash). Remove the inner/second escalation invocation so that
command.arg uses a single shell string like "sh -c 'echo {encoded} | base64 -d |
bash'" and rely on the outer prefix from arguments.privilege_escalation_command
(or conversely remove the outer prefix and keep a single inner use) to ensure
escalation is invoked only once; update the command.arg construction accordingly
(affecting the command.arg call that references {encoded} and
{escalation_command}).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4741588c-0871-4da3-94a0-f60e8ffa5dc9

📥 Commits

Reviewing files that changed from the base of the PR and between b8d2f76 and d2714bf.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • crates/core/src/commands/noninteractive.rs
  • crates/core/src/commands/pty/mod.rs
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md

Comment thread crates/core/src/commands/pty/mod.rs Outdated
@mrshmllow mrshmllow force-pushed the marshmallow/p-putkoutmxzzm branch from d2714bf to dd88214 Compare April 30, 2026 04:46
@mrshmllow mrshmllow force-pushed the marshmallow/p-putkoutmxzzm branch from dd88214 to 1ca1213 Compare April 30, 2026 05:23
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/core/src/commands/pty/mod.rs`:
- Around line 337-343: The elevated keep_stdin_open branch currently passes
command_string through "sh -c" which breaks because command_string contains
bash-only IO_SUBS and may lose quotes; change that branch (the block that checks
arguments.privilege_escalation_command && arguments.keep_stdin_open) to use the
same Base64+bash pattern as the other elevated branch: base64-encode
command_string (the existing encoded variable) and pass an argument like
"{escalation_command} sh -c 'echo {encoded} | base64 -d | bash'" so the decoded
payload runs under bash and avoids shell quoting/compatibility issues.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ffec0e4c-ab03-4822-b60b-355834b47f08

📥 Commits

Reviewing files that changed from the base of the PR and between d2714bf and 1d8fb29.

📒 Files selected for processing (2)
  • crates/core/src/commands/noninteractive.rs
  • crates/core/src/commands/pty/mod.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/core/src/commands/noninteractive.rs

Comment on lines +337 to +343
if let Some(escalation_command) = &arguments.privilege_escalation_command {
if arguments.keep_stdin_open {
command.arg(format!("{escalation_command} sh -c '{command_string}'"));
} else {
command.arg(format!(
"{escalation_command} sh -c 'echo {encoded} | base64 -d | bash'"
));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the file structure and the specific lines mentioned
cd crates/core/src/commands/pty && wc -l mod.rs

Repository: forallsys/wire

Length of output: 69


🏁 Script executed:

# Read the context around lines 337-343 to understand the full scope
head -n 360 crates/core/src/commands/pty/mod.rs | tail -n 50

Repository: forallsys/wire

Length of output: 1466


🏁 Script executed:

# Search for IO_SUBS definition and usage
rg "IO_SUBS" crates/core/src/commands/pty/

Repository: forallsys/wire

Length of output: 272


🏁 Script executed:

# Search for command_string definition to understand what it contains
rg -B5 -A5 "let command_string" crates/core/src/commands/pty/mod.rs

Repository: forallsys/wire

Length of output: 605


🏁 Script executed:

# Search for encoded definition to understand the Base64 payload
rg -B5 -A5 "let encoded" crates/core/src/commands/pty/mod.rs

Repository: forallsys/wire

Length of output: 381


Use bash with Base64 encoding in the elevated keep_stdin_open path.

Lines 338–339 pass command_string through sh -c, but command_string always includes IO_SUBS, which contains bash-only process substitution (>(...)). On systems where /bin/sh is not bash, this will fail. Additionally, the approach is vulnerable to quote loss if command_string contains embedded single quotes.

The non-elevated keep_stdin_open path works because it runs the command directly without invoking a shell. The elevated non-keep_stdin_open path works because it uses the Base64 payload and explicitly pipes to bash. Apply the same Base64 + bash pattern to the elevated keep_stdin_open path:

Suggested fix
     if let Some(escalation_command) = &arguments.privilege_escalation_command {
         if arguments.keep_stdin_open {
-            command.arg(format!("{escalation_command} sh -c '{command_string}'"));
+            command.arg(format!(
+                r#"{escalation_command} env WIRE_PTY_COMMAND_B64={encoded} bash -c 'eval "$(printf %s "$WIRE_PTY_COMMAND_B64" | base64 -d)"'"#
+            ));
         } else {
             command.arg(format!(
                 "{escalation_command} sh -c 'echo {encoded} | base64 -d | bash'"
             ));
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/core/src/commands/pty/mod.rs` around lines 337 - 343, The elevated
keep_stdin_open branch currently passes command_string through "sh -c" which
breaks because command_string contains bash-only IO_SUBS and may lose quotes;
change that branch (the block that checks arguments.privilege_escalation_command
&& arguments.keep_stdin_open) to use the same Base64+bash pattern as the other
elevated branch: base64-encode command_string (the existing encoded variable)
and pass an argument like "{escalation_command} sh -c 'echo {encoded} | base64
-d | bash'" so the decoded payload runs under bash and avoids shell
quoting/compatibility issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release PRs against main rust Pull requests that update rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant