From 929174c06c9595afcc30c54a818fa27ec2a23566 Mon Sep 17 00:00:00 2001 From: Jussi Kukkonen Date: Sun, 11 Feb 2024 13:03:11 +0200 Subject: [PATCH 1/4] tests: Add test for Targets.get_delegated_role() This test currently fails for SuccinctRoles. Signed-off-by: Jussi Kukkonen --- tests/test_api.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index 517ff5bdf8..5850f27eea 100755 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1008,6 +1008,33 @@ def test_get_roles_in_succinct_roles(self) -> None: expected_bin_suffix = f"{bin_numer:0{expected_suffix_length}x}" self.assertEqual(role_name, f"bin-{expected_bin_suffix}") + def test_delegations_get_delegated_role(self) -> None: + delegations = Delegations({}, {}) + targets = Targets(delegations=delegations) + + with self.assertRaises(ValueError): + targets.get_delegated_role("abc") + + # test "normal" delegated role (path or path_hash_prefix) + role = DelegatedRole("delegated", [], 1, False, []) + delegations.roles = {"delegated": role} + with self.assertRaises(ValueError): + targets.get_delegated_role("not-delegated") + self.assertEqual(targets.get_delegated_role("delegated"), role) + delegations.roles = None + + # test succinct delegation + bit_len = 3 + role2 = SuccinctRoles([], 1, bit_len, "prefix") + delegations.succinct_roles = role2 + for name in ["prefix-", "prefix--1", f"prefix-{2**bit_len:0x}"]: + with self.assertRaises(ValueError, msg=f"role name '{name}'"): + targets.get_delegated_role(name) + for i in range(0, 2**bit_len): + self.assertEqual( + targets.get_delegated_role(f"prefix-{i:0x}"), role2 + ) + # Run unit test. if __name__ == "__main__": From 77cb66bc879d108c449ba4c46dfb0e3a9e57a785 Mon Sep 17 00:00:00 2001 From: Jussi Kukkonen Date: Sun, 11 Feb 2024 11:59:04 +0200 Subject: [PATCH 2/4] Metadata API: Fix role lookup for succinct delegation get_delegated_role() should not return a Role if the rolename is not a delegated role. This is already true for "normal" DelegatedRole but was not actually verified for SuccinctRoles. Signed-off-by: Jussi Kukkonen --- tuf/api/metadata.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tuf/api/metadata.py b/tuf/api/metadata.py index 205678a3d1..7af43d05e8 100644 --- a/tuf/api/metadata.py +++ b/tuf/api/metadata.py @@ -2044,10 +2044,13 @@ def get_delegated_role(self, delegated_role: str) -> Role: if self.delegations is None: raise ValueError("No delegations found") + role: Optional[Role] = None if self.delegations.roles is not None: - role: Optional[Role] = self.delegations.roles.get(delegated_role) - else: - role = self.delegations.succinct_roles + role = self.delegations.roles.get(delegated_role) + elif self.delegations.succinct_roles is not None: + succinct = self.delegations.succinct_roles + if succinct.is_delegated_role(delegated_role): + role = succinct if not role: raise ValueError(f"Delegated role {delegated_role} not found") From fd438c86fcf55823ac02ca66c91dd3a23d315229 Mon Sep 17 00:00:00 2001 From: Jussi Kukkonen Date: Fri, 3 Nov 2023 12:00:25 +0200 Subject: [PATCH 3/4] CI: Run lint on oldest supported Python version * This was suggested as best practice by a pylint developer * Seems better than CI randomly breaking when GitHub updates Python version (and pylint starts applying new rules that we can't follow because that would break old Python versions) Signed-off-by: Jussi Kukkonen --- .github/workflows/_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/_test.yml b/.github/workflows/_test.yml index 128fb8ad94..f34f347d55 100644 --- a/.github/workflows/_test.yml +++ b/.github/workflows/_test.yml @@ -14,10 +14,10 @@ jobs: - name: Checkout TUF uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 - - name: Set up Python 3.x + - name: Set up Python (oldest supported version) uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1 with: - python-version: 3.x + python-version: 3.8 cache: 'pip' cache-dependency-path: 'requirements/*.txt' From b59bf13a7e69e140712516d2cbdbd9dfe825254f Mon Sep 17 00:00:00 2001 From: Jussi Kukkonen Date: Fri, 16 Feb 2024 09:34:01 +0200 Subject: [PATCH 4/4] Release 3.1.1 Signed-off-by: Jussi Kukkonen --- docs/CHANGELOG.md | 10 ++++++++++ tuf/__init__.py | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index dbeadb6256..5545ce4db4 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## v3.1.1 + +This is a security fix release to address advisory +GHSA-77hh-43cm-v8j6. The issue does **not** affect tuf.ngclient +users, but could affect tuf.api.metadata users. + +### Changed +* Added additional input validation to + `tuf.api.metadata.Targets.get_delegated_role()` + ## v3.1.0 ### Added diff --git a/tuf/__init__.py b/tuf/__init__.py index 36723485d3..56299e374f 100755 --- a/tuf/__init__.py +++ b/tuf/__init__.py @@ -5,4 +5,4 @@ """ # This value is used in the requests user agent. -__version__ = "3.1.0" +__version__ = "3.1.1"