Submitting as delegate for a Cisco pen-testing team
This is a modification on the product to adopt secure best practices to enhance the security posture and resiliency of the product.
Headline: Jenkins stores API tokens in a recoverable format
Versions: 1.620, 1.622
CWE Tags: CWE-257
Jenkins allows users to authenticate via multiple credentials including a
Jenkins-generated API token. This API token provides the user with a fully
authenticated session (the same as if the user had logged in using a password).
Although the user's password and API token provide equivalent access to Jenkins,
these credentials are not stored with equivalent security protections. User
passwords are stored as salted hashes (SHA-256 or bcrypt); whereas API tokens
are encrypted using an AES-128 ECB-mode block cipher, using a static key shared
among all users. As a result, an attacker with sufficient access to internal
Jenkins datastructures can decrypt API tokens and impersonate any user.
User credentials should never be stored in a recoverable format (e.g. encrypted)
unless the application requires them to authenticate on behalf of the user (e.g.
to authenticate to an external system). Jenkins does not appear to have any
such reason for storing API tokens in a recoverable format, as the API token
appears to only be used for inbound authentication.
It is assumed that Jenkins developers may have chosen to store API tokens in a
recoverable form in order to implement the "Show API Token..." functionality
contained on the user configuration page. This is a dangerous feature, as an
application should never display stored user credentials via the UI. If an
attacker were able to gain unauthorized access to an authenticated session, he
could utilize this feature to trivially recover the user's credential.
Just as a user never needs an application to display his stored password, a user
should never need an application to display a previously stored API token. When
first generated, the application can display the API token to the user. If he
loses/forgets his API token, a user can request a new token be generated (and
displayed). If it's deemed useful to allow the user to confirm the value of his
API token, Jenkins could store a few characters of the API token that could be
displayed to the user (e.g. similar to displaying the last 4 digits of a credit
It is recommended that Jenkins securely store user API tokens in a
non-recoverable form (e.g. using a strong, salted, one-way hash). Making this
change will necessitate removal of the "Show API Token..." feature, which can be
simply replaced with the existing "Change API Token" feature.