Skip to content

Commit c9cd54b

Browse files
1 parent adc5641 commit c9cd54b

3 files changed

Lines changed: 193 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-8mxq-7xr7-2fxj",
4+
"modified": "2026-04-03T21:42:35Z",
5+
"published": "2026-04-03T21:42:35Z",
6+
"aliases": [
7+
"CVE-2026-34052"
8+
],
9+
"summary": "LTI JupyterHub Authenticator: Unbounded Memory Growth via Nonce Storage (Denial of Service)",
10+
"details": "## Summary\n\nThe LTI 1.1 validator stores OAuth nonces in a class-level dictionary that grows without bounds. Nonces are added before signature validation, so an attacker with knowledge of a valid consumer key can send repeated requests with unique nonces to gradually exhaust server memory, causing a denial of service.\n\n## Patches\n\n- upgrade jupyterhub-litauthenticator to 1.6.3",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "PyPI",
21+
"name": "jupyterhub-ltiauthenticator"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "1.6.3"
32+
}
33+
]
34+
}
35+
],
36+
"database_specific": {
37+
"last_known_affected_version_range": "<= 1.6.2"
38+
}
39+
}
40+
],
41+
"references": [
42+
{
43+
"type": "WEB",
44+
"url": "https://github.com/jupyterhub/ltiauthenticator/security/advisories/GHSA-8mxq-7xr7-2fxj"
45+
},
46+
{
47+
"type": "PACKAGE",
48+
"url": "https://github.com/jupyterhub/ltiauthenticator"
49+
}
50+
],
51+
"database_specific": {
52+
"cwe_ids": [
53+
"CWE-401",
54+
"CWE-770"
55+
],
56+
"severity": "MODERATE",
57+
"github_reviewed": true,
58+
"github_reviewed_at": "2026-04-03T21:42:35Z",
59+
"nvd_published_at": null
60+
}
61+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-cxj8-ggf2-p57c",
4+
"modified": "2026-04-03T21:43:22Z",
5+
"published": "2026-04-03T21:43:22Z",
6+
"aliases": [
7+
"CVE-2026-34083"
8+
],
9+
"summary": "Signal K Server: OAuth Authorization Code Theft via Unvalidated Host Header in OIDC Flow",
10+
"details": "## Summary\n\nSignalK Server contains a code-level vulnerability in its OIDC login and logout handlers where the unvalidated HTTP Host header is used to construct the OAuth2 redirect_uri. Because the redirectUri configuration is silently unset by default, an **attacker spoof the Host header** to steal OAuth authorization codes and hijack user sessions in realistic deployments as The OIDC provider will then send the authorization code to whatever domain was injected.\n\n_The OIDC specification requires redirect_uri to be pre-registered and not derived from untrusted input. Constructing it from the Host header violates this requirement and introduces a trust boundary break._\nThis risk is actively amplified by SignalK's official documentation, which instructs administrators to deploy an Nginx configuration that forwards the vulnerable Host header, exposing production environments.\n\n## Vulnerability Root Cause\n\nTwo factors combine to create this vulnerability:\n\n**Factor 1: redirectUri is optional with an unsafe fallback**\nIn types.ts:30, redirectUri is declared as optional\n```\nexport interface OIDCConfig {\n // ...\n redirectUri?: string // ← Optional, no default value\n // ...\n}\n```\n\nThe defaults in types.ts:175-185 do not include a redirectUri: never checks or warns about a missing redirectUri. This means a fully \"valid\" OIDC configuration can exist without redirectUri, silently activating the vulnerable fallback path.\n```\nexport const OIDC_DEFAULTS: Omit<OIDCConfig, 'issuer' | 'clientId' | 'clientSecret'> = {\n enabled: false,\n scope: 'openid email profile',\n defaultPermission: 'readonly',\n autoCreateUsers: true,\n providerName: 'SSO Login',\n autoLogin: false\n // ← No redirectUri default\n}\n```\n\n**Factor 2: Unsafe Host header usage in two locations**\nLocation 1 — Login handler in oidc-auth.ts:278-282:\n```\nconst protocol = req.secure ? 'https' : 'http'\nconst host = req.get('host') // ← Attacker-controlled\nconst redirectUri =\n oidcConfig.redirectUri || // ← Only safe if explicitly set\n `${protocol}://${host}${skAuthPrefix}/oidc/callback` // ← Uses attacker's Host\n\n```\nThis redirectUri flows into createAuthState() → buildAuthorizationUrl() → OIDC provider's redirect_uri parameter. The OIDC provider will then send the authorization code to whatever domain was injected.\n\nLocation 2 — Logout handler in oidc-auth.ts:513-515:\n```\nconst protocol = req.secure ? 'https' : 'http'\nconst host = req.get('host') // ← Same pattern\nconst fullPostLogoutUri = `${protocol}://${host}${postLogoutRedirect}`\n```\nThis constructs the post_logout_redirect_uri sent to the OIDC provider's end_session_endpoint, allowing an attacker to redirect the user to an attacker controlled domain after logout.\n\n### Official Documentation Enables the Attack\n\nSignalK's own security documentation at docs/security.md:222-228 provides the recommended nginx reverse proxy configuration:\nThe proxy_set_header Host $host; directive forwards the client-supplied Host header to the backend unmodified. Without this directive, nginx would replace the Host header with the upstream address (localhost:3000), which would neutralize the injection.\n```\nlocation / {\n proxy_pass http://localhost:3000;\n proxy_set_header X-Forwarded-For $remote_addr;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_set_header Host $host; # ← Forwards client's Host header to SignalK\n}\n```\nAdministrators who follow the official documentation are directly enabling this vulnerability behind their reverse proxy.\n\n## Proof of Concept \nTested against SignalK Server v2.23.0 in Docker with OIDC enabled .\n\n**Step 1 — Send login request with injected Host header:**\n`$response = Invoke-WebRequest -Uri \"http://localhost:3000/signalk/v1/auth/oidc/login\" -Headers @{\"Host\"=\"evil.com\"} -MaximumRedirection 0 -ErrorAction SilentlyContinue -UseBasicParsing`\n\n**Step 2: Decode and print the injected redirect URL**\n`[uri]::UnescapeDataString($response.Headers.Location)\n`\n<img width=\"1259\" height=\"211\" alt=\"Screenshot 2026-03-25 171251\" src=\"https://github.com/user-attachments/assets/6e4a9655-639e-48c2-a7f0-06e17ad471ff\" />\n\n## Impact\n\n* **Authorization Code Theft:** The OIDC provider sends the OAuth authorization code to the attacker's domain instead of the legitimate server.\n* **Session Hijack:** The attacker can exchange the stolen code for tokens and create a session as the victim user.\n* **Logout Redirect Hijack:** The logout handler has the same pattern, allowing post-logout redirection to an attacker domain (phishing opportunity).",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "npm",
21+
"name": "signalk-server"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "2.20.0"
29+
},
30+
{
31+
"fixed": "2.24.0"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "WEB",
41+
"url": "https://github.com/SignalK/signalk-server/security/advisories/GHSA-cxj8-ggf2-p57c"
42+
},
43+
{
44+
"type": "ADVISORY",
45+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-34083"
46+
},
47+
{
48+
"type": "PACKAGE",
49+
"url": "https://github.com/SignalK/signalk-server"
50+
},
51+
{
52+
"type": "WEB",
53+
"url": "https://github.com/SignalK/signalk-server/releases/tag/v2.24.0"
54+
}
55+
],
56+
"database_specific": {
57+
"cwe_ids": [
58+
"CWE-346",
59+
"CWE-601"
60+
],
61+
"severity": "MODERATE",
62+
"github_reviewed": true,
63+
"github_reviewed_at": "2026-04-03T21:43:22Z",
64+
"nvd_published_at": "2026-04-02T17:16:23Z"
65+
}
66+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-gfmv-vh34-h2x5",
4+
"modified": "2026-04-03T21:42:11Z",
5+
"published": "2026-04-03T21:42:11Z",
6+
"aliases": [
7+
"CVE-2026-33951"
8+
],
9+
"summary": "Signal K Server: Unauthenticated Source Priorities Manipulation ",
10+
"details": "## Summary\n\nThe SignalK Server exposes an unauthenticated HTTP endpoint that allows remote attackers to modify navigation data source priorities. This endpoint, accessible via `PUT /signalk/v1/api/sourcePriorities`, does not enforce authentication or authorization checks and directly assigns user-controlled input to the server configuration.\n\nAs a result, attackers can influence which GPS, AIS, or other sensor data sources are trusted by the system. The changes are immediately applied and persisted to disk, allowing the manipulation to survive server restarts.\n\n### Affected Component\n- **File**: `src/serverroutes.ts`\n- **Endpoint**: `PUT /signalk/v1/api/sourcePriorities` (also accessible at `/skServer/sourcePriorities`)\n- **Lines**: 1064-1076\n- **Function**: Source priorities configuration handler\n\n### Vulnerable Code\n\n```typescript\n// src/serverroutes.ts - Lines 1064-1076\napp.put(\n `${SERVERROUTESPREFIX}/sourcePriorities`,\n (req: Request, res: Response) => {\n app.config.settings.sourcePriorities = req.body\n app.activateSourcePriorities()\n writeSettingsFile(app, app.config.settings, (err: any) => {\n if (err) {\n res\n .status(500)\n .send('Unable to save to sourcePrefences in settings file')\n } else {\n res.json({ result: 'ok' })\n }\n })\n }\n)\n```\n## Vulnerability Characteristics\n\n**Missing Authentication**: The endpoint has zero authentication middleware, allowing unauthenticated access from any network-adjacent attacker.\n\n**Direct Configuration Assignment**: User-supplied request body is directly assigned to app.config.settings.sourcePriorities without validation or sanitization.\n\n**Persistent Storage**: Malicious configuration is written to disk via writeSettingsFile(), ensuring changes survive server restarts.\n**Live Configuration Update**: Changes take effect immediately via activateSourcePriorities(), affecting live navigation data processing.\n\n**No Input Validation**: No JSON schema validation, type checking, or field allowlisting is performed on the request body.\n\n## Impact\n- **Navigation Data Manipulation**: Attackers can modify source priorities to change which existing, active source's data is being used",
11+
"severity": [
12+
{
13+
"type": "CVSS_V4",
14+
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "npm",
21+
"name": "signalk-server"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "2.24.0-beta.1"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "WEB",
41+
"url": "https://github.com/SignalK/signalk-server/security/advisories/GHSA-gfmv-vh34-h2x5"
42+
},
43+
{
44+
"type": "ADVISORY",
45+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33951"
46+
},
47+
{
48+
"type": "PACKAGE",
49+
"url": "https://github.com/SignalK/signalk-server"
50+
},
51+
{
52+
"type": "WEB",
53+
"url": "https://github.com/SignalK/signalk-server/releases/tag/v2.24.0-beta.1"
54+
}
55+
],
56+
"database_specific": {
57+
"cwe_ids": [
58+
"CWE-284",
59+
"CWE-306"
60+
],
61+
"severity": "MODERATE",
62+
"github_reviewed": true,
63+
"github_reviewed_at": "2026-04-03T21:42:11Z",
64+
"nvd_published_at": "2026-04-02T17:16:23Z"
65+
}
66+
}

0 commit comments

Comments
 (0)