1. 56
  1. 17

    I’ve always been somewhat skeptical of products that boast about UX before anything else but reading that thread is a little… obtuse, I guess one might say?

    Looking at the report, you seem to be reporting something that is a general concern for all CLI utilities on Linux or BSDs that handle secrets

    I mean… it is a general concern, as in yes, command-line arguments are exposed. That’s why you don’t pass secrets through command-line arguments. There are plenty of CLI tools that don’t suffer from this particular problem, by e.g. passing secrets via stdin.

    In wider terms, and I realise this may sound overly paternalistic, I don’t think it’s a good idea to evaluate UX/security trade-offs based on what a proportion of users consider to be a major concern. While everyone is obviously responsible for their threat model, there are plenty of design choices which are either bad under pretty much any threat model, or which limit the range of realistic threat models you can deploy on, whether their users realise it or not. In more illustrative terms, most users don’t think emails from heirs to the Nigerian throne or from their banks’ customer support teams are a major concern, either, but we still devise anti-scam tools, because said users are wrong. In fact, their propensity for reusing passwords and handing them over to *air quotes* their banks’ customer support teams is one of the reasons why password managers are a thing in the first place.

    As the author points out, it’s hard to see how this is even a trade-off – it’s either an extra pipe or, with a slightly more radical redesign (which, okay, may be unpleasant to deal with), none at all. Maybe it makes automating the generation of records slightly more difficult? It’s admittedly easy to not see these things from the outside, but when even GnuPG managed to get this one right, you just have to wonder what on Earth the trade-off could’ve been.

    1. 12

      Can I just ask why anyone in their right mind would be using a command line password vault on a multi-user system where the other users aren’t implicitly trusted anyway?

      I’m not suggesting that vendors should get carte blanche, but I also think this amounts to punishing a vendor for having taken the time and effort to make their amazing (in my opinion :) toolchain available for Linux.

      1. 9

        Maybe I’m just weird, but it really feels like the number of folks using Linux as their daily driver is vanishingly small, in relative terms, and the number of those folks who have multiple interactive users on a single machine is even more vanishingly small?

        1. 4

          I figured the fact any “user” (as in user account) that can see the CLI args can be extended to any “program” bring able to see CLI args, including malware. But in that case the malware would be your more pressing concern.

          1. 3

            Right, I mean, I’m not trying to minimize the problem, but maybe the framing of “any interactive user” carries less weight because to the first approximation there are no 1Password customers on machines with multiple interactive users.

            1. 2

              Yes I think that’s fair enough.

        2. 4

          Truth to be told, 99% of macOS systems are not really multi-user. I work with the command line daily and I’m the only one who pops from my macbook pro to my iMac, which features two users: me and my wife (doesn’t know/care what the CLI is).

          The issue is real, but the impact is small(ish) IMO.

          1. 2

            Your question was my first thought also.

            I stopped using 1Password because they kept pushing the subscription model harder and harder and their new stuff doesn’t let me bring my own sync. (I don’t care that much whether I buy a perpetual license or pay for a subscription… I’m keeping my password manager up-to-date anyway. But I want to keep my password database somewhere other than their servers, and they’ve been discontinuing the ability to do that as they move more users over to subscriptions.) That is what shoved me to BitWarden.

            I was happy except for that, and this issue would not have moved that needle for me. Using their password tools on a multiuser system feels like using ssh agent forwarding on such a system. If you don’t trust the other users, you’re gonna have a bad time.

            1. 1

              I can totally appreciate that. I did in fact move to the hosted 1Password subscription service, but only because to be honest I purposefully maintain my personal computing life in such a way that it’s sufficiently ‘low stakes’ that even a full on vault compromise would be annoying at best and in no way catastrophic.

              That said I COMPLETELY understand why someone might not be comfortable with that, or the new subscription model. I’m actually pretty happy with it because we use the ‘family’ sub and my wife and I can share passwords and the like with a single click.

            2. 2

              IMHO the biggest and most important problem, even more important than the potential leakage of secrets (which, at the end of the day, is deemed acceptable or not in terms of a threat model, not in absolute terms) is that this isn’t more prominently documented. It’s an unusual choice (most CLI utils don’t use this method for passing secrets) so a lot of users probably don’t even spend much time thinking about its consequences, as they never had to do it before.

              Other than that, I think it’s simply a problem of unnecessarily introducing yet another leakage mechanism (well, several, actually), even among applications running on machines that are effectively single-user. While there are certainly bigger fish to fry, even moderately smart malware can get along just fine on nothing but smelt.

            3. 9

              That’s unfortunately also why I have to close this as a duplicate, as work is in fact already underway to find a way to process input from the stdin.

              Glad they’re at least working on it. Sucks that there was no payout; they may have been planning to support stdin, but they didn’t say the reasoning was for security, and they didn’t know their docs needed updating too.

              1. 12

                It isn’t clear at all to me that they’re working on it:

                1. The documentation website doesn’t mention the security risk at all. This is, imho, negligent.
                2. They make no commitment at all about releasing the fix. Fixing the bug before the heat death of the universe would satisfy the “working on it” task. The idea that you need to “try to find a way to process input from the stdin” screams, to me, “yeah we’re tracking this issue in the bottom of the backlog from 2 issue trackers ago.”

                Edit: as an aside, I really don’t care about a payout. I took the issue to bugcrowd to be certain it was seen and replied to.

              2. 5

                This is pretty careless, and the fact that they know and don’t care makes it egregious. As you well point out there isn’t even a usability tradeoff in play here, just composing the command differently would help.

                Perhaps it’s worth reminding them that it isn’t just other trusted users of a system getting access to the secrets, it is any process on the system, authorized or not. They have some (not lots but some) measures to protect users against keyloggers, clipboard scrapers, shoulder surfers, and screen recorders; yet they just blindly trust every process on the system with CLI secrets?

                1. 3

                  On the one hand, using a password manager this way, versus reusing the same crappy password on 100 websites, will make orders of magnitude more improvement to my security than fixing this problem will.

                  On the other hand, I expect my password manager vendor to employ the class of security professionals that are constantly worried about and actively protecting me from threats I would never even think of, not telling me to do things that even I know are bad. It’s not confidence-inspiring.

                  1. 3

                    In 2021, what is the best method to pass secrets to CLI apps and shell scripts?

                    1. 3

                      Everyone will fight for their preferred method, but I’ll mention some of the more common ones:

                      1. Have your app go get it’s own secret via some command you run(say via a config option) that returns the password via stdout. You just suck it in, and make generating the secret some other person’s problem.

                      2. Have your app read it from a file or file descriptor (i.e. a pipe or an actual file or stdin) The actual file could be on an in-memory file system so it doesn’t live past reboots

                      3. pass it via an ENV variable, this almost ensures a leak vector, since /proc and loads of debugging tools make ENV variables of processes quite easy to see.

                      4. Hide it in some blessed “tool”, something like hashicorp vault, or gpg or whatever suits your fancy and only support said tool.

                      I put them basically in my preferred order, but usually what I do is a mix of 1 & 2. I.e. by default I accept the password via STDIN, but have an option to run some command to get it, the command is defined by a config option.

                      1. 1

                        Not sure if files have always been the best way, but a very nice feature about them is you can control permissions.

                        1. 3

                          The issue with files is that you store unencrypted information on the filesystem, which is forbidden in a number of companies or regulations. We use network to fetch secrets which provides audit and easy secrets update, etc… but that doesn’t work well for cli apps that are used for tooling etc…

                          1. 1

                            It’s not a perfect solution and obviously, depending on companies and regulations, it may not be a solution, either, but it’s usually considered a slightly better option to use pipes for transferring data locally. They are not backed by non-volatile storage and the range of trivial snooping options is more restricted.

                            Edit: this works quite well for CLI apps that are used for tooling, with the caveat that it’s pretty easy to misuse (e.g. sooner or later someone will write plaintext passwords to a file and pipe that). That’s kind of inevitable, though, and still slightly better than handing over secrets via command-line arguments, as you can at least chown files on volatile storage, whereas CLI arguments are basically public to other users on most systems, and stay in the shell’s history file for a while…

                            1. 1

                              Nobody says they have to be unencrypted, you can encrypt files at rest.

                              They don’t even have to be files at all, named pipes are one way to make a file-like access model work without ever having data on disk, you can connect your network fetch to that.

                              You can even simplify from there and use shell process substitution to wire up a network command to a file interface.

                          2. 1

                            I think a pipe could work; I was going to sketch it out, but there’s already an example in the thread, with an alternative:

                            op encode < login.json | op create item "Login" -

                            Or skip this encode step:

                            op create item "Login" ./login.json

                            In twelve-factor apps, environment variables are used for credentials and configuration.

                            1. 4

                              This article details some reasons why environment variables may not be a good option for secrets.

                              TL;DR: it’s easy to leak env var values to child processes, debugging/error/crash logs, and access is hard to track

                              1. 1

                                The login.json is stored in plain-text, right? And if we change its chmod, the caller script should also have the lifted chmod?