Cli: CLI Should NOT Render Decrypted Access or Refresh Tokens

Created on 9 Mar 2021  路  3Comments  路  Source: forcedotcom/cli

Summary

sfdx force:org:display --verbose, sfdx force:org:display, and sfdx force:user:display commands all expose sensitive information which should not be easily decrypted, specifically Access Tokens and/or Security Tokens.

Quote from Refresh Tokens: When to Use Them and How They Interact with JWTs

__Security considerations__

Refresh tokens are __long-lived__. This means when a client gets a refresh token from a server, this token must be __stored securely__ to keep it from being used by potential attackers. If a refresh token is leaked, it may be used to obtain new access tokens (and access protected resources) until it is either blacklisted or it expires (which may take a long time). Refresh tokens must be issued to a single authenticated client to prevent use of leaked tokens by other parties. Access tokens must be kept secret, but as you may imagine, security considerations are less strict due to their shorter life."

  1. A __bad actor__ could easily use the tokens to access an org and reset passwords, manipulate data, etc.
  2. The leaked refresh tokens, may be used to obtain new access tokens (and access protected resources) until they are either blacklisted or they expires (which may take a long time)
  3. The leaked access tokens may be used to manually set passwords via Dev Console, system.setPassword('005xx0000000XXX', 'passwordText'). Imagine admins getting locked out of their own org.

Rendering decrypted OAuth Tokens is not a feature, it is a practice that should be avoided with OAuth.

Most helpful comment

Follow-up: I reviewed the CLI with our security teams again and everything is working as designed. If a bad actor has access to the machine, consider this: They could read every file you have access to, including tokens for every other CLI and SSL connection. They could rewrite every script and scripting language tool to do whatever they wanted. If they have more than user access, they could intercept and redirect every single request made on your machine. They could capture every keystroke (and therefore password) on your machine.

This is precisely why we show warnings when installing CLI plugins not signed by Salesforce. More than that, you should be aware of this with every client-side tool you use. This is why IT restricts the use of certain tools. In addition, good security policies should be used on a Salesforce org using the principle of least privligaes and using extra measures and good practices with connected apps. And if all of that isn't enough, you can disallow the use of the Salesforce CLI in your organization (at least with the default connected app). If that is the case, you will probably want to disallow the use of every other major CLI (npm, aws, azure, etc).

All 3 comments

Thank you for filing this issue. We appreciate your feedback and will review the issue as soon as possible. Remember, however, that GitHub isn't a mechanism for receiving support under any agreement or SLA. If you require immediate assistance, contact Salesforce Customer Support.

Client-side tools are a different ball game, especially ones written in node. If a command is run as user, all bets are off.

Here is what we do:

  • We use all oAuth security measures when requesting a token
  • We encrypt tokens on disk and in memory in the core libraries
  • We use OS-specific keychains when possible, and SSL level permissions when not.

There are many reasons why we need to show tokens when requested, so that is not changing. "_Rendering decrypted OAuth Tokens is not a feature_" is debatable. We guard the refresh token more, but similarly, there are many situations where it needs to be exposed. According to your quote, we do store them securely but just give them to you when asked.

We could make it so it isn't the default, making it less likely to be accidentally shown in CI or some other environments. Here is the thing though: going back to my original statement, we can't completely protect tokens on a client machine using node. We have to store them somewhere and code ran as user could decrypt them from storage using the keychain if they wanted. This is specifically why we display warnings when installing plugins.

If there is enough community comments on this, our security teams can take another look at this but as of now it is working as designed.

Follow-up: I reviewed the CLI with our security teams again and everything is working as designed. If a bad actor has access to the machine, consider this: They could read every file you have access to, including tokens for every other CLI and SSL connection. They could rewrite every script and scripting language tool to do whatever they wanted. If they have more than user access, they could intercept and redirect every single request made on your machine. They could capture every keystroke (and therefore password) on your machine.

This is precisely why we show warnings when installing CLI plugins not signed by Salesforce. More than that, you should be aware of this with every client-side tool you use. This is why IT restricts the use of certain tools. In addition, good security policies should be used on a Salesforce org using the principle of least privligaes and using extra measures and good practices with connected apps. And if all of that isn't enough, you can disallow the use of the Salesforce CLI in your organization (at least with the default connected app). If that is the case, you will probably want to disallow the use of every other major CLI (npm, aws, azure, etc).

Was this page helpful?
0 / 5 - 0 ratings