erlef / rebar3_hex

Rebar3 Hex library
Apache License 2.0
101 stars 49 forks source link

password issue #126

Closed benoitc closed 3 years ago

benoitc commented 5 years ago

I noticed that now rebar3_hex is asking for a local password forcing the user to type it. I'm wondering what is the reason for it. Since it force you to type a static password which can happen in public location what security does it add? Disabling a key remotely should be enoug, since the access to a machine should already be protected. How can we disable it?

ericmj commented 5 years ago

Any password you type can be in a public place, I don't think that removes the benefit of passwords. The password encrypts your API key meaning that if someone gains access to your access they do not get access to your Hex account. This works similarly to password managers or browser auto-fill that asks for a password before giving you the credentials to a service.

Have you tried filling in a blank password?

ferd commented 5 years ago

do note that the local password (along with measures like 2FA) is probably good idea to prevent misbehaving code from publishing on your behalf. See https://jamie.build/how-to-build-an-npm-worm or https://medium.com/@gajus/distributing-a-self-replicating-malicious-code-using-npm-cf2bf3209293 for examples where it happened on npm.

It would be easy to imagine similar scenarios in Erlang or Elixir where the known path where credentials are stored are used by a plugin, build hook, or parse transform in a dependency, in order to start gathering credentials and then re-publish the same malicious code in other libraries automatically.

The "access to a machine" is not as guaranteed as you'd imply, and we're probably more interested in validating "actual intended human initiating the operation" rather than "actual machine running the operation"

benoitc commented 5 years ago

Any password you type can be in a public place,

yes this is why some people never type a password in a public place. That's really an extra security compared to unlist the authorized machines or keys in doubt or having 2FA.

It would be easy to imagine similar scenarios in Erlang or Elixir where the known path where credentials are stored are used by a plugin, build hook, or parse transform in a dependency, in order to start gathering credentials and then re-publish the same malicious code in other libraries automatically.

Dependencies or plugins are supposed to be checked by the user and this case the risk can be worth than having a key to hex.pm stolen. A password will not prevent such risk you're describing. I guess having package signed would mitigate part of it, plus making sure that the build can't access to the whole system.

At least maybe that could be optionnal? Or provide alternative auth system like adding it to a keychain so the publishing can be automated?

ericmj commented 5 years ago

yes this is why some people never type a password in a public place. That's really an extra security compared to unlist the authorized machines or keys in doubt or having 2FA.

Right, but it's not an argument against passwords. You can revoke API keys and we want to support 2FA, unfortunately our time and resources are limited so we have not been able to implement it.

Dependencies or plugins are supposed to be checked by the user and this case the risk can be worth than having a key to hex.pm stolen. A password will not prevent such risk you're describing. I guess having package signed would mitigate part of it, plus making sure that the build can't access to the whole system.

A password would stop this. Your credentials are encrypted with the password so they cannot be stolen if the machine is compromised.

This is called layered security. Just because some other mechanism or manual check should catch the problem does not mean we should try to prevent it in other ways.

At least maybe that could be optionnal?

Have you tried supplying an empty password? Mix supports this, not sure if rebar3 does.

Or provide alternative auth system like adding it to a keychain so the publishing can be automated?

I am not sure how this would be implemented in Erlang in a cross-platform way. Contributions in this area are always appreciated.

tsloughter commented 5 years ago

It will not be optional since it is about protecting the ecosystem. Like vaccinating kids :).

Making it optional makes us vulnerable to the npm worm.

benoitc commented 5 years ago

A password would stop this. Your credentials are encrypted with the password so they cannot be stolen if the machine is compromised.

what i meant is that if a dep or a plugin can access to the file system, then the issue is worth. I doubt people would just stop to get a key.

It will not be optional since it is about protecting the ecosystem. Like vaccinating kids :).

if it protects anything. If the risk you mention exists I could simply install a keylogger as well or patch any beam....

benoitc commented 5 years ago

Or provide alternative auth system like adding it to a keychain so the publishing can be automated? I am not sure how this would be implemented in Erlang in a cross-platform way. Contributions in this area are always appreciated.

I will have a look. One thing that could be done at first is to make such auth pluggable. I will have a look on the current implementation.

ferd commented 5 years ago

if it protects anything. If the risk you mention exists I could simply install a keylogger as well or patch any beam....

Since the key is encrypted, any worm wanting to re-publish on your behalf has to ask for your specific hex.pm local password on this machine in order to go forward, or wait silently until you publish a package to go and grab the password through a keylogger, which assumes you are running builds on a dev machine with elevated privileges.

The one most worrisome part would be to have the code patch the code that publish the packages itself. That would indeed break the protection, but because of the password would still require someone to manually publish code to hex from a compromised machine, as opposed to merely railroading it and publishing without any user consent.

It's not 100% effective, but it lowers the surface area and makes worms less interesting to develop, and much slower to propagate. You can imagine the worm propagation rate to be stupidly fast without the password, and rather slow and manageable with it.

@ericmj mentioned layered security, and the ability to respond to an incident is also part of that. The password may make it possible to have an issue raised, a packaged cleaned, and the whole propagation stopped within a few days without compromising most of the ecosystem, whereas without a password, infecting one big library might be enough to compromise most of it within a few hours.

starbelly commented 4 years ago

@benoitc Is this still an issue since you can now use HEX_API_KEY to circumvent local authentication?

benoitc commented 4 years ago

How is this supposed to work?

On 19 Apr 2020, at 03:42, Bryan Paxton notifications@github.com wrote:

@benoitc https://github.com/benoitc Is this still an issue since you can now use HEX_API_KEY to circumvent local authentication?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/tsloughter/rebar3_hex/issues/126#issuecomment-616003691, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAADRIQVM4ADCIKZSF4LPLDRNJJIHANCNFSM4H5B54TQ.

starbelly commented 4 years ago

@benoitc You generate a key either on hex.pm with write permissions or via rebar3 hex (use hex.pm for now until next rebar3 hex release though)...

Example:

env HEX_API_KEY=some_key rebar3 hex publish

Of course I would be remiss if I didn't point out that publishing this way is discouraged by hex and rebar team... it was added recently because people were automating publishing in CI regardless.

fenollp commented 4 years ago

If the rebar3 hex plugin can read that env then isn't any rebar3 plugin also capable of stealing hexpm write access?

starbelly commented 4 years ago

@fenollp That sounds right and why this method is discouraged and in light of that we should offer a switch. You still have problems that @benoitc alludes to with passwords, but it would circumvent the env problem you pointed out.

starbelly commented 4 years ago

@benoitc provided the option of using a blank password, does this resolve the issue for you? If not, what suggestions do you have?

IMO we should not allow blank passwords and in a better world we wouldn't allow api keys to be passed in the env or via a switch. This should be a very strict and rigid operation IMHO, publishing packages should not be convenient in this regard.

benoitc commented 4 years ago

@starbelly maybe having TOTP based on the key would do the trick? at least it would solve my original issue.

starbelly commented 4 years ago

@benoitc yeah... you mean like yubkey or just topt in general? There has been discussion around supporting the existing TOPT support for hexpm user interface on the cli. Also discussion around fido/u2f support.

benoitc commented 4 years ago

TOPT in general. Having U2F would be awesome

starbelly commented 3 years ago

@benoitc Right, so in order to support TOTP we have to complete https://github.com/erlef/build-and-packaging-wg/issues/21

Since that is being handled there, I will close this issue.