-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
dangerous eval's in the shell code #3459
Comments
That part is bogus... I forgot hat the options are (as far as I can see: always) given via the env var |
As for the I'd say that: Line 154 in a3ff49a
and: Line 156 in a3ff49a
are IMO safe, as orig_complete is only from controlled input ($(complete -p "$orig_cmd" 2> /dev/null) ) and the functions called before (_completion_loader and __fzf_orig_completion ) don’t seem to modify it.
Line 175 in a3ff49a
is unsafe as mentioned before, actually I don’t even understand what it does (I mean I don't understand what it's supposed to achieve). But printf ’s %q might be used to make it save!?
Line 185 in a3ff49a
is AFAICS save, $1 is controlled by us and either _fzf_compgen_path or _fzf_compgen_dir and the rest of the string is already escape via printf ’s %q .
TODO: check (it's too late and I don't understand it right now ^^): Line 358 in a3ff49a
|
Without the line, something like |
Ah, I see. Well… if it was just for One could perhaps try to escape any other expansions/substitutions, but I think that's also difficult to do propely and likely fragile. Using |
I've just seen that bash-completion provides a number of functions ( If you'd say it's enough to support just that, we could simply use the right one from bash-completion, and simply do nothing if it's not available (honestly, who uses |
The more I think about it, the more I'd come to the conclusion that simply only a) It seems to require a more or less a shell code parser to determine what to expand: What I would actually rather like was, if e.g. Anyway… would you consider to support only |
That's just a guess. We have no data to support this claim. For example, I installed bash-completion only a few years ago after using fzf for several years before that.
|
Arguably ;-)
In my opinion we (from the This in turn means, that we should not define our own e.g. So in the end I think we can do the following:
If you have a good idea t do the Actually, expanding vars may even destroy some uses cases: |
Of course, the last point also applies to my idea of expanding shell patterns ( Maybe, readline’s |
A simple fix: ee4ba10 Fuzzy completion is not provided if the prefix contains a pattern that is potentially dangerous. I think this will cover 99.9% of the use cases (all existing test cases are passing) and remove the risk. Please let me know if there are any other risky scenarios.
Good point. But it can be tricky to get it right. This example shows an approach that doesn't expand the prefix, the problem is the preview program will no longer work. TEMP=/tmp
dir='$TEMP'
eval "dir_eval=$dir"
if [ -d "$dir_eval" ]; then
(cd "$dir_eval"; ls) | sed "s@^@${dir}/@" | fzf --preview 'cat {}'
fi
|
At first I though I could easily find a way to still break that, but turns out it looks mostly good (at least for a start).
However… 😈
In general, I'd feel much safer if your check was much broader, e.g. something like:
which I'd probably extend by
Other questions: b. Cosmetic: Line 173 in e833823
Line 238 in e833823
You use now two different quoting styles (with and without "…" ) shouldn't matter though for [[ … ]] , IIRC bash doesn't perform word splitting there, does it? Still, I personally like to quote it.
|
btw:
I'd no longer consider my own argument valid. ^^ I mean if someone does If however, if a user doesn't want expansion - well than simply don't use fzf-completion on that word. And I mean, if one does e.g. |
Actually, there may be an exception from the above: IIRC, a while ago, either bash or bash-completion, caused something like I for example, made a keybinding that does So assuming I'd accidentally press ... I might still want a way to not do the Well not sure what make sense... maybe it would be nice to have a config option that allows to disable the |
Oh and have you had a chance to double check the other Especially this little fella: Line 358 in a3ff49a
|
Wow, you tried really hard to break it, thank you. It's a relief to hear that you couldn't find a way to run an arbitrary command. I can't answer all your questions right now because my time is limited and I don't have a comprehensive knowledge of the inner workings of bash. I'm looking for practical solutions through a series of trial and error, and I'll move on when I feel they're good enough, and then the community will fill in the missing pieces.
I noticed that too, but that part is required for zsh and I wanted to put the same code in two implementations so I added it anyway. Wouldn't hurt. Not including I also found that
Agreed. I think we'll probably be fine once we reject a few more characters. |
What perplexes me is that when you trigger fuzzy completion on The default completion doesn't trigger in this scenario, so we probably shouldn't try either. Do you know when the default completion is triggered or not? FWIW, it works on |
Well, point (2) above is in principle a side-effect which also allows for execution, consider e.g.
I wrote another mail to help-bash, asking whether there's a real proper way for what we want to do.
Well it might lead to more false positives (probably not, if bash splits words on
Are you going to add it, or shall I make a PR?
I think this is the same as my point (4) above. Again I don't understand why bash splits the command as it does, but the problem is the lone
My I propose first, that I split up the points from above into separate issues. I guess otherwise it gets to messy here. Ok for you? |
Indeed... Sounds like this could be some bug in bash? Would you mind to report it?
No idea, sorry... |
Good point. Thanks for the enlightenment.
Got it.
I think it's safe to just suppress the error message. Or, we can just give up trying in those wacky cases.
Removing COMP_WORDBREAKS=${COMP_WORDBREAKS//:} |
Take two. * Avoid eval if the prefix contains `:=` * This is not to evaluate variable assignment. e.g. ${FOO:=BAR} * [zsh] Prevent `>(...)` form * Suppress error message from prefix evaluation * Stop completion when prefix evaluation failed Thanks to @calestyo
Can never know if a command is evil or not. Any side effects shouldn't be allowed. The normal tab completion doesn't trigger in those cases anyway, so yeah. |
Looks good on a first glance.
Might be enough. At least right now I cannot think of any way, where the syntax error could be abused or cause accidental damage (after all, it shouldn't even execute).
Hmm it still feels like a bug, which is only worked around by the removal of |
Well sure, it's of course better to catch too much, than to few... but ideally a definite solution would just catch all the right cases. |
Well, I don't think I understand enough of the situation to report the bug (or feature?) in a concise way. A quick Google search revealed that people have been suffering from colon problems in completion for ages. Sigh.
|
I've just noted some interesting things (Debian sid, with bash-completion 2.11 and bash 5.2.15):
the
I mean that's IMO the best one can get: completions but not expansions On the other hand:
is not completed Further, after:
we have:
Now:
results in:
However:
correctly gives:
(that is: completion but no expansion). Similarly:
gives:
but:
expands correctly to:
No |
However…
Now:
completes to:
=> dammit... that should be and:
to:
=> that would be good. |
@junegunn Well... stupid me always looked at my Debian's bash-completion code (which is version 2.11, which is the most recent one - yet still hopelessly outdated) ;-) It seems that bash-completion in git may already have what we need: I only made some very simple checks so far, but it seems it even catches case (2) (i.e. |
Made some more tests with First some caveats: The former (i.e. execution in cases like The case described there with Apart from that:
AFAICS, this is all expected and what we'd also want. It also seems to catch cases like:
Which should hopefully still prevent any shenanigans in case the user changed |
man fzf
)Info
Problem / Steps to reproduce
Hey.
By chance I've stumbled over the following:
If I now do:
and then ESC without any selection being made (but I guess it would also happen if a selection is made), one gets the following messed up line on the prompt:
which I then abort with
Ctrl-C
, so it's not executed by me pressing Enter, yet:The reason for this is likely:
fzf/shell/completion.bash
Line 175 in a3ff49a
Perhaps less of an "attack", but one can "easily" imagine that someone accidentally writes:
$(rm -rf / )**<TAB>
rather than a safe$(rm -rf / ) **<TAB>
(with a space before the**
).Any
eval
s on values which in turn had some expansion/substitution are always dangerous, unless it's made sure that those cannot contain other shell code.I haven't checked the other
eval
s incompletion.bash
yet.The
eval
s inkey-bindings.bash
are IMO safe, because for them it's fully expected by the user, that whatever is set inFZF_ALT_C_COMMAND
and friends, is executed.However, vars like
FZF_TMUX_HEIGHT
,FZF_DEFAULT_OPTS
may also accidentally be used to execute any commands... maybe one should check them for "evil" shell meta-characters (like;
,$
and more) and ignore them if set.Cheers,
Chris.
The text was updated successfully, but these errors were encountered: