VC add-member writes to devices the user has no permission to change
NetBox Edition
NetBox Community
NetBox Version
v4.7.1
Python Version
3.12
Steps to Reproduce
- Give a user view + change on VirtualChassis only — no device permissions of any kind. Confirm GET /dcim/devices//edit/ returns 403.
- Create a virtual chassis they can change, and a separate device they cannot touch.
- POST to /dcim/virtual-chassis//add-member/ with device=, vc_position, and vc_priority.
Expected Behavior
Writing to a device requires dcim.change_device on that device. Holding change_virtualchassis should not confer write access to arbitrary device rows.
Observed Behavior
The only permission check is on the virtual chassis from the URL. The device comes from the POST body and is saved with nothing checked against it.
Suspected Cause
VirtualChassisAddMemberView (netbox/dcim/views.py:5267-5320) declares queryset = VirtualChassis.objects.all() and get_required_permission() returning dcim.change_virtualchassis. ObjectPermissionRequiredMixin.has_permission() (netbox/utilities/views.py:130-138) restricts only that queryset.
The device then arrives via VCMemberSelectForm (netbox/dcim/forms/model_forms.py:1301-1308), whose field is Device.objects.all(). post() never calls restrict_form_fields(), so the queryset stays unrestricted, and membership_form.save() at line 5301 writes the device with no change_device check anywhere in between. The form's query_params={'virtual_chassis_id': 'null'} only filters the dropdown the browser renders; it doesn't constrain what the POST may name.
Proposed Fix
call restrict_form_fields(member_select_form, request.user, 'change') in post(), and re-check change_device against the selected device before saving. The get() handler should get the same treatment so the dropdown matches what will be accepted.
Source: netbox-community/netbox