Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

only use arguments on suda#executable if it's equal to "sudo" #60

Merged
merged 2 commits into from
Mar 12, 2024

Conversation

aarondill
Copy link
Collaborator

@aarondill aarondill commented Jul 19, 2023

This ensures that the sudo options work correctly, and creates rudimentary support for other commands (such as doas, see #40)

This isn't perfect, but likely the best we can do (see my comment).

This change allows any command which accepts no password, or else a password from stdin to work. Any command set to g:suda#executable will be executed with no further arguments (so the user may need to provide any needed), and will be run, first with an empty stdin, then with the user's provided password as stdin. Further support would likely need to be added on a case-by-case basis and may quickly spiral out of control.

Summary by CodeRabbit

  • New Features
    • Enhanced command construction for improved reliability and security.
    • Introduced interactive password prompts for certain operations.

@acid-bong
Copy link

Just tested, it doesn't pass the password to doas, and 2 failed attempts it somehow counted as 3

@aarondill
Copy link
Collaborator Author

aarondill commented Jul 19, 2023

The password is passed through stdin, but doas doesn't process it. Also, it is called twice, one without stdin, once with (as noted above).

This will only work with doas when the user has the nopass privilege.

@aarondill
Copy link
Collaborator Author

One tool that does work with this change is su - -c (as su accepts input through stdin), though I believe a wrapper would be required to ensure that all arguments passed end up as one after the -c (like the one below)

#!/usr/bin/env sh
exec su - -c "$*"

@acid-bong
Copy link

The difference is that su asks for root's password, not your user's, like sudo and doas do

@aarondill
Copy link
Collaborator Author

The difference is that su asks for root's password, not your user's, like sudo and doas do

This is true, but as I've already said, unless you can discover a way to pass the password to doas, we can only support any tools that accept the password through stdin (like, sudo and su)

@lambdalisue lambdalisue self-requested a review July 19, 2023 15:31
@lambdalisue
Copy link
Owner

My apologies for the delay. I completely overlooked this matter. Could you please resolve the conflicts first so we can proceed with the review? @aarondill

@lambdalisue lambdalisue requested review from lambdalisue and removed request for lambdalisue March 10, 2024 17:09
This ensures that the sudo options work correctly, and creates *rudimentary* support for other commands (such as `doas`, see lambdalisue#40)
This helps avoid the printf('%s %s') which is repetative and unclear. get_command now returns the *full* command to run.
Copy link

coderabbitai bot commented Mar 12, 2024

Walkthrough

This update introduces a more sophisticated approach to command construction and execution in suda.vim. By adding a dedicated function for building commands and refining how passwords are requested, the changes enhance both security and usability. Centralizing shell escaping ensures commands are safely constructed, reducing potential vulnerabilities.

Changes

File(s) Summary
autoload/suda.vim Introduced s:get_command, improved suda#system, centralized shell escaping, and refined password interaction logic.

🐰✨
In the realm of code, where commands are spun,
A rabbit hopped in, a mission begun.
With a leap and a bound, it refined the art,
Of constructing commands, so smart.
"To safety and ease!" it cheerfully sung,
As into the code, its magic it flung.
🌟🐇

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit-tests for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

Copy link

@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.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between b6363e8 and 2a2030e.
Files selected for processing (1)
  • autoload/suda.vim (1 hunks)
Additional comments: 2
autoload/suda.vim (2)
  • 11-45: In the suda#system function, there's a significant change in how commands are constructed and executed, particularly with the introduction of conditional logic to handle password prompts interactively. This change is crucial for supporting different privilege escalation commands beyond sudo, such as doas and potentially su.

However, there are a few points to consider:

  • The logic to determine whether to ask for a password non-interactively (lines 23-37) is specific to sudo and relies on the sudo timestamp feature. This is a clever use of sudo's behavior but may not be transparent to users unfamiliar with sudo's configuration nuances.
  • The handling of passwords (lines 38-45) assumes that the command can accept a password via stdin, which, as noted in the PR comments, does not work with doas in its default configuration. This limitation should be clearly documented to manage user expectations.

Consider adding detailed comments or documentation to explain the specific behaviors and limitations of the suda#system function, especially regarding the non-interactive password logic and its compatibility with different privilege escalation tools. This will help users understand how to configure their systems for optimal compatibility with suda.vim.

  • 1-48: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [46-118]

The changes in the suda#read, suda#write, suda#BufReadCmd, suda#FileReadCmd, suda#BufWriteCmd, and suda#FileWriteCmd functions seem to be primarily focused on integrating the new command construction and execution logic introduced earlier. These changes are consistent with the PR's objectives to refine the behavior of the plugin when using different command executables for privilege escalation.

However, it's important to ensure that these changes do not introduce any regressions or unexpected behaviors, especially in edge cases such as handling file paths with special characters, dealing with large files, or operating in environments with strict security policies.

Ensure thorough testing of these functions in various scenarios, including with file paths containing special characters, large files, and different operating system environments. Consider adding automated tests to cover these cases if not already present.

Comment on lines +1 to +10
function! s:get_command(opts, cmd)
" TODO: should we pass '--' between a:opts and a:cmd?
" TODO: should we change this api to use lists? system() allows either
" strings or lists. We don't need a intermediate shell for anything though.
" TODO: Should we move shell escaping to the responsibility of
" suda#system/s:get_command to avoid forgetting it at the call site?
return g:suda#executable ==# "sudo" && len(a:opts) > 0
\ ? printf('%s %s %s', g:suda#executable, a:opts, a:cmd)
\ : printf('%s %s', g:suda#executable, a:cmd)
endfunction
Copy link

@coderabbitai coderabbitai bot Mar 12, 2024

Choose a reason for hiding this comment

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

The new s:get_command function introduces a flexible way to construct commands based on the g:suda#executable variable. However, there are several TODO comments that raise important questions about the function's design and implementation:

  1. The consideration of passing '--' between a:opts and a:cmd to signify the end of command options. This is a best practice for security, ensuring that subsequent strings are not interpreted as options.
  2. The suggestion to change the API to use lists instead of strings for system() calls. This would indeed avoid the need for an intermediate shell, which can enhance security and performance.
  3. The idea of moving shell escaping to the responsibility of suda#system/s:get_command to avoid forgetting it at the call site. This could significantly reduce the risk of shell injection vulnerabilities.

Each of these points merits careful consideration. The first point is particularly important for security, as it prevents potential command-line argument injection. The second and third points could improve the maintainability and security of the code by reducing complexity and the risk of errors.

Consider implementing these TODO items, especially the use of '--' to separate options from commands and the transition to list-based APIs for system calls. Additionally, centralizing shell escaping would enhance security and reduce the risk of injection vulnerabilities.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

While I personally think we should pass -- (at least for sudo), this isn't present in the original source, so I'll leave this up to you, @lambdalisue.

As to the other 2 TODOs that I left, I'd like to implement these, if you'd allow me to; however, they are both out of scope of this PR. I'll implement them after this PR is merged, if you'd merge it.

Copy link

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

@aarondill
Copy link
Collaborator Author

@lambdalisue I've rebased this onto HEAD.
I've also introduced a few changes:
The checking introduced in 257767d is only done on 'sudo', since there's no guarantee that the user provided command will ever support not passing a password. Additionally, the user provided command is called the same way either way: user_sudo command with no options.

Copy link
Owner

@lambdalisue lambdalisue left a comment

Choose a reason for hiding this comment

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

LGTM

@lambdalisue lambdalisue merged commit 66727b4 into lambdalisue:master Mar 12, 2024
@lambdalisue
Copy link
Owner

Thanks a lot 🎉

@aarondill aarondill mentioned this pull request Mar 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants