diff --git a/data/model/repository.py b/data/model/repository.py index 2e3e2118d..fd050304a 100644 --- a/data/model/repository.py +++ b/data/model/repository.py @@ -126,7 +126,13 @@ class _RepositoryExistsException(Exception): def create_repository( - namespace, name, creating_user, visibility="private", repo_kind="image", description=None + namespace, + name, + creating_user, + visibility="private", + repo_kind="image", + description=None, + proxy_cache=False, ): namespace_user = User.get(username=namespace) yesterday = datetime.now() - timedelta(days=1) @@ -154,7 +160,8 @@ def create_repository( # Note: We put the admin create permission under the transaction to ensure it is created. if creating_user and not creating_user.organization: - admin = Role.get(name="admin") + rolename = "admin" if proxy_cache == False else "read" + admin = Role.get(name=rolename) RepositoryPermission.create(user=creating_user, repository=repo, role=admin) except _RepositoryExistsException as ree: try: diff --git a/data/model/test/test_repository.py b/data/model/test/test_repository.py index 96a681c17..2ad1ec857 100644 --- a/data/model/test/test_repository.py +++ b/data/model/test/test_repository.py @@ -3,6 +3,11 @@ from datetime import timedelta import pytest +from auth.permissions import ( + AdministerRepositoryPermission, + ModifyRepositoryPermission, + ReadRepositoryPermission, +) from data.database import BlobUpload, QuotaRepositorySize, Repository from data.model.repository import ( create_repository, @@ -105,3 +110,27 @@ def test_get_repository_sizes(initialized_db): repo2.id: 92, repo3.id: 0, } + + +@pytest.fixture() +def test_create_repository_proxy_cache(initialized_db): + # with CVE-2025-4374 we want to ensure that repositories in PROXY_CACHE are not assigned to "admin" + repo1 = create_repository( + "devtable", + "somenewrepo", + None, + repo_kind="image", + visibility="public", + proxy_cache=True, + ) + # we should not have modify or admin permissions on the repo if created with proxy_cache=True + if all( + [ + ReadRepositoryPermission("devtable", "somenewrepo").can(), + not ModifyRepositoryPermission("devtable", "somenewrepo").can(), + not AdministerRepositoryPermission("devtable", "somenewrepo").can(), + ] + ): + assert True + else: + assert False diff --git a/data/registry_model/registry_proxy_model.py b/data/registry_model/registry_proxy_model.py index 0a0e00557..160904e64 100644 --- a/data/registry_model/registry_proxy_model.py +++ b/data/registry_model/registry_proxy_model.py @@ -127,7 +127,9 @@ class ProxyModel(OCIModel): visibility = "private" if app.config.get("CREATE_PRIVATE_REPO_ON_PUSH", True) else "public" - repo = create_repository(namespace_name, repo_name, self._user, visibility=visibility) + repo = create_repository( + namespace_name, repo_name, self._user, visibility=visibility, proxy_cache=True + ) return RepositoryReference.for_repo_obj( repo, namespace_name,