netbox icon indicating copy to clipboard operation
netbox copied to clipboard

`PluginMenuItem` and `PluginMenuButton` Share Mutable State Between Instances

Open jnovinger opened this issue 6 months ago • 0 comments

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.

jnovinger avatar Sep 03 '25 14:09 jnovinger