PluginMenuItem and PluginMenuButton Share Mutable State Between Instances #11565

Open
opened 2025-12-29 21:46:50 +01:00 by adam · 0 comments
Owner

Originally created by @jnovinger on GitHub (Sep 3, 2025).

Deployment Type

Self-hosted

NetBox Version

v4.4.0

Python Version

3.10

Steps to Reproduce

  1. Create two PluginMenuItem instances without explicit permissions parameter
  2. Modify the permissions of the first instance
  3. Check the permissions of the second instance
from unittest import TestCase
from netbox.plugins.navigation import PluginMenuItem

class TestPluginNavigationBug(TestCase):
    def test_shared_mutable_state_bug(self):
        """
        Test that PluginMenuItem instances share mutable class attributes,
        causing permission leakage between instances.
        """
        # Clean slate
        PluginMenuItem.permissions.clear()

        # Create instance without explicit permissions (uses class default)
        item1 = PluginMenuItem(link='test1', link_text='Test 1')

        # Modify permissions through this instance
        item1.permissions.append('leaked_permission')

        # Create second instance - should have clean permissions but doesn't
        item2 = PluginMenuItem(link='test2', link_text='Test 2')

        # SECURITY ASSERTIONS: These fail when vulnerability exists
        self.assertIsNot(item1.permissions, item2.permissions,
                        "VULNERABILITY: Instances share same permission object")

        # Clean up
        PluginMenuItem.permissions.clear()

Note: While not demonstrated, PluginMenuButton has the same behavior and also needs to be fixed.

Expected Behavior

Each PluginMenuItem instance should have its own independent permissions list. When item1.permissions is modified, item2.permissions should remain empty ([]).

Observed Behavior

Both PluginMenuItem instances share the same permissions list object. Modifying permissions on one instance affects all other instances that don't have explicit permissions parameters.

Originally created by @jnovinger on GitHub (Sep 3, 2025). ### Deployment Type Self-hosted ### NetBox Version v4.4.0 ### Python Version 3.10 ### Steps to Reproduce 1. Create two PluginMenuItem instances without explicit permissions parameter 2. Modify the permissions of the first instance 3. Check the permissions of the second instance ```python from unittest import TestCase from netbox.plugins.navigation import PluginMenuItem class TestPluginNavigationBug(TestCase): def test_shared_mutable_state_bug(self): """ Test that PluginMenuItem instances share mutable class attributes, causing permission leakage between instances. """ # Clean slate PluginMenuItem.permissions.clear() # Create instance without explicit permissions (uses class default) item1 = PluginMenuItem(link='test1', link_text='Test 1') # Modify permissions through this instance item1.permissions.append('leaked_permission') # Create second instance - should have clean permissions but doesn't item2 = PluginMenuItem(link='test2', link_text='Test 2') # SECURITY ASSERTIONS: These fail when vulnerability exists self.assertIsNot(item1.permissions, item2.permissions, "VULNERABILITY: Instances share same permission object") # Clean up PluginMenuItem.permissions.clear() ``` **Note:** While not demonstrated, `PluginMenuButton` has the same behavior and also needs to be fixed. ### Expected Behavior Each `PluginMenuItem` instance should have its own independent permissions list. When `item1.permissions` is modified, `item2.permissions` should remain empty (`[]`). ### Observed Behavior Both `PluginMenuItem` instances share the same permissions list object. Modifying permissions on one instance affects all other instances that don't have explicit permissions parameters.
adam added the type: bugstatus: needs ownernetboxseverity: low labels 2025-12-29 21:46:50 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#11565