Deleting a collaboration should also delete linked resources
Description
vantage6 is privacy preserving federated learning infrastructure. When a collaboration is deleted, the linked resources (such as tasks from that collaboration) should be deleted. This is partly to manage data properly, but also to prevent a potential (but unlikely) side-effect that affects versions prior to 4.0.0, where if a collaboration with id=10 is deleted, and subsequently a new collaboration is created with id=10, the authenticated users in that collaboration could potentially see results of the deleted collaboration in some cases. Version 4.0.0 contains a patch for this issue. There are no known workarounds.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
vantage6PyPI | < 4.0.0 | 4.0.0 |
Affected products
1Patches
1cce9538f8b70Merge pull request #748 from vantage6/feature/delete-child-resources-by-flag
4 files changed · +85 −0
vantage6-server/vantage6/server/resource/collaboration.py+24 −0 modified@@ -515,6 +515,12 @@ def delete(self, id): type: integer description: Collaboration id required: true + - in: query + name: delete_dependents + schema: + type: boolean + description: If set to true, the collaboratio will be deleted along + with all its tasks and nodes (default=False) responses: 200: @@ -540,6 +546,24 @@ def delete(self, id): return {'msg': 'You lack the permission to do that!'}, \ HTTPStatus.UNAUTHORIZED + if collaboration.tasks or collaboration.nodes: + delete_dependents = request.args.get('delete_dependents', False) + if not delete_dependents: + return { + "msg": f"Collaboration id={id} has " + f"{len(collaboration.tasks)} tasks and " + f"{len(collaboration.nodes)} nodes. Please delete them " + "separately or set delete_dependents=True" + }, HTTPStatus.BAD_REQUEST + else: + log.warn(f"Deleting collaboration id={id} along with " + f"{len(collaboration.tasks)} tasks and " + f"{len(collaboration.nodes)} nodes") + for task in collaboration.tasks: + task.delete() + for node in collaboration.nodes: + node.delete() + collaboration.delete() return {"msg": f"Collaboration id={id} successfully deleted"}, \ HTTPStatus.OK
vantage6-server/vantage6/server/resource/role.py+21 −0 modified@@ -564,6 +564,12 @@ def delete(self, id): minimum: 1 description: Role id required: true + - in: query + name: delete_dependents + schema: + type: boolean + description: If set to true, the role is deleted even though users + with this role may lose permissions (default=False) responses: 200: @@ -591,6 +597,21 @@ def delete(self, id): return {'msg': 'You can\'t delete a role from another ' 'organization'}, HTTPStatus.UNAUTHORIZED + # check if role is assigned to users + if role.users: + params = request.args + if not params.get('delete_dependents', False): + return { + 'msg': "Role is assigned to users. Please remove the role " + "from the users first, or set the 'delete_dependents' " + "parameter to delete the role anyway." + }, HTTPStatus.BAD_REQUEST + else: + log.warn(f"Role {id} deleted even though it was assigned to " + "users. This may result in missing permissions.") + # Note that the role is removed from the users automatically + # due to the relationship between the role and the user. + role.delete() return {"msg": "Role removed from the database."}, HTTPStatus.OK
vantage6-server/vantage6/server/resource/task.py+18 −0 modified@@ -735,8 +735,26 @@ def delete(self, id): log.info(f" Removing run id={run.id}") run.delete() + # delete child/grandchild/... tasks + Task._delete_subtasks(task) + # permissions ok, delete... task.delete() return {"msg": f"task id={id} and its algorithm run data have been " "successfully deleted"}, HTTPStatus.OK + + @staticmethod + def _delete_subtasks(task: db.Task) -> None: + """ + Delete subtasks recursively. + + Parameters + ---------- + task : db.Task + Task to delete. + """ + for child_task in task.children: + Task._delete_subtasks(child_task) + log.info(f" Removing child task id={child_task.id}") + child_task.delete()
vantage6-server/vantage6/server/resource/user.py+22 −0 modified@@ -702,6 +702,12 @@ def delete(self, id): type: integer description: User id required: true + - in: query + name: delete_dependents + schema: + type: boolean + description: If set to true, the user will be deleted along with + all tasks they created (default=False) responses: 200: @@ -728,6 +734,22 @@ def delete(self, id): return {'msg': 'You lack the permission to do that!'}, \ HTTPStatus.UNAUTHORIZED + # check if user created any tasks + if user.created_tasks: + params = request.args + if not params.get('delete_dependents', False): + return { + "msg": f"User has created {len(user.created_tasks)} tasks." + " Please delete those first, or set the " + "`delete_dependents` parameter to true to delete them " + "automatically together with this user." + }, HTTPStatus.BAD_REQUEST + else: + log.warn(f"Deleting {len(user.created_tasks)} tasks created by" + f" user id={id}") + for task in user.created_tasks: + task.delete() + user.delete() log.info(f"user id={id} is removed from the database") return {"msg": f"user id={id} is removed from the database"}, \
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
7- github.com/advisories/GHSA-rf54-7qrr-96j6ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-41881ghsaADVISORY
- github.com/pypa/advisory-database/tree/main/vulns/vantage6/PYSEC-2023-200.yamlghsaWEB
- github.com/vantage6/vantage6/blob/0682c4288f43fee5bcc72dc448cdd99bd7e57f76/docs/release_notes.rstghsax_refsource_MISCWEB
- github.com/vantage6/vantage6/commit/cce9538f8b70e814c080dd0ae43b297f3af8a732ghsaWEB
- github.com/vantage6/vantage6/pull/748ghsax_refsource_MISCWEB
- github.com/vantage6/vantage6/security/advisories/GHSA-rf54-7qrr-96j6ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.