Security Digest · Critical advisory (no CVE assigned)
GHSA-4xm8-rg9h-jhq2: Signal K resources API path traversal can disclose the JWT signing secret and enable remote code execution
Summary Path traversal in the Signal K resources and applicationData APIs lets an unauthenticated or low-privileged user read, write and delete files outside the storage root.
CVSS 9.8 Critical GitHub-reviewed · critical
Should you act?
- Only if you depend on one of the packages below, directly or transitively, in a vulnerable version. Check your lockfile with
npm audit (or: npm ls <package>). - No CVE has been assigned, so it will not appear in CVE-based scanners that ignore GitHub advisories.
npm audit,pip-auditand Dependabot do read GitHub advisories.
Affected packages
| Ecosystem | Package | Vulnerable | First fixed |
|---|---|---|---|
| npm | signalk-server | >= 2.0.0, < 2.34.0 | 2.34.0 |
| npm | @signalk/resources-provider | >= 1.0.0, < 1.5.3 | 1.5.3 |
Details
Summary
Path traversal in the Signal K resources and applicationData APIs lets an unauthenticated or low-privileged user read, write and delete files outside the storage root. Reading /security.json discloses the JWT signing secret, enabling admin token forgery and remote code execution.
Details
Description
The v2 REST resources API GET /signalk/v2/api/resources/:resourceType/:resourceId passes resourceId to FileStore.getResource() without validation. getResource() builds the file path with path.join(this.resources[type].path, itemUuid) followed by readFile + JSON.parse, so a %2F-encoded multi-level traversal (..%2F..%2F..%2F..%2F) escapes the resource storage directory and returns any JSON file on the server (source: src/api/resources/index.ts:559-600, packages/resources-provider-plugin/src/filestorage.ts:115-125).
Because the JWT signing secret is stored in plaintext in /security.json (generated at src/tokensecurity.ts:271, persisted via saveSecurityConfig at src/security.ts:377), an unauthenticated attacker on deployments with allowreadonly=true (a supported, UI-toggleable configuration granting anonymous read access) can:
1. Read /security.json — disclosing the JWT signing secret (512-hex) and user password hashes. 2. Forge an admin JWT — HS256-sign {"id":"admin"} with the disclosed secret; accepted by /skServer/loginStatus (userLevel: "admin") and all admin-protected endpoints (adminAuthenticationMiddleware, src/tokensecurity.ts:593, applied at src/tokensecurity.ts:953). 3. Gain remote code execution — POST /skServer/providers (admin) accepts a provider of type Execute; packages/streams/src/execute.ts:93 executes it via spawn('sh', ['-c', command]) at creation time. The provider persists to settings.json and survives restarts.
On default deployments (allowreadonly=false), step 1 returns 401 to anonymous users but succeeds with any readonly user token.
CVSS: 9.8 (v3.1) CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Sources and references
- GitHub Advisory GHSA-4xm8-rg9h-jhq2 github.com
- github.com github.com
- github.com github.com
- github.com github.com