AzureAD / microsoft-authentication-library-for-python

Microsoft Authentication Library (MSAL) for Python makes it easy to authenticate to Microsoft Entra ID. General docs are available here https://learn.microsoft.com/entra/msal/python/ Stable APIs are documented here https://msal-python.readthedocs.io. Questions can be asked on www.stackoverflow.com with tag "msal" + "python".
https://stackoverflow.com/questions/tagged/azure-ad-msal+python
Other
795 stars 200 forks source link

[Feature Request] Reduce risk of oauth token compromise by storing tokens in $XDG_RUNTIME_DIR #690

Closed nickweeds2 closed 5 months ago

nickweeds2 commented 5 months ago

MSAL client type

Public

Problem Statement

Microsoft products such as Azure CLI and git-credential-manager rely on MSAL to authenticate to Azure and Azure DevOps. On headless Linux systems the MSAL client libraries store oauth tokens unencrypted. Applications can override this by passing MSAL an application-specific credential cache, and some applications (e.g. git-credential-manager) appear to do so to improve security in some cases. However, standard headless Linux configurations remain unencrypted, and other applications do not add their own credential cache. Some applications (e.g. git-credential-manager) also warn if oauth tokens will be stored unencrypted, but again others do not. This is unfortunate because user oauth tokens are only as secure as the least secure application using MSAL. This means that anything that can be done to improve the security of the default MSAL oauth token storage would be worthwhile.

It is understandable that MSAL stores oauth tokens unencrypted on headless Linux because headless Linux does not provide a standardized credential store.

What can be done ?

One simple improvement would be to store oauth tokens under directory $XDG_RUNTIME_DIR when this exists.

Many Linux distributions use systemd, and systemd creates a user session when the user logs in or starts an SSH session. When the user session is first started systemd creates a tmpfs runtime filesystem and sets $XDG_RUNTIME_DIR to the runtime filesystem. When the user's last session ends systemd deletes the user's runtime filesystem. This is observed on both Ubuntu and Mariner.

This has two immediate benefits:

  1. The runtime filesystem uses tmpfs so oauth tokens stored in $XDG_RUNTIME_DIR are not stored on disk.
  2. The runtime filesystem is deleted when the user sessions terminate, so oauth tokens stored in $XDG_RUNTIME_DIR are deleted at the end of the user session.

Together these features protect the oauth tokens almost as well as Gnome Keyring on desktop Linux or DPAPI on Windows (both of which allow any program in a user session to access / unencrypt secrets).

Side effects of the proposed change:

We might want to allow users to override this behavior and store oauth tokens under $HOME rather than $XDG_RUNTIME_DIR so that users can avoid these side effects (at the cost of persistent oauth tokens) if they wish. This could be done using an environment variable to force oauth tokens to be stored under $HOME rather than $XDG_RUNTIME_DIR.

Proposed solution

When storing unencrypted oauth tokens on Linux, check whether $XDG_RUNTIME_DIR is set and refers to a valid directory, and if so store oauth tokens under $XDG_RUNTIME_DIR rather than $HOME.

See also: microsoft-authentication-library-for-dotnet issue 4720.

rayluo commented 5 months ago

Thanks, @bgavrilMS , for triaging this issue before triaging the same one in the .Net repo. :)

With regard to @nickweeds2 's proposal, actually MSAL does not decide where to store the token cache, MSAL just stores token cache in memory by default (which is more secure). It is the calling app to provide a path for token cache persistence location. We might be able to append $XDG_RUNTIME_DIR if the caller happens to provide a relative path, but probably not for an absolute path.

Before we get into the details of "how", I would like to hear from one of our downstream partner - Azure CLI. Will the following side effect be acceptable for an Azure CLI scenario, @jiasli ?

Side effects of the proposed change:

  • Users who exit an SSH session and start a new SSH session need to re-authenticate.
  • Processes left running after the SSH session ends (e.g. using nohup or tmux) lose access to oauth tokens.
nickweeds2 commented 5 months ago

This is an issue for applications such as azure-cli.

rayluo commented 4 months ago

This is an issue for applications such as azure-cli.

Agreed with @nickweeds2 . I also modified MSAL Python's document to mention XDG_RUNTIME_DIR in a recipe, without actually changing MSAL's default behavior. I guess that is what MSAL can do here.