NVD has published CVE-2026-107780, a CVSS 9.8 (CRITICAL) OS command injection vulnerability affecting Dromara Skyeye, the open-source intelligent operations/asset management platform, through commit 003549ae5615bd114ba5bb8ddf6a8e8ead97c321. The flaw lives in the unauthenticated /post/TtsController/textToSpeech endpoint, where the format parameter is concatenated directly into a PowerShell command string. An attacker who injects a single quote (') into format breaks out of the PowerShell string context and executes arbitrary operating system commands as the Skyeye service account on the underlying Windows host.
Let's be precise about scope, because the early headlines are sloppy: this is not a vulnerability in Microsoft Windows itself. Windows is the exploitation surface because Skyeye invokes PowerShell to perform text-to-speech rendering. Any organization self-hosting Dromara Skyeye on Windows — common in dev/test environments, small-ops tooling stacks, and increasingly in production IT asset/deploy management roles — is exposed to remote, unauthenticated, network-level command execution. That is the worst-case combination: no credentials required, direct shell access, and a service account that frequently runs with elevated local privileges.
If Skyeye is reachable from the internet or from a broad internal segment, treat this as an emergency change. If it's reachable at all, treat it as urgent.
Technical Analysis
Affected Component
- Product: Dromara Skyeye (open-source Java-based operations/asset management suite)
- Affected versions: All builds through commit
003549ae5615bd114ba5bb8ddf6a8e8ead97c321 - Vulnerable endpoint:
/post/TtsController/textToSpeech - Vulnerable parameter:
format - Authentication required: None
- Underlying OS at risk: Windows (PowerShell invoked by the TTS module)
- CVSS v3.1: 9.8 — Network / Low complexity / No privileges / No user interaction
How the Vulnerability Works
The textToSpeech handler takes user-controlled input from the format parameter and embeds it, without sanitization or proper quoting, into a PowerShell command line that the application executes server-side to invoke the Windows Speech API. Because the value is dropped inside a single-quoted PowerShell string, an attacker-supplied format value containing a single quote terminates the intended string literal. Anything after the quote is interpreted as live PowerShell — additional statements separated by ;, subexpressions $(), or pipeline segments.
The exploitation chain from a defender's perspective looks like this:
- Reconnaissance — attacker identifies an exposed Skyeye instance (favicon, login page, or the predictable
/post/...controller paths). - Delivery — a single crafted HTTP POST to
/post/TtsController/textToSpeechwith a maliciousformatvalue (e.g.wav'; <payload>; echo '). - Execution — the Skyeye application shell invokes PowerShell; the injected payload runs with the privileges of the Skyeye service account.
- Post-exploitation — typical follow-on behavior: child processes spawned from
powershell.exe(whoami, net, curl/certutil for payload retrieval), webshell or persistence deployment, and lateral movement if the service account has domain context.
Because execution rides on the application's own PowerShell invocation, there is no anomalous authentication event, no exploit crash artifact, and frequently no web-server error — the POST may return HTTP 200 with a syntactically plausible response even when the injected command ran.
Exploitation Status
The vulnerability is documented in NVD with a full technical description and a reproducible injection primitive (single-quote breakout), which puts working exploit construction within reach of any competent attacker. At the time of writing, CVE-2026-107780 has not been added to the CISA Known Exploited Vulnerabilities catalog, but unauthenticated RCE in internet-facing management tooling historically moves from disclosure to scanning within days. Given the trivial injection mechanism — one character to escape the string — assume weaponization and act accordingly.
Detection & Response
Detection should focus on the two most reliable observables: HTTP requests to the vulnerable endpoint and PowerShell child processes spawned by the Skyeye/Java application process. The second is higher fidelity — Skyeye legitimately calling PowerShell for TTS should be rare in most environments, and PowerShell spawning further children from that lineage is almost never legitimate.
---
title: Dromara Skyeye TTS Command Injection - PowerShell Child Process
id: 3f8a1c92-7d4e-4b5a-9c21-8e6f2a4b7d10
status: experimental
description: Detects PowerShell spawned by Java application processes consistent with exploitation of CVE-2026-107780 in Dromara Skyeye's textToSpeech endpoint, or Skyeye-invoked PowerShell spawning further command interpreters or LOLBins.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-107780
- https://attack.mitre.org/techniques/T1059/001/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.execution
- attack.t1059.001
- attack.t1190
logsource:
category: process_creation
product: windows
detection:
selection_parent_java:
ParentImage|endswith:
- '\java.exe'
- '\javaw.exe'
Image|endswith:
- '\powershell.exe'
- '\pwsh.exe'
- '\cmd.exe'
selection_suspicious_cl:
CommandLine|contains:
- 'textToSpeech'
- 'Add-Type'
- 'SpeechSynthesizer'
condition: selection_parent_java or selection_suspicious_cl
falsepositives:
- Legitimate Skyeye TTS functionality invoking PowerShell for speech synthesis (rare in production; baseline and tune)
level: high
---
title: Suspicious Child Process of PowerShell Launched by Web Application
id: 9c2e5b17-4a6d-4f83-b1e4-5d7a9c0e2f38
status: experimental
description: Detects reconnaissance, download, and execution tools spawned from PowerShell whose lineage traces to a server-side application, consistent with post-exploitation after CVE-2026-107780 command injection.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-107780
- https://attack.mitre.org/techniques/T1105/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.discovery
- attack.t1033
- attack.t1105
- attack.command_and_control
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\powershell.exe'
- '\pwsh.exe'
selection_children:
Image|endswith:
- '\whoami.exe'
- '\net.exe'
- '\net1.exe'
- '\nltest.exe'
- '\ipconfig.exe'
- '\systeminfo.exe'
- '\curl.exe'
- '\certutil.exe'
- '\bitsadmin.exe'
- '\mshta.exe'
- '\rundll32.exe'
- '\regsvr32.exe'
- '\wmic.exe'
- '\quser.exe'
- '\tasklist.exe'
condition: all of selection_*
falsepositives:
- Administrative scripts run interactively via PowerShell; correlate with parent lineage to java.exe/web processes before escalating
level: medium
---
title: HTTP Request to Vulnerable Skyeye textToSpeech Endpoint
id: 5d1a8e64-2b9c-4e71-a3f6-1b8c4d9e5a72
status: experimental
description: Detects web requests targeting the unauthenticated Dromara Skyeye TTS endpoint, particularly POSTs containing quote characters in parameters indicative of CVE-2026-107780 injection attempts. Deploy against web server, reverse proxy, or WAF logs.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-107780
- https://attack.mitre.org/techniques/T1190/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.initial_access
- attack.t1190
logsource:
category: webserver
detection:
selection_uri:
cs-uri|contains:
- '/post/TtsController/textToSpeech'
selection_injection:
cs-method: 'POST'
condition: selection_uri and selection_injection
falsepositives:
- Legitimate TTS feature usage; all hits warrant review given unauthenticated reachability of this endpoint
level: high
// Hunt for CVE-2026-107780 exploitation: PowerShell spawned by Java app processes
// and suspicious follow-on command execution on hosts running Dromara Skyeye
let Lookback = 7d;
let SuspiciousChildren = dynamic(["whoami.exe","net.exe","net1.exe","nltest.exe","curl.exe","certutil.exe","bitsadmin.exe","mshta.exe","rundll32.exe","regsvr32.exe","wmic.exe","ipconfig.exe","systeminfo.exe","quser.exe"]);
DeviceProcessEvents
| where Timestamp > ago(Lookback)
| where InitiatingProcessFileName in~ ("java.exe","javaw.exe")
and FileName in~ ("powershell.exe","pwsh.exe","cmd.exe")
| project PS_Timestamp = Timestamp, DeviceName, DeviceId,
PS_ProcessId = ProcessId, PS_CommandLine = ProcessCommandLine,
JavaCommandLine = InitiatingProcessCommandLine,
AccountName, ReportId
| join kind=leftouter (
DeviceProcessEvents
| where Timestamp > ago(Lookback)
| where FileName in~ (SuspiciousChildren)
| project ChildTimestamp = Timestamp, DeviceId,
InitiatingProcessId, ChildProcess = FileName,
ChildCommandLine = ProcessCommandLine
) on $left.PS_ProcessId == $right.InitiatingProcessId and $left.DeviceId == $right.DeviceId
| extend ChildProcess = coalesce(ChildProcess, "")
| project PS_Timestamp, DeviceName, AccountName, PS_CommandLine, ChildProcess, ChildCommandLine, JavaCommandLine
| order by PS_Timestamp desc
// Hunt for web requests to the vulnerable endpoint via proxy/firewall logs in Sentinel
let Lookback = 14d;
CommonSecurityLog
| where TimeGenerated > ago(Lookback)
| where RequestURL contains "/post/TtsController/textToSpeech"
or RequestContext contains "/post/TtsController/textToSpeech"
| extend InjectionIndicator = iff(RequestURL has "'%22" or RequestURL has "%27" or RequestURL has "'", "Possible quote injection", "Clean")
| project TimeGenerated, SourceIP, DestinationIP, RequestMethod, RequestURL, InjectionIndicator, DeviceAction
| order by TimeGenerated desc
-- Hunt for PowerShell/cmd processes spawned by Java on Windows hosts
-- (Dromara Skyeye CVE-2026-107780 post-exploitation artifact)
SELECT Pid, Ppid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE CommandLine =~ 'powershell|pwsh|cmd\.exe'
OR Name =~ 'powershell|pwsh'
-- Correlate: find PowerShell processes whose parent is java.exe/javaw.exe
LET procs = SELECT Pid, Ppid, Name, CommandLine, Username, CreateTime FROM pslist()
SELECT child.Pid AS PID,
child.Name AS ProcessName,
child.CommandLine AS CommandLine,
child.Username AS RunAs,
parent.Name AS ParentName,
parent.CommandLine AS ParentCommandLine,
child.CreateTime AS Started
FROM procs AS child
JOIN procs AS parent ON child.Ppid = parent.Pid
WHERE child.Name =~ '(?i)powershell|pwsh|cmd'
AND parent.Name =~ '(?i)java'
Triage Guidance
If any of the above fire:
- Isolate the host immediately. An injected command runs as the Skyeye service account — assume full compromise of that identity, including any cached credentials and network shares it can reach.
- Capture memory and the Skyeye application logs before remediation. The Java process command line, HTTP access logs for
/post/TtsController/*, and PowerShell operational logs (Event ID 4104 if script block logging is enabled) are your primary forensic sources. - Hunt laterally. Pull the service account's logon sessions across the environment and review any authentication from the Skyeye host to other systems in the exposure window.
Remediation
Immediate containment (today):
- Block the endpoint at the edge. If you cannot patch immediately, deny unauthenticated access to
/post/TtsController/textToSpeechat your reverse proxy, WAF, or load balancer. Better: restrict the entire Skyeye application to authenticated administrative networks. - Take Skyeye off the internet. Management/ops tooling of this class should never be internet-facing. Place it behind VPN or zero-trust access with strong authentication.
- Constrain the service account. If Skyeye runs as
LocalSystemor a privileged account, drop it to a least-privilege dedicated service account with no interactive logon rights and no domain privileges.
Patch and upgrade:
- Update Dromara Skyeye to a build after commit
003549ae5615bd114ba5bb8ddf6a8e8ead97c321containing the fix. Track the upstream repository (gitee.com/dromara/skyeye / github.com/dromara) and the NVD entry at https://nvd.nist.gov/vuln/detail/CVE-2026-107780 for the patched release reference. If the TTS module is not required, disable or remove theTtsControllerfunctionality entirely until a fixed build is deployed.
Hardening script — verify exposure and constrain the service account:
# CVE-2026-107780 exposure check and hardening for Windows hosts running Dromara Skyeye
# Run elevated on suspected hosts.
# 1. Identify Java processes that may be hosting Skyeye
Write-Host "[*] Java processes running on this host:" -ForegroundColor Cyan
Get-CimInstance Win32_Process -Filter "Name='java.exe' OR Name='javaw.exe'" |
Select-Object ProcessId, CommandLine |
Format-List
# 2. Check for Skyeye-related listeners (default ports vary; review all Java-owned sockets)
Write-Host "[*] Listening sockets owned by Java processes:" -ForegroundColor Cyan
$javaPids = (Get-CimInstance Win32_Process -Filter "Name='java.exe' OR Name='javaw.exe'").ProcessId
foreach ($pid_ in $javaPids) {
Get-NetTCPConnection -State Listen -OwningProcess $pid_ -ErrorAction SilentlyContinue |
Select-Object LocalAddress, LocalPort, OwningProcess
}
# 3. Search web/access logs for exploitation attempts against the TTS endpoint
$logPaths = @("C:\skyeye\logs", "C:\Program Files\skyeye\logs", "D:\skyeye\logs")
foreach ($path in $logPaths) {
if (Test-Path $path) {
Write-Host "[*] Searching $path for textToSpeech requests..." -ForegroundColor Cyan
Get-ChildItem $path -Recurse -Include *.log -ErrorAction SilentlyContinue |
Select-String -Pattern "textToSpeech" -SimpleMatch |
Select-Object -First 50 Path, LineNumber, Line
}
}
# 4. Audit: PowerShell spawned by Java in the last 14 days (requires process creation auditing / Sysmon)
Write-Host "[*] Checking for PowerShell child processes of Java (Sysmon EID 1)..." -ForegroundColor Cyan
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -MaxEvents 5000 -ErrorAction SilentlyContinue |
Where-Object { $_.Id -eq 1 -and $_.Message -match 'ParentImage.*java(w)?\.exe' -and $_.Message -match 'Image.*(powershell|pwsh|cmd)\.exe' } |
Select-Object TimeCreated, Message -First 20
# 5. Enable PowerShell Script Block Logging for post-exploitation visibility
$sbPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"
if (-not (Test-Path $sbPath)) { New-Item -Path $sbPath -Force | Out-Null }
Set-ItemProperty -Path $sbPath -Name "EnableScriptBlockLogging" -Value 1
Write-Host "[+] Script Block Logging enabled." -ForegroundColor Green
# 6. If Skyeye runs as LocalSystem, create/verify a least-privilege service account
$svc = Get-CimInstance Win32_Service | Where-Object { $_.PathName -match 'skyeye|java' -and $_.StartName -match 'LocalSystem' }
if ($svc) {
Write-Host "[!] WARNING: Service(s) running as LocalSystem — reconfigure to a least-privilege account:" -ForegroundColor Red
$svc | Select-Object Name, StartName, PathName | Format-List
}
# 7. Block outbound egress from the host to limit payload retrieval (example: deny all except update/mgmt)
# Review before applying — tailor to your environment
# New-NetFirewallRule -DisplayName "Skyeye - Deny Outbound" -Direction Outbound -Program "C:\path\to\java.exe" -Action Block
Longer-term:
- Inventory every self-hosted Java application platform in your environment — Dromara projects are widely cloned and embedded, so Skyeye code may exist inside derivative internal tools. Software composition analysis (SCA) against your internal builds will surface it.
- Enforce WAF virtual patching for the endpoint pattern
/post/TtsController/*until all instances are confirmed remediated. - Add this endpoint to your attack surface monitoring; unauthenticated controller paths on ops tooling are exactly what external scanners find first.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.