Live › vulnerability › GHSA-7wpf-ch8f-5f4x
signalk-server fetches the icon URL a plugin declares in its package, and accepts absolute http(s) URLs as-is and follows redirects. A malicious plugin listed in the app store can make the server request internal or cloud metadata addresses and store any image response as the plugin icon, which is then shown in the admin UI.
Summary written from the sources below. Check the originals before acting.
First seen by InfraStack 2026-10-30 23:02 UTC. All times on this page are UTC.
Servers running signalk-server in the affected range that browse the app store and so fetch plugin icons. Exposure comes from the app store fetch path, so a server with no app store use and no outbound access to the vessel network or cloud metadata is less at risk. The sources do not say whether managed or default configurations change this.
| Product | Ecosystem | Affected | Fixed in |
|---|---|---|---|
| signalk-server | npm | >= 2.28.0-beta.2, < 2.34.0 | 2.34.0 |
npm ls signalk-server or the server's package.json; affected versions are >= 2.28.0-beta.2 and < 2.34.0.signalk.appIcon values that are absolute URLs in installed plugin package.json files.signalk-server 2.34.0Each row is the first time that source carried this signal. The analyst’s rows are its own findings.
The app store icon code (dist/appstore/icon-probe.js around line 200 and icon-bytes.js around line 138) resolves a plugin's declared signalk.appIcon. Relative paths are pinned to the CDN, but an absolute http(s) URL is used as-is: the server fetches it, follows redirects, and stores any image/* response as the plugin's icon, which is then served to the admin UI. Unrelated to GHSA-q59x-jc9f-gfqf.
signalk-server 2.33.0 (latest).
The real dist modules driven directly, Docker with --network none; a local "internal" service on 127.0.0.1 logs requests:
[CONTROL relative] declared=../../icon.png
resolved=null
internal-service hits: [] stored: null
[ATTACK absolute] declared=http://127.0.0.1:35013/latest/meta-data/iam
resolved=http://127.0.0.1:35013/latest/meta-data/iam
internal-service hits: ["GET /latest/meta-data/iam"] stored: .../icon-bytes/[email protected] (70 bytes)
[ATTACK redirect] declared=http://127.0.0.1:35013/redir
internal-service hits: ["GET /redir","GET /internal-secret-via-redirect.png"] stored: .../icon-bytes/[email protected] (70 bytes)
The modules were tested directly rather than through a full running server.
Anyone who can get a plugin listed in the app store (publishing an npm package with the signalk keywords) can make every signalk-server that browses the app store send requests to internal addresses on the vessel network and to cloud metadata endpoints. Responses with an image content type are stored and served back to the user.
Only accept relative icon paths resolved against the CDN (or an https allowlist of known hosts), do not follow redirects to other hosts, and reject private, loopback and link-local addresses after resolution.
This page as .md · .json · in your agent: get_signal("GHSA-7wpf-ch8f-5f4x")
GitHub Advisory Database, CC-BY 4.0. Posts quoted belong to their authors.