Landscape insecure tokens generation

Bug #1929034 reported by Anton
260
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Landscape Server
Fix Released
Critical
Simon Poirier

Bug Description

Hi team!

Landscape API Access and Secret keys are generated using python random.choice() function:
/opt/canonical/landscape/canonical/lib/credentials.py

import random
import string

__all__ = ["create_access_key", "create_secret_key"]

def create_access_key():
    """Create a randomly generated 20 character access key."""
    key_choice = string.uppercase + string.digits
    key = []
    for i in xrange(20):
        key.append(random.choice(key_choice))
    return "".join(key)

def create_secret_key():
    """Create a randomly generated 40 character access secret."""
    secret_choice = (
        string.uppercase + string.lowercase + string.digits + "+/")
    secret = []
    for i in xrange(40):
        secret.append(random.choice(secret_choice))
    return "".join(secret)

Python random module uses the Mersenne Twister as the core generator. As it is a pseudo-random numbers generator it is not suitable for generating secrets.
From https://docs.python.org/2/library/random.html:
Warning The pseudo-random generators of this module should not be used for security purposes. Use os.urandom() or SystemRandom if you require a cryptographically secure pseudo-random number generator.

The same function (random.choice()) used to generate password recovery token:
/opt/canonical/landscape/canonical/lib/text.py

...
import string
import random
...
def make_secure_id(length=64):
    choices = string.digits + string.letters
    return "".join(random.choice(choices) for _ in xrange(length))
...

In theory, it is possible to collect as much data as needed to obtain the state of the Mersenne Twister matrix and, afterwards, predict the next values of the generator. A related technique is described on https://github.com/tna0y/Python-random-module-cracker. It can be used to obtain the password reset token of the admin account or try to retrieve API tokens.

To get generated password reset tokens attacker can register a new account using '/new-standalone-user' endpoint using the email address he controls (no rights needed) and then use reset password functionality on '/forgot-my-passphrase' endpoint.

Impact
Compromising admin account or obtaining secret API keys which can be used to RCE on multiple hosts registered in organisation.

Mitigation
Use os.urandom() or SystemRandom functions to generate secret tokens.

CVE References

Simon Poirier (simpoir)
Changed in landscape:
status: New → Triaged
importance: Undecided → Critical
assignee: nobody → Simon Poirier (simpoir)
Revision history for this message
Anton (ivanovant) wrote :

Hello!

Thank for the update. Will you assign CVE for this bug?

Simon Poirier (simpoir)
Changed in landscape:
status: Triaged → In Progress
Simon Poirier (simpoir)
Changed in landscape:
status: In Progress → Fix Committed
milestone: none → 19.10.5
Simon Poirier (simpoir)
Changed in landscape:
status: Fix Committed → Fix Released
Anton (ivanovant)
information type: Private Security → Public
Alex Murray (alexmurray)
information type: Public → Public Security
Revision history for this message
Mark Esler (eslerm) wrote :

Thank you for reporting this vulnerability Anton.

Please refer to this vulnerability as CVE-2023-32549.

To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.