-
Notifications
You must be signed in to change notification settings - Fork 11
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
Variable values should be escaped #11
Comments
I've been reading a blog article about how to escape shell command parameters in Node.js. The article starts by writing an example Node.js program that takes user input and passes it to a shell command. Then the article tells what kind of security implications this may have. For the Shell commands plugin, security risks are a bit different than for a web application. However, I'm not a security expert, so I can't possibly know all security risks. But here is some differences:
The actual point of my post begins here. I'll write here notes from the blog article that may be beneficial to this problem. The most useful part of the article for this case starts from the heading Input validation or output sanitization?. Quotes:
The example has nicely split the command Also, it's not possible to handle something like this only bit by bit: The bottom line is that while I did not yet find a solution just by reading, this has given me some small ideas, and most importantly now I can try the Shell-quote library for Node.js. I will explore it and see if it can provide a solution I haven't seen yet. |
I just read an interesting article about escaping strings in Bash, written a decade ago. The article simply suggests the following:
I'll need to try this. Obviosly, this is only for Bash, and I'll need to find out if the same would work for PowerShell too. I've lost my hope for CMD already, so I'm probably not gonna do anything for it. My current thoughts about escaping:
I hope that I will soon be able to bring up something concrete. |
To continue my previous post, I want to add that this escaping obviosly needs the knowledge about which shell is used. It seems that I have not yet started a discussion about an ability to choose the shell that is used for executing shell commands. I'll create a discussion for that some time later. There's already a discussion for making it possible to have operating system specific versions of shell commands (#38). I need to combine the two abilities somehow, to be able to have OS specific and shell specific versions of commands. When these are implemented, I think I can start to think about creating escaping rules for different shells, starting from Bash and PowerShell. |
Finally progress in this matter. I think I've managed to implement escaping for Windows PowerShell, at least according to a very quick test I made. I've also implemented escaping for Bash and Zsh (both for Linux and Mac), but I haven't tested them. For Bash I think it should work. For Zsh, I just made it to use the same escaping that bash will use - I hope Bash and Zsh are not too different in this regard. (Edit: they are a bit different. See my next comment). Nonetheless, I'll still test these things more to be certain, rather than just guess that things work.
And I'll repeat here just in case: All And last but not least, another thing to repeat: Windows's CMD will not get any kind of escaping. No matter if you use |
Source: https://apple.stackexchange.com/a/361957 Edit 2021-10-31: Nope, my quick test told me that Zsh uses |
I hope this starts to be in a good shape. I'm considering this done, at least at the moment. Let's see if beta testing will bring up any issues. |
One thing that I think I haven't mentioned here in GitHub, but that will be important about escaping: At least in Bash, due to special characters escaping, it's recommended to place Examples:
So this allows a simple usage of variables: If you don't need to add static text before or after a variable, you can just do: |
Done & released - at last. |
The problem
A quote from README.md:
An even worse example is this:
mycommand {{clipboard}}
, with clipboard happening to contain stuff likesome text > C:\path\to\some\important\file
. In this case, the command might end up accidentally overwriting some file without a conscious meaning from the user.Terminology
I mess up with terms. When I say escaping, I mean encoding. These might be different things (I don't know), so I need to clarify these terms later. But for now, you'll see me using both words escaping and encoding for the same thing.
The current state
The current behavior of the plugin is to not do any escaping for variable values, with mainly two reasons:
"
or'
characters, then the user should be able to expect that the result will be"
or'
, not e.g.\"
or\'
unless the user has consciously opted for escaping.Optional escaping
How would the user denote that they want to turn escaping on?
A global setting that escapes all variable values in all commands?Maybe I'd like to have more fine grained control over this.A per command setting to escape all variable values in a particular command?No because user might want to use different kind of escaping/encoding in different places of a command.escapedunescaped? E.g.!
, so that the value of{{!clipboard}}
would be unescaped, and the value of{{clipboard}}
would be escaped. (Edit 2021-10-30: Changed the logic the other way around, so that!
denotes not to escape).What to escape
How to know which characters need to be escaped? There are multiple ways parameters can be enclosed/quoted (I don't know a correct term) as shell command arguments:
One complicated way would be to inspect the particular command, and check that if a variable is inside quotes, check which quotes (single/double) are used and escape those in the variable's value.This might be too complex to accomplish, and too prone for errors. We need to have an escaping solution that is simple by its logic and that users can trust. I don't want to have a "black box" that I don't know if it works or not. Also this technique cannot reliably determine if the user wants to perform URL encoding.That's why there needs to be some explicit way for the user to define what characters will be escaped and what not.
URL encoding
Sometimes URLs might be used in commands, for example with Obsidian URI or when launching a web browser to open a specific web page or service, such as search from the internet using keywords from a variable.
For URL encoding, there are two different options regarding where the variable value will be actually placed in a URL:
https://duckduckgo.com/?q={{selection}}
. Here{{selection}}
should be encoded according to application/x-www-form-urlencoded (space is encoded with +).https://github.com/Taitava/{{selection}}
(to go to a specific repository under my GitHub account). Here{{selection}}
should be encoded according to the plain Percent-Encoding (space is encoded with %20).Major parts of the above text are copied 2021-09-16 from https://stackoverflow.com/a/4744917/2754026 . The source talks about URL encoding in PHP, but the same principles can be applied to development in JavaScript/TypeScript too. I just need to find the corresponding encoding JS functions.
Optionality and "What to escape" combined
In "Optional escaping" I suggested to use
!
as a flag which would indicate to escape the variable's value. It's nice and short. But it does need a way to indicate what kind of escaping the user wants. So I want to explore more ideas on how to define escaping. Here are some:!
in front of the variable name, e.g.{{!clipboard}}
(the same as I already suggested).{{url_encode:file_path:relative}}
. Here{{url_encode}}
variable would resolve another varible that is passed to it:{{file_path:relative}}
. You could even chain different encodings:{{escape_double_quotes:url_encode:file_path:relative}}
or apply the same encoding twice if needed:{{escape_double_quotes:escape_double_quotes:file_path:relative}}
. Downsides: 1) these are really long, but I could come up with shorter variable names, 2) No way to pass parameters to the encoding algorithm, e.g. what characters to escape if an algorithm can take an optional list of characters?I need to look into for example different templating languages, scripting languages etc. and see how they handle escaping definitions conveniently. This is certainly a non unique problem, so it must have countless of solutions already.
Different platforms
There are three operating systems that this plugin supports:
I have used commandline on Linux and a little bit on Windows. I don't have experience of Macs, but I need to find out how Mac commandline works, too.
Help wanted
If you are well experienced with command line stuff (Windows, Linux, or Mac), I'd like to hear your tips about what characters need to be escaped and in what situations. You can comment in this issue. Thank you, your support is highly appreciated! 🙂
If something in this issue is unclear, please comment and I'll try to clarify/rewrite things better.
The text was updated successfully, but these errors were encountered: