rfjakob / gocryptfs

Encrypted overlay filesystem written in Go

Home Page:https://nuetzlich.net/gocryptfs/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

-extpass option does not support arguments containing space

slackner opened this issue · comments

As the title says, currently -extpass does not support arguments containing spaces. This limits the flexibility quite a bit, since its not possible to pass any untrusted user arguments. Extpass should either understand quotes, or support a syntax similar to find -exec, e.g., gocryptfs -extpass arg1 arg2 \;

You mean somethink like

-extpass "cat "my password.txt""

?

Bad example as this can be done with -passfile...

Yes, something like this, but let's assume its a different program than cat, otherwise it would indeed be preferred to use -passfile. Examples could be:

  • -extpass "sha256sum \"my keyfile.txt\"" (space in argument)
  • -extpass "\"$HOME/getkey.py\"" (might contain space in $HOME)
  • -extpass "\"my program.sh\"" (space in program name)

What if it contains a quote character?

For a shell-like syntax, normal quotes would have to be escaped. As a result, the escape character itself also has to be escaped. Adding code for that will certainly make the code more complicated.

If we want to avoid the complexity, we could either use the version where the command is passed as separate arguments (cf. find -exec), or always prepend /bin/sh, -c and let the shell deal with decoding the arguments. Something like this would work, for example: /bin/sh -c "cat 'my keyfile.txt'".

I've thought about this a bit more. Although I'm not really sure how many people are using -extpass, I fear we cannot change the syntax completely without breaking existing applications, so this is not an option. And having two command line options, one for the old and one for the new syntax, sounds even worse.

The idea with using /bin/sh -c ... would work, but is also very ugly. It would allow to embed multiple shell commands separated with ";" as part of -extpass, and we probably don't want that.

Considering all options, I think the best one is to add support for shell quotes. There are also existing projects we could use, e.g., https://github.com/kballard/go-shellquote. (Note that this is just one of the first search results, maybe there are also other / better projects out there.) What is your opinion on this direction?

I think the use case is valid, people use spaces in file names, and we should support that.

Passing a user-controlled string to the shell for interpretation is super scary. We would place the burden of sanitising the string on the caller, and that's a ticking time bomb, because it is so hard to get right.

The shellquote thing could work, i guess, but i think i would prefer an even simpler solution: have a new flag, "-extpass-raw", that can be specified multiple times. For example,

gocryptfs -extpass-raw sha256sum -extpass-raw "my file.doc"

While this should work, I think it would be better to have a bit shorter name, so we can deprecate the old -extpass behavior at some point.

What about allowing -extpass itself to be used multiple times, and add fallback logic if it consists of exactly one element, but isn't the path to a executable?

Hmm this can lead to unexpected results when the "executable name" may contain spaces:

-extpass "userpassword.py"

-extpass "rm -rf /"

Based on my understanding this issue already exists right now. By implementing some legacy logic to split parameters we could ensure that existing scripts continue working during the transition, and then remove the fallback logic in one or two versions. But I agree, its not that easy to check if the parameter is a valid program - we would also have to take into account the PATH environment variable, for example.

BTW: While we probably still shouldn't do this, encfs has chosen the /bin/sh -c ... approach:
https://github.com/vgough/encfs/blob/249d0942fece79419732c7b1f64fd76d0eda0927/encfs/FileUtils.cpp#L1530

Implemented in cf27037 . I have added guidance for how to use -extpass correctly to the man page.

Thanks! I think this is a good compromise.