VYPR
Critical severity9.8NVD Advisory· Published Nov 18, 2024· Updated Apr 15, 2026

CVE-2024-47533

CVE-2024-47533

Description

Cobbler, a Linux installation server that allows for rapid setup of network installation environments, has an improper authentication vulnerability starting in version 3.0.0 and prior to versions 3.2.3 and 3.3.7. utils.get_shared_secret() always returns -1, which allows anyone to connect to cobbler XML-RPC as user '' password -1 and make any changes. This gives anyone with network access to a cobbler server full control of the server. Versions 3.2.3 and 3.3.7 fix the issue.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
cobblerPyPI
>= 3.3.0, < 3.3.73.3.7
cobblerPyPI
>= 3.0.0, < 3.2.33.2.3

Patches

4
e19717623c10

Merge commit from fork

https://github.com/cobbler/cobblerEnno G.Nov 17, 2024via ghsa
5 files changed · +67 9
  • cobbler/cobblerd.py+2 2 modified
    @@ -46,8 +46,8 @@ def regen_ss_file() -> None:
         ssfile = "/var/lib/cobbler/web.ss"
         data = os.urandom(512)
     
    -    with open(ssfile, "wb", 0o660) as ss_file_fd:
    -        ss_file_fd.write(binascii.hexlify(data))
    +    with open(ssfile, "w", 0o660, encoding="UTF-8") as ss_file_fd:
    +        ss_file_fd.write(str(binascii.hexlify(data)))
     
         http_user = "apache"
         family = utils.get_family()
    
  • cobbler/remote.py+2 0 modified
    @@ -3661,6 +3661,8 @@ def login(self, login_user: str, login_password: str) -> str:
             """
             # if shared secret access is requested, don't bother hitting the auth plugin
             if login_user == "":
    +            if self.shared_secret == -1:
    +                raise ValueError("login failed(<DIRECT>)")
                 if login_password == self.shared_secret:
                     return self.__make_token("<DIRECT>")
                 raise ValueError("login failed due to missing username!")
    
  • cobbler/utils/__init__.py+2 3 modified
    @@ -1026,13 +1026,12 @@ def get_shared_secret() -> Union[str, int]:
     
         :return: The Cobbler secret which enables full access to Cobbler.
         """
    -
         try:
    -        with open("/var/lib/cobbler/web.ss", "rb", encoding="utf-8") as web_secret_fd:
    +        with open("/var/lib/cobbler/web.ss", "r", encoding="UTF-8") as web_secret_fd:
                 data = web_secret_fd.read()
         except Exception:
             return -1
    -    return str(data).strip()
    +    return data
     
     
     def local_get_cobbler_api_url() -> str:
    
  • tests/utils/utils_test.py+24 3 modified
    @@ -1,9 +1,11 @@
    +import binascii
     import datetime
     import os
     import re
     import time
     from pathlib import Path
     from threading import Thread
    +from typing import TYPE_CHECKING, Any
     
     import pytest
     from netaddr.ip import IPAddress
    @@ -13,6 +15,9 @@
     
     from tests.conftest import does_not_raise
     
    +if TYPE_CHECKING:
    +    from pytest_mock import MockerFixture
    +
     
     def test_pretty_hex():
         # Arrange
    @@ -411,15 +416,31 @@ def test_get_supported_system_boot_loaders():
         assert result == ["grub", "pxe", "ipxe"]
     
     
    -def test_get_shared_secret():
    +@pytest.mark.parametrize("web_ss_exists", [True, False])
    +def test_get_shared_secret(mocker: "MockerFixture", web_ss_exists: bool):
         # Arrange
    -    # TODO: Test the case where the file is there.
    +    open_mock = mocker.mock_open()
    +    random_data = binascii.hexlify(os.urandom(512)).decode()
    +    mock_web_ss = mocker.mock_open(read_data=random_data)
    +
    +    def mock_open(*args: Any, **kwargs: Any):
    +        if not web_ss_exists:
    +            open_mock.side_effect = FileNotFoundError
    +            return open_mock(*args, **kwargs)
    +        if args[0] == "/var/lib/cobbler/web.ss":
    +            return mock_web_ss(*args, **kwargs)
    +        return open_mock(*args, **kwargs)
    +
    +    mocker.patch("builtins.open", mock_open)
     
         # Act
         result = utils.get_shared_secret()
     
         # Assert
    -    assert result == -1
    +    if web_ss_exists:
    +        assert result == random_data
    +    else:
    +        assert result == -1
     
     
     def test_local_get_cobbler_api_url():
    
  • tests/xmlrpcapi/miscellaneous_test.py+37 1 modified
    @@ -6,12 +6,13 @@
     import os
     import pathlib
     import time
    -from typing import Any, Callable, Dict, List, Union
    +from typing import Any, Callable, Dict, List, Union, TYPE_CHECKING
     
     import pytest
     
     from cobbler.remote import CobblerXMLRPCInterface
     from cobbler.utils import get_shared_secret
    +from tests.conftest import does_not_raise
     
     
     def test_clear_system_logs(
    @@ -442,6 +443,41 @@ def test_is_autoinstall_in_use(
         assert not result
     
     
    +@pytest.mark.parametrize(
    +    "input_username,input_password,expected_result,expected_exception,web_ss_exists",
    +    [
    +        ("cobbler", "cobbler", True, does_not_raise(), True),
    +        ("cobbler", "incorrect-password", True, pytest.raises(ValueError), True),
    +        ("", "doesnt-matter", True, pytest.raises(ValueError), True),
    +        ("", "my-random-web-ss", True, does_not_raise(), True),
    +        ("", "my-random-web-ss", True, pytest.raises(ValueError), False),
    +    ],
    +)
    +def test_login(
    +    remote: CobblerXMLRPCInterface,
    +    input_username: str,
    +    input_password: str,
    +    expected_result: Any,
    +    expected_exception: Any,
    +    web_ss_exists: bool
    +):
    +    """
    +    Assert that the login is working successfully with correct and incorrect credentials.
    +    """
    +    # Arrange
    +    if web_ss_exists:
    +        remote.shared_secret = "my-random-web-ss"
    +    else:
    +        remote.shared_secret = -1
    +
    +    # Act
    +    with expected_exception:
    +        token = remote.login(input_username, input_password)
    +
    +        # Assert
    +        assert remote.token_check(token) == expected_result
    +
    +
     def test_logout(remote: CobblerXMLRPCInterface):
         """
         Assert that any action with a token is not successful after using the "logout" method to invalidate the token.
    
32c5cada013d

Use utf-8 encoding for md5 handling and web.ss data.

https://github.com/cobbler/cobblerThomas HillerJun 17, 2019via ghsa
2 files changed · +3 3
  • cobbler/modules/authn_configfile.py+1 1 modified
    @@ -37,7 +37,7 @@ def __parse_storage():
     
         if not os.path.exists("/etc/cobbler/users.digest"):
             return []
    -    fd = open("/etc/cobbler/users.digest")
    +    fd = open("/etc/cobbler/users.digest", encoding='utf-8')
         data = fd.read()
         fd.close()
         results = []
    
  • cobbler/utils.py+2 2 modified
    @@ -55,7 +55,7 @@
     
     
     def md5(key):
    -    return hashlib.md5(key)
    +    return hashlib.md5(key.encode('utf-8'))
     
     
     CHEETAH_ERROR_DISCLAIMER = """
    @@ -1836,7 +1836,7 @@ def get_shared_secret():
         """
     
         try:
    -        fd = open("/var/lib/cobbler/web.ss", 'rb')
    +        fd = open("/var/lib/cobbler/web.ss", 'rb', encoding='utf-8')
             data = fd.read()
         except:
             return -1
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.