Sep 23, 2026·7 min read·18 visits
A validation discrepancy between Nautobot controllers allows authenticated low-privileged users to directly POST forged approval responses, bypass group and permission checks, and trigger the execution of privileged automated tasks.
An authorization bypass vulnerability exists in Nautobot's REST API endpoints handling approval workflows. Due to an architectural inconsistency, a standalone, generic REST API endpoint for creating approval responses was exposed without propagating the required business-logic validations. This allows low-privileged authenticated users to submit forged, self-approved votes, bypassing approval thresholds and triggering unauthorized server-side automated jobs.
Nautobot serves as an authoritative Network Source of Truth and Network Automation Platform, orchestrating complex state definitions and managing sensitive network resources. To control risk, Nautobot employs an approval workflow framework that acts as a gatekeeper for critical administrative actions and automated script executions, such as scheduled jobs. These workflows are constructed from sequential approval stages, each defined by validation rules including designated group permissions, object change privileges, and response thresholds.
The application separates the management of these workflows into distinct controllers and objects: the high-level workflow stage container and individual approval stage response records. This architectural decoupling exposed a broad attack surface, as it relied on nested business logic in specific controller pathways rather than central validation enforcement at the model level. An oversight in endpoint routing allowed the model viewset handling the individual response records to be reached directly, bypass the stage validations, and process raw database writes.
As a result, a low-privileged authenticated user holding only standard response creation permissions could interact directly with the standalone response endpoint. By sending a crafted payload, the attacker could bypass the operational constraints defined on the parent stage, such as authorized user group constraints, single-response constraints, and specific object-level editing requirements. This systemic flaw effectively undermined the entire integrity of Nautobot's automation control loop.
The vulnerability stems from an inconsistency in authorization verification between Nautobot's main stage controller and the individual stage-response endpoints. Nautobot implemented critical business validations—verifying that an approver belongs to the correct approver group, verifying that the approver possesses change permissions on the targeted object, and ensuring a one-vote-per-user limit—solely inside the custom action methods approve and deny of the ApprovalWorkflowStageViewSet controller. The generic REST API router, however, simultaneously registered a standard Django REST Framework ModelViewSet named ApprovalWorkflowStageResponseViewSet at /api/extras/approval-workflow-stage-responses/.
When clients invoked this generic ViewSet via a standard HTTP POST request, the application did not propagate or enforce the complex authorization checks written inside the custom action methods of the parent ViewSet. Instead, it executed standard model-level creation validations, which only verified basic field syntax and basic foreign key relationships. The critical business-logic constraints designed to govern approval validation and maintain procedural safety were bypassed during these direct create requests.
Compounding this issue, the ApprovalWorkflowStageResponseSerializer defined the user and state fields as writable parameters without restricting them to read-only access. Because of this mass-assignment flaw, an attacker could supply any arbitrary user identifier in the user payload parameter, effectively impersonating an administrator or an authorized approver. When the API accepted and stored these forged response objects, the state machine updated the collective approval status of the stage, initiating transitions and executing scheduled jobs automatically once the threshold was met.
To analyze the defect and verify the resolution, consider the structural changes introduced in commit 8682707d0391cbfd7694e3276127b78dc9cf29d8. The primary fix strategy was to eliminate the standalone, routable endpoints entirely and modify the deserialization rules to make the response properties read-only.
In the vulnerable application, the URL router registered the viewset directly:
# Nautobot URL Router (nautobot/extras/api/urls.py)
# BEFORE PATCH: Standalone route was exposed to clients
router.register("approval-workflow-stage-responses", views.ApprovalWorkflowStageResponseViewSet)This allowed direct HTTP requests to target response creations without checking stage rules. The patch completely excised this line from the router configuration, removing the endpoint route. Furthermore, the patch redefined the ApprovalWorkflowStageResponseSerializer to make both the user and state fields read-only:
# Nautobot Serializers (nautobot/extras/api/serializers.py)
# AFTER PATCH: Enforcing read-only state and nesting inside parent views
class ApprovalWorkflowStageResponseSerializer(ValidatedModelSerializer):
user = serializers.SerializerMethodField()
def get_user(self, obj):
# Safe nested serialization implementation
pass
class Meta:
model = ApprovalWorkflowStageResponse
fields = [
"id",
"user",
"comments",
"state",
"last_updated",
]
read_only_fields = ["user", "state"]This configuration prevents direct creation or modification of these sensitive fields through any endpoint. The parent serializer was updated to render these responses strictly as read-only nested items, fetching only relevant entries via explicit user permission restrictions using .restrict(request.user, 'view'). This architectural overhaul ensures that no variant attacks targeting the response object can succeed, making the fix complete.
Exploitation of CVE-2026-83805 requires an active, authenticated user session with basic write permissions on the response models (extras.add_approvalworkflowstageresponse). The attacker must also locate a pending approval workflow stage, which is commonly associated with restricted network orchestration tasks. Once these conditions are met, the attack proceeds by bypassing the designed user checks.
The attacker targets the standalone endpoint /api/extras/approval-workflow-stage-responses/ with an HTTP POST request. The payload specifies the target stage's UUID, an administrative user's UUID in the user field, and sets the state field to approved. The lack of server-side validation against the request's authenticated token allows the creation of this response record under the administrative user's identity.
By executing multiple requests using different spoofed administrative UUIDs, an attacker can sequentially satisfy the minimum approver threshold (min_approvers). When the final required approval is inserted, the model save event handler automatically transitions the parent ApprovalWorkflow object. This state change directly triggers the execution of the associated ScheduledJob on the system under the identity of the user who originally scheduled it, resulting in execution.
The security impact of this vulnerability is significant, particularly due to the role Nautobot plays in managing live production enterprise networks. By bypassing approval gates, a low-privileged authenticated user can force the immediate execution of restricted automation scripts. Because scheduled jobs often run with administrative network credentials, this access allows the attacker to manipulate network topologies, extract sensitive device configuration variables, or alter credentials without oversight.
From an operating system perspective, if a scheduled job is configured to perform system-level tasks or execute custom code on the underlying container, the attacker can leverage this bypass to achieve arbitrary code execution. This code execution occurs in the context of the Nautobot worker container, which may lead to lateral movement within the hosting infrastructure. The CVSS vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N reflects this scope change, indicating that a failure in the application layer directly impacts the security boundaries of downstream connected network devices.
At the time of this analysis, the vulnerability is not listed in CISA's Known Exploited Vulnerabilities catalog, and no public functional exploit or active in-the-wild campaigns have been observed. However, the technical ease of execution, requiring only a low-privileged account to issue structured REST requests, elevates the operational risk. Organizations relying heavily on Nautobot for workflow-gated network deployments face a elevated threat landscape until they deploy remediations.
The recommended and primary path of remediation is upgrading all Nautobot instances to version 3.1.8 or later. This release completely removes the vulnerable standalone endpoint and implements strict nested serialization rules to prevent unauthorized direct writes to the database.
If an immediate upgrade is not feasible, administrators should restrict the extras.add_approvalworkflowstageresponse permissions. Removing this permission from all non-administrative and low-privileged user roles prevents access to the vulnerable endpoint path. Valid users who need to approve or deny workflow stages can continue to use the secure /approve/ or /deny/ actions of the ApprovalWorkflowStageViewSet controller, which enforce appropriate group validations.
Additionally, security teams can deploy a Web Application Firewall (WAF) or API gateway rule to drop incoming HTTP requests matching the vulnerable path. Specifically, any POST, PUT, PATCH, or DELETE requests directed to /api/extras/approval-workflow-stage-responses/ should be blocked and logged for incident response. Network detection systems can monitor application logs for anomalous approval responses where the database creator does not match the designated author.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Nautobot Nautobot | >= 3.0.0, < 3.1.8 | 3.1.8 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-285 |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Score | 6.4 (Medium) |
| EPSS Score | 0.00 |
| Exploit Status | none |
| KEV Status | Not Listed |
The product does not perform or incorrectly performs an authorization check when an actor attempts to access a resource or perform an action.
CVE-2026-9639 (GHSA-j93m-3j9p-m5m8) is a null pointer dereference vulnerability in Canonical LXD affecting versions 5.0.0 through 5.21.4 and 6.0 through 6.8. The flaw resides in the (*lxdBackend).CreateCustomVolumeFromBackup method within lxd/storage/backend_lxd.go. An authenticated attacker with the can_create_storage_volumes permission can upload a crafted custom volume backup tarball that omits the expires_at field on a snapshot entry, triggering an unhandled SIGSEGV panic and terminating the LXD daemon.
An operating system command injection vulnerability (CWE-78) exists in GeoNode versions prior to 5.1.0. The vulnerability occurs in the vector upload processing pipeline when handling user-supplied geospatial files. By supplying a crafted layer name containing shell metacharacters, an authenticated attacker with basic data upload privileges can execute arbitrary commands on the underlying server or container hosting the GeoNode application and Celery worker processes.
GeoNode versions prior to 5.0.3 contain an unrestricted file upload vulnerability (CWE-434) within the document and dataset ingestion architecture. Authenticated low-privileged users can bypass upload validation via direct REST API interactions, file extension masquerading, metadata mutation via PATCH requests, or malicious archive submissions. This allows attackers to store and serve dangerous file types, alter on-disk file references, or trigger path traversal and resource exhaustion during archive extraction.
CVE-2026-55649 is a stored Cross-Site Scripting (XSS) vulnerability in GeoNode versions prior to 5.0.3. The flaw exists because document abstract metadata fields are ingested via the metadata management pipeline and stored in the backend database without HTML sanitization or input neutralization. An authenticated attacker with privileges to create or edit document metadata can inject arbitrary HTML and JavaScript payloads into these fields. When another user, such as an administrator, views the affected document page or catalog listing, the unencoded payload is rendered into the Document Object Model (DOM) and executes within the victim's browser session.
CVE-2026-55622 (GHSA-qx75-2p3r-pwm5) is an improper access control vulnerability (CWE-284) in Canonical LXD and LXC Incus (tracked as GHSA-c9f5-j9c3-mhrg). In multi-tenant deployments utilizing project-based isolation, the REST API handler for instance creation via POST /1.0/instances verifies that the authenticated user has authorization in the destination project specified by the query parameter, but fails to verify whether the user holds read or view permissions for the source instance when executing a copy operation across projects. Consequently, an authenticated client restricted to a single project can clone instances or snapshots from unauthorized projects into their own project, resulting in complete disclosure of the target instance filesystem and embedded credentials.
An authorization bypass vulnerability in Canonical LXD (tracked as GHSA-7mr3-28h5-m5vx and CVE-2026-55621, and as GHSA-64f3-v33m-w89f in Linux Containers Incus) allows an authenticated user with restricted project access to copy custom storage volumes and volume snapshots from unauthorized projects. The flaw resides in the storagePoolVolumesPost REST API handler, which verifies permissions on the destination project but fails to check whether the caller holds view entitlements on the source project or volume specified in the request body.