diff --git a/modules/interfaces/interfaceDbApp.py b/modules/interfaces/interfaceDbApp.py index 250b2a38..1f1d1e53 100644 --- a/modules/interfaces/interfaceDbApp.py +++ b/modules/interfaces/interfaceDbApp.py @@ -742,8 +742,16 @@ class AppObjects: logger.error(f"Unexpected error creating user: {str(e)}") raise ValueError(f"Failed to create user: {str(e)}") - def updateUser(self, userId: str, updateData: Union[Dict[str, Any], User]) -> User: - """Update a user's information""" + def updateUser(self, userId: str, updateData: Union[Dict[str, Any], User], allowSysAdminChange: bool = False) -> User: + """Update a user's information. + + Args: + userId: ID of the user to update + updateData: User data to update (dict or User model) + allowSysAdminChange: If True, allows changing isSysAdmin field. + Only set to True when called by a SysAdmin explicitly + changing another user's admin status. + """ try: # Get user user = self.getUser(userId) @@ -758,6 +766,14 @@ class AppObjects: # Remove id field from updateDict if present - we'll use userId from parameter updateDict.pop("id", None) + + # SECURITY: Protect sensitive fields from being overwritten by profile updates. + # These fields should only be changed explicitly by admins, not through + # profile forms where they might be sent as default values (e.g., isSysAdmin=False). + protectedFields = ["isSysAdmin"] + if not allowSysAdminChange: + for field in protectedFields: + updateDict.pop(field, None) # Update user data using model updatedData = user.model_dump()