CVE-2026-23515 is a critical-severity (CVSS 9.9) OS Command Injection vulnerability in @signalk/set-system-time. A fix is available for @signalk/set-system-time — see the affected versions and patch details below.
RCE - Command Injection in Signal K set-system-time plugin
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
- A successful exploit gives an attacker total control of the affected component, not partial access.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-23515.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
How urgent is this, really
CVE-2026-23515 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.
Where this sits among everything scored
Of 379,145 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.
Real-World Exposure
How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.
@signalk/set-system-timenpmDescription
Summary
A Command Injection vulnerability allows authenticated users with write permissions to execute arbitrary shell commands on the Signal K server when the set-system-time plugin is enabled. Unauthenticated users can also exploit this vulnerability if security is disabled on the Signal K server. This occurs due to unsafe construction of shell commands when processing navigation.datetime values received via WebSocket delta messages.
Details
Product: Signal K set-system-time plugin
Repository: https://github.com/SignalK/set-system-time
File: index.js, lines 60-71
stream.onValue(function (datetime) {
var child
if (process.platform == 'win32') {
console.error("Set-system-time supports only linux-like os's")
} else {
if( ! plugin.useNetworkTime(options) ){
const useSudo = typeof options.sudo === 'undefined' || options.sudo
const setDate = `date --iso-8601 -u -s "${datetime}"` // ← VULNERABLE
const command = useSudo
? `if sudo -n date &> /dev/null ; then sudo ${setDate} ; else exit 3 ; fi`
: setDate
child = require('child_process').spawn('sh', ['-c', command]) // ← EXECUTES SHELL
The vulnerability has three components:
- Unsanitized Input: The
datetimevalue fromnavigation.datetimeSignal K path is directly interpolated into a shell command without validation - Shell Execution: The command is executed via
spawn('sh', ['-c', command]), which interprets shell metacharacters - Sudo Privileges: The plugin can execute with root privileges if
sudois misconfigured, instructions to limit passwordless sudo to the /bin/date binary helps mitigate this but RCE can still be achieved with the privileges of the user that installed it.
PoC
Exploitation Requirements
- Signal K server with security enabled, if disabled credentials not required
- Valid user credentials with
readwriteoradminpermissions - set-system-time plugin installed and enabled
- Signal K server installed on a Linux OS
- Passwordless sudo configured, official instructions will do this for the
datecommand which is enough to satisfy the if condition
"""
Run provided POC:
python3 poc.py --host signalkserver_IP -u username -p password
Payload: Creates /tmp/signalk-RCE.txt to prove code execution
"""
Impact
An attacker that has write privileges either through security on the Signal K server being disabled or valid credentials with read/write permissions can execute arbitrary commands on the server with the privileges of the SignalK process or root if sudo is misconfigured. This enables complete system compromise.
Recommendations
-
Replace shell-based execution with child_process.execFile() so user-controlled input is passed as arguments rather than interpreted by a shell.
-
Validate that navigation.datetime conforms to an expected ISO-8601 format to improve robustness.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 📦npm | @signalk/set-system-time | all versions | 1.5.0npm install @signalk/set-system-time@1.5.0 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for @signalk/set-system-time, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update @signalk/set-system-time to 1.5.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-23515 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2026-23515 can be triaged on real exposure rather than presence alone.
Tailored to CVE-2026-23515. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is CVE-2026-23515 in your dependencies?
O3 Security finds CVE-2026-23515 across npm dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.