{"id":"GHSA-prj9-97mp-mwh2","revision":null,"records":[{"revision":"cbf5ea18bbaa4eac9808e60b8106535f","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-53541","aliases":[],"title":"OliveTin has Unvalidated `ot_`-prefixed Arguments that Bypass Input Filtering","description":"OliveTin gives access to predefined shell commands from a web interface. The `filterToDefinedArgumentsOnly` function in the executor is intended to discard any arguments not explicitly defined in the action's configuration. However, prior to commit ebffd9f040f791208aee1db2e5a8aecd1e3e603d, a special case allows any argument whose name starts with `ot_` to bypass this filter. While two system arguments (`ot_executionTrackingId` and `ot_username`) are injected by OliveTin and overridden, all other `ot_`-prefixed arguments supplied by the user pass through unmodified. These bypassed arguments are not type-checked — the validation loop only iterates over the action's defined arguments, so `ot_`-prefixed arguments skip all type safety checks entirely; set as environment variables — via `buildEnv()`, with completely unvalidated values, and passed to the executed command; and included in the template context — available as `.Arguments.ot_*` in template rendering. Commit ebffd9f040f791208aee1db2e5a8aecd1e3e603d contains a patch.","state":0,"publishedAt":"2026-08-21T22:51:52.752+00:00","modifiedAt":"2026-08-24T20:03:47.277+00:00","affected":[{"ecosystem":"Vendor product","name":"OliveTin","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"OliveTin\",\n                    \"product\": \"OliveTin\",\n                    \"versions\": [\n                        {\n                            \"version\": \"<= 2025.03.07\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N","score":4.3,"severity":"MEDIUM"}],"references":["https://github.com/OliveTin/OliveTin/security/advisories/GHSA-prj9-97mp-mwh2","https://github.com/OliveTin/OliveTin/commit/ebffd9f040f791208aee1db2e5a8aecd1e3e603d"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-53541","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-53541","identifiers":["CVE-2026-53541"]},"retained":false,"historicalAffected":[]},{"revision":"954ff55090bc4b21b6b6aef12ad1ab5b","observedAt":"2026-11-09T12:12:05.154+00:00","statement":{"source":"euvd","id":"EUVD-2026-64203","aliases":["CVE-2026-53541","GHSA-prj9-97mp-mwh2"],"title":"OliveTin gives access to predefined shell commands from a web interface. The `filterToDefinedArgumentsOnly` function in the executor is intended to discard any arguments not explicitly defined in the action's configuration. However, prior t…","description":"OliveTin gives access to predefined shell commands from a web interface. The `filterToDefinedArgumentsOnly` function in the executor is intended to discard any arguments not explicitly defined in the action's configuration. However, prior to commit ebffd9f040f791208aee1db2e5a8aecd1e3e603d, a special case allows any argument whose name starts with `ot_` to bypass this filter. While two system arguments (`ot_executionTrackingId` and `ot_username`) are injected by OliveTin and overridden, all other `ot_`-prefixed arguments supplied by the user pass through unmodified. These bypassed arguments are not type-checked — the validation loop only iterates over the action's defined arguments, so `ot_`-prefixed arguments skip all type safety checks entirely; set as environment variables — via `buildEnv()`, with completely unvalidated values, and passed to the executed command; and included in the template context — available as `.Arguments.ot_*` in template rendering. Commit ebffd9f040f791208aee1db2e5a8aecd1e3e603d contains a patch.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N","score":4.3,"severity":null}],"references":["https://github.com/OliveTin/OliveTin/security/advisories/GHSA-prj9-97mp-mwh2","https://github.com/OliveTin/OliveTin/commit/ebffd9f040f791208aee1db2e5a8aecd1e3e603d"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-64203","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Aug 21, 2026, 10:51:52 PM","dateUpdated":"Aug 24, 2026, 8:03:47 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-64203","identifiers":["EUVD-2026-64203","CVE-2026-53541","GHSA-prj9-97mp-mwh2"]},"retained":false,"historicalAffected":[]},{"revision":"adbc6c182dc945e6ba480c67c0cafb16","observedAt":"2026-10-25T13:17:16.273+00:00","statement":{"source":"nvd","id":"CVE-2026-53541","aliases":[],"title":"OliveTin gives access to predefined shell commands from a web interface. The `filterToDefinedArgumentsOnly` function in the executor is intended to discard any arguments not explicitly defined in the action's configuration. However, prior t…","description":"OliveTin gives access to predefined shell commands from a web interface. The `filterToDefinedArgumentsOnly` function in the executor is intended to discard any arguments not explicitly defined in the action's configuration. However, prior to commit ebffd9f040f791208aee1db2e5a8aecd1e3e603d, a special case allows any argument whose name starts with `ot_` to bypass this filter. While two system arguments (`ot_executionTrackingId` and `ot_username`) are injected by OliveTin and overridden, all other `ot_`-prefixed arguments supplied by the user pass through unmodified. These bypassed arguments are not type-checked — the validation loop only iterates over the action's defined arguments, so `ot_`-prefixed arguments skip all type safety checks entirely; set as environment variables — via `buildEnv()`, with completely unvalidated values, and passed to the executed command; and included in the template context — available as `.Arguments.ot_*` in template rendering. Commit ebffd9f040f791208aee1db2e5a8aecd1e3e603d contains a patch.","state":0,"publishedAt":"2026-08-21T23:16:26.5+00:00","modifiedAt":"2026-10-14T19:10:00.297+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N","score":4.3,"severity":"MEDIUM"}],"references":["https://github.com/OliveTin/OliveTin/commit/ebffd9f040f791208aee1db2e5a8aecd1e3e603d","https://github.com/OliveTin/OliveTin/security/advisories/GHSA-prj9-97mp-mwh2"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-53541","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-20"],"productCriteria":[],"sourceDates":{"published":"2026-08-21T23:16:26.500","lastModified":"2026-10-14T19:10:00.297"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-53541","identifiers":["CVE-2026-53541"]},"retained":false,"historicalAffected":[]},{"revision":"5d5fcf5d11ad4a6c9b53858e30f47f0e","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-prj9-97mp-mwh2","aliases":["CVE-2026-53541","GO-2026-5552"],"title":"OliveTin has Unvalidated `ot_`-prefixed Arguments that Bypass Input Filtering","description":"### Description\n\nThe `filterToDefinedArgumentsOnly` function in the executor is intended to discard any arguments not explicitly defined in the action's configuration. However, a special case allows any argument whose name starts with `ot_` to bypass this filter. While two system arguments (`ot_executionTrackingId` and `ot_username`) are injected by OliveTin and overridden, all other `ot_`-prefixed arguments supplied by the user pass through unmodified.\n\nThese bypassed arguments are:\n\n1. **Not type-checked** — the validation loop only iterates over the action's defined arguments, so `ot_`-prefixed arguments skip all type safety checks entirely.\n2. **Set as environment variables** — via `buildEnv()`, with completely unvalidated values, and passed to the executed command.\n3. **Included in the template context** — available as `.Arguments.ot_*` in template rendering.\n\n### Affected Code\n\n**Filter bypass — `service/internal/executor/executor.go` (lines 728–731):**\n\n```go\nfunc keepArgument(name string, definedNames map[string]struct{}) bool {\n    _, ok := definedNames[name]\n    return ok || strings.HasPrefix(name, \"ot_\")\n}\n```\n\n**System args only override two keys — `service/internal/executor/executor.go` (lines 742–745):**\n\n```go\nfunc injectSystemArgs(req *ExecutionRequest) {\n    req.Arguments[\"ot_executionTrackingId\"] = req.TrackingID\n    req.Arguments[\"ot_username\"] = req.AuthenticatedUser.Username\n}\n```\n\nAny other `ot_`-prefixed argument (e.g., `ot_malicious`) survives both functions.\n\n**Unvalidated values become environment variables — `service/internal/executor/executor.go` (lines 867–882):**\n\n```go\nfunc buildEnv(args map[string]string) []string {\n    ret := append(os.Environ(), \"OLIVETIN=1\")\n    for k, v := range args {\n        varName := fmt.Sprintf(\"%v\", strings.TrimSpace(strings.ToUpper(k)))\n        if varName == \"\" { continue }\n        ret = append(ret, fmt.Sprintf(\"%v=%v\", varName, v))\n    }\n    return ret\n}\n```\n\nThe value `v` is never validated. It can contain newlines, shell metacharacters, null bytes, or any arbitrary data.\n\n### Proof of Concept\n\nAn attacker sends a `StartAction` request with extra `ot_`-prefixed arguments:\n\n```json\n{\n  \"bindingId\": \"<any-action-id>\",\n  \"arguments\": [\n    { \"name\": \"ot_custom_var\", \"value\": \"arbitrary unvalidated content \\n with newlines\" },\n    { \"name\": \"ot_another\",    \"value\": \"$(whoami)\" }\n  ]\n}\n```\n\nThese arguments:\n\n- Pass through `filterToDefinedArgumentsOnly` (the `ot_` prefix exempts them).\n- Are never type-checked (not in the action's argument definitions).\n- Become environment variables `OT_CUSTOM_VAR` and `OT_ANOTHER` in the executed command's environment.\n- Are available in the template rendering context as `.Arguments.ot_custom_var` and `.Arguments.ot_another`.\n\n### Impact\n\n- **Environment variable pollution** — attacker can set arbitrary environment variables (with `OT_` uppercased prefix) in the execution environment of any action they can trigger. Scripts or programs that read custom environment variables could be influenced.\n- **Potential for secondary exploitation** — if any executed script or command reads `OT_`-prefixed environment variables, the unvalidated content could cause unexpected behavior.\n- **Template context pollution** — although Go's `text/template` does not recursively evaluate data values (mitigating direct template injection), the extra arguments are accessible in the template context and could interact unexpectedly with custom template logic.\n\n### Suggested Fix\n\nRemove the `ot_` prefix exception from `keepArgument`, or restrict it to only the two known system arguments:\n\n```go\nvar systemArgs = map[string]struct{}{\n    \"ot_executionTrackingId\": {},\n    \"ot_username\":            {},\n}\n\nfunc keepArgument(name string, definedNames map[string]struct{}) bool {\n    _, isDefined := definedNames[name]\n    _, isSystem := systemArgs[name]\n    return isDefined || isSystem\n}\n```\n\n---\n\n## Discovery Methodology\n\nBoth vulnerabilities were identified through manual source code review of the OliveTin repository, focusing on:\n\n- Input validation boundaries (API request fields flowing into file system operations and execution contexts)\n- Argument filtering and type-checking logic in the executor\n- File path construction in the log persistence feature\n\nNo automated scanners or fuzzing tools were used. The review was conducted against the current `main` branch source code.\n\n---","state":0,"publishedAt":"2026-06-24T17:43:50+00:00","modifiedAt":"2026-06-25T23:11:17.5759846+00:00","affected":[{"ecosystem":"Go","name":"github.com/OliveTin/OliveTin","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"0.0.0-20260531214440-ebffd9f040f7"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"MODERATE"}],"references":["https://github.com/OliveTin/OliveTin/security/advisories/GHSA-prj9-97mp-mwh2","https://github.com/OliveTin/OliveTin/commit/ebffd9f040f791208aee1db2e5a8aecd1e3e603d","https://github.com/OliveTin/OliveTin"],"sourceUrl":"https://github.com/advisories/GHSA-prj9-97mp-mwh2","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-prj9-97mp-mwh2","identifiers":["GHSA-prj9-97mp-mwh2","CVE-2026-53541","GO-2026-5552"]},"retained":false,"historicalAffected":[]},{"revision":"f2fd8ea22f0048478b992e7c3893e526","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-5552","aliases":["CVE-2026-53541","GHSA-prj9-97mp-mwh2"],"title":"OliveTin has Unvalidated `ot_`-prefixed Arguments that Bypass Input Filtering in github.com/OliveTin/OliveTin","description":"OliveTin has Unvalidated `ot_`-prefixed Arguments that Bypass Input Filtering in github.com/OliveTin/OliveTin","state":0,"publishedAt":"2026-06-25T22:34:34+00:00","modifiedAt":"2026-06-25T23:01:30.5311903+00:00","affected":[{"ecosystem":"Go","name":"github.com/OliveTin/OliveTin","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"0.0.0-20260531214440-ebffd9f040f7"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/OliveTin/OliveTin/security/advisories/GHSA-prj9-97mp-mwh2","https://github.com/OliveTin/OliveTin/commit/ebffd9f040f791208aee1db2e5a8aecd1e3e603d"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-5552","license":"OSV · upstream source license applies","key":"osv:GO-2026-5552","identifiers":["GO-2026-5552","CVE-2026-53541","GHSA-prj9-97mp-mwh2"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-10T00:04:20.9434546+00:00","complete":true,"records":1773,"lastAttemptAt":"2026-11-10T00:04:20.9434546+00:00","lastSuccessAt":"2026-11-10T00:04:21.6223341+00:00","error":null,"lastVerifiedAt":"2026-11-10T00:04:21.622335+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-24e6fde7b744113daefb8f6135035fb8a5c69c9617c9c0d40574a0376532ffd3-28cfe0e9a7fd540693c3c003e82e8794f6d50787cb7c9866f49d79161db1199f","complete":true,"records":421738,"lastAttemptAt":"2026-11-10T00:02:15.9105874+00:00","lastSuccessAt":"2026-11-10T00:02:15.7728836+00:00","error":null,"lastVerifiedAt":"2026-11-10T00:02:15.9105874+00:00","snapshotPublishedAt":"2026-11-09T23:23:26+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-712f6c1278224b899f49f24ee1b071dc","complete":false,"records":13689,"lastAttemptAt":"2026-11-10T00:17:10.7338694+00:00","lastSuccessAt":"2026-11-10T00:17:10.73+00:00","error":"42 identifier lookups failed; latest failures include HTTP 403. Other identifiers were checked independently.","lastVerifiedAt":"2026-11-10T00:17:10.73+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13662,"expectedIdentifiers":13742,"failedIdentifiers":42},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-10T00:04:20.9434546+00:00","complete":true,"records":1096,"lastAttemptAt":"2026-11-10T00:04:20.9434546+00:00","lastSuccessAt":"2026-11-10T00:04:21.6231234+00:00","error":null,"lastVerifiedAt":"2026-11-10T00:04:21.6231235+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-46931e0d84a04da7b4a608d083ac3d63","complete":false,"records":13695,"lastAttemptAt":"2026-11-10T00:04:49.7283608+00:00","lastSuccessAt":"2026-11-10T00:04:49.725+00:00","error":null,"lastVerifiedAt":"2026-11-10T00:04:49.725+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13704,"expectedIdentifiers":13742,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-cdffb4589856378aa42e8d1bd4a6c74e27a180d8160bf764c44715ef760f0a62","complete":true,"records":9932,"lastAttemptAt":"2026-11-10T00:04:20.2100924+00:00","lastSuccessAt":"2026-11-10T00:04:19.8260565+00:00","error":null,"lastVerifiedAt":"2026-11-10T00:04:20.2100924+00:00","snapshotPublishedAt":"2026-11-09T23:48:01+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-26503967ae4379db8f374089589d6e03fb15bd31f820c9e992aaf93840c2236c","complete":true,"records":1971,"lastAttemptAt":"2026-11-10T00:02:15.9827084+00:00","lastSuccessAt":"2026-11-09T21:02:20.472473+00:00","error":null,"lastVerifiedAt":"2026-11-10T00:02:15.9827084+00:00","snapshotPublishedAt":"2026-11-09T20:18:18+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-761ecc9061239b0da572dc9254c6f384c1d19339eb08408c436647a2f26129e9","complete":true,"records":3064,"lastAttemptAt":"2026-11-10T00:04:20.8155249+00:00","lastSuccessAt":"2026-11-09T17:05:03.4044794+00:00","error":null,"lastVerifiedAt":"2026-11-10T00:04:20.8155249+00:00","snapshotPublishedAt":"2026-11-09T16:33:20+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-0238b66eb8569b8ca6bfb00e5ba7ca79562b7b754d90d8771d19caf3b72b4f1c","complete":true,"records":231580,"lastAttemptAt":"2026-11-10T00:04:10.424408+00:00","lastSuccessAt":"2026-11-10T00:04:09.9885069+00:00","error":null,"lastVerifiedAt":"2026-11-10T00:04:10.424408+00:00","snapshotPublishedAt":"2026-11-09T23:48:05+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}