PATCH on an object blocked by object-based write permissions returns 404 instead of 403, despite the user having read permissions for that object #10420

Closed
opened 2025-12-29 21:31:14 +01:00 by adam · 6 comments
Owner

Originally created by @mimukr on GitHub (Oct 29, 2024).

Deployment Type

Self-hosted

Triage priority

N/A

NetBox Version

v4.1.5

Python Version

3.12

Steps to Reproduce

If a user has:

  • Read permissions for an object
  • Write permissions for the object type, but not that specific object due to constraints

Then a 404 status code is returned, even though a 403 would be more appropriate as the user does have permission to know that the object exists.

E.g. the combination of the two following permissions:

{
    "name": "All Devices Read",
    "enabled": true,
    "object_types": [
        "dcim.device"
    ],
    "actions": [
        "view"
    ],
    "constraints": null,
    "users": [
        {
            "id": 1,
            "username": "foo"
        }
    ]
    ...
}
{
    "name": "Some Devices Write",
    "enabled": true,
    "object_types": [
        "dcim.device"
    ],
    "actions": [
        "view",
        "add",
        "change",
        "delete"
    ],
    "constraints": {
        "name": "editable-device"
    },
    "users": [
        {
            "id": 1,
            "username": "foo"
        }
    ]
    ...
}

PATCH https://demo.netbox.dev/api/dcim/devices/1 will then return a 404 if the device does not match the given write constraint, despite the device existing and the user having read permission to know this.

Expected Behavior

In the abovementioned case, a 403 should be returned.

Observed Behavior

A 404 was returned.

Originally created by @mimukr on GitHub (Oct 29, 2024). ### Deployment Type Self-hosted ### Triage priority N/A ### NetBox Version v4.1.5 ### Python Version 3.12 ### Steps to Reproduce If a user has: * _Read_ permissions for an object * _Write_ permissions for the object type, but not that _specific_ object due to constraints Then a 404 status code is returned, even though a 403 would be more appropriate as the user does have permission to know that the object exists. E.g. the combination of the two following permissions: ```javascript { "name": "All Devices Read", "enabled": true, "object_types": [ "dcim.device" ], "actions": [ "view" ], "constraints": null, "users": [ { "id": 1, "username": "foo" } ] ... } ``` ```javascript { "name": "Some Devices Write", "enabled": true, "object_types": [ "dcim.device" ], "actions": [ "view", "add", "change", "delete" ], "constraints": { "name": "editable-device" }, "users": [ { "id": 1, "username": "foo" } ] ... } ``` PATCH `https://demo.netbox.dev/api/dcim/devices/1` will then return a 404 if the device does not match the given write constraint, despite the device existing and the user having read permission to know this. ### Expected Behavior In the abovementioned case, a 403 should be returned. ### Observed Behavior A 404 was returned.
adam added the type: bugstatus: needs ownerpending closurenetboxseverity: low labels 2025-12-29 21:31:14 +01:00
adam closed this issue 2025-12-29 21:31:15 +01:00
Author
Owner

@arthanson commented on GitHub (Oct 30, 2024):

@mimukr can you please provide what specific permissions you are setting in order to reproduce the issue, for example:

  1. create device with name=xxx
  2. create user A
  3. assign user A permissions YYY on object xxx
    ...
    It saves us a lot of time when trying to replicate the issue as there may be some small thing in the reproduction that is different if we don't have the exact steps.
@arthanson commented on GitHub (Oct 30, 2024): @mimukr can you please provide what specific permissions you are setting in order to reproduce the issue, for example: 1. create device with name=xxx 2. create user A 3. assign user A permissions YYY on object xxx ... It saves us a lot of time when trying to replicate the issue as there may be some small thing in the reproduction that is different if we don't have the exact steps.
Author
Owner

@mimukr commented on GitHub (Oct 30, 2024):

Definitely. Here's a more step-by-step version.

First, using an admin account:

  1. Create a simple user. Here's the POST body I used:
{
   "username":"foo",
   "password":"Password1234"
}
  1. Create a permission to view all devices without constraints, and assign it to the user. Here's the POST body I used:
{
   "name":"All Devices Read",
   "object_types":[
      "dcim.device"
   ],
   "actions":[
      "view"
   ],
   "constraints":null,
   "users":[
      <ID of user from step 1>
   ]
}
  1. Create a permission to change devices named "editable-device", and assign it to the user. Here's the POST body I used:
{
   "name":"Some Devices Write",
   "object_types":[
      "dcim.device"
   ],
   "actions":[
      "view",
      "add",
      "change",
      "delete"
   ],
   "constraints":{
      "name":"editable-device"
   },
   "users":[
      <ID of user from step 1>
   ]
}
  1. Find or create any device not named "editable-device". Here's the POST body I used:
{
   "name":"device1",
   "device_type":1,
   "role":1,
   "site":1
}

Now, login with the user created in step 1 and create an API token using the default options. Use this API token for the following request:

PATCH https://demo.netbox.dev/api/dcim/devices/<ID of device from step 4>/
{
    "description":"something"
}

This will return a 404 despite this user having view access to the device. It should instead return a 403.

@mimukr commented on GitHub (Oct 30, 2024): Definitely. Here's a more step-by-step version. **First, using an admin account:** 1. Create a simple user. Here's the POST body I used: ```javascript { "username":"foo", "password":"Password1234" } ``` 2. Create a permission to view all devices without constraints, and assign it to the user. Here's the POST body I used: ```javascript { "name":"All Devices Read", "object_types":[ "dcim.device" ], "actions":[ "view" ], "constraints":null, "users":[ <ID of user from step 1> ] } ``` 3. Create a permission to change devices named "editable-device", and assign it to the user. Here's the POST body I used: ```javascript { "name":"Some Devices Write", "object_types":[ "dcim.device" ], "actions":[ "view", "add", "change", "delete" ], "constraints":{ "name":"editable-device" }, "users":[ <ID of user from step 1> ] } ``` 4. Find or create any device _not_ named "editable-device". Here's the POST body I used: ```javascript { "name":"device1", "device_type":1, "role":1, "site":1 } ``` **Now, login with the user created in step 1 and create an API token using the default options. Use this API token for the following request:** ``` PATCH https://demo.netbox.dev/api/dcim/devices/<ID of device from step 4>/ { "description":"something" } ``` This will return a 404 despite this user having view access to the device. It should instead return a 403.
Author
Owner

@github-actions[bot] commented on GitHub (Nov 9, 2024):

This is a reminder that additional information is needed in order to further triage this issue. If the requested details are not provided, the issue will soon be closed automatically.

@github-actions[bot] commented on GitHub (Nov 9, 2024): This is a reminder that additional information is needed in order to further triage this issue. If the requested details are not provided, the issue will soon be closed automatically.
Author
Owner

@mimukr commented on GitHub (Nov 11, 2024):

This is a reminder that additional information is needed in order to further triage this issue. If the requested details are not provided, the issue will soon be closed automatically.

I believe my second comment includes all information required to replicate this. I also just replicated this on https://demo.netbox.dev using those instructions.

image

@mimukr commented on GitHub (Nov 11, 2024): > This is a reminder that additional information is needed in order to further triage this issue. If the requested details are not provided, the issue will soon be closed automatically. I believe my second comment includes all information required to replicate this. I also just replicated this on https://demo.netbox.dev using those instructions. ![image](https://github.com/user-attachments/assets/87f9e604-bd21-4bfa-b96e-f9e8fa48b093)
Author
Owner

@github-actions[bot] commented on GitHub (Apr 24, 2025):

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Do not attempt to circumvent this process by "bumping" the issue; doing so will result in its immediate closure and you may be barred from participating in any future discussions. Please see our contributing guide.

@github-actions[bot] commented on GitHub (Apr 24, 2025): This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. **Do not** attempt to circumvent this process by "bumping" the issue; doing so will result in its immediate closure and you may be barred from participating in any future discussions. Please see our [contributing guide](https://github.com/netbox-community/netbox/blob/main/CONTRIBUTING.md).
Author
Owner

@github-actions[bot] commented on GitHub (May 25, 2025):

This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the core maintainers may elect to reopen this issue at a later date if deemed necessary.

@github-actions[bot] commented on GitHub (May 25, 2025): This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the core maintainers may elect to reopen this issue at a later date if deemed necessary.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#10420