CVE-2026-67439: OliveTin StartActionAndWait Endpoints Bypass `logs` Permission Vulnerability
MODERATECVE-2026-67439 is a MODERATE (CVSS 4.3) startactionandwait endpoints bypass `logs` permission vulnerability (CWE-863: Incorrect Authorization) affecting OliveTin libraries in the Go ecosystem. The issue involves startactionandwait endpoints bypass `logs` permission and return action output. Remediation is available by upgrading affected packages to version 0.0.0-20260708085316-e421780c9885.
CVE-2026-67439 at a Glance
Security Impact
CVSS: 4.3
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N).
How to Fix CVE-2026-67439
To remediate this vulnerability, upgrade all affected OliveTin dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade github.com/OliveTin/OliveTin to 0.0.0-20260708085316-e421780c9885
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for github.com/OliveTin/OliveTin
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-67439, inspect your project dependencies for OliveTin:
inspect dependencies for github.com/OliveTin/OliveTin
Analyze the terminal output to locate any version of OliveTin in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.0.0-20260708085316-e421780c9885), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-863: Incorrect Authorization, where the product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. In OliveTin, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-67439 Affected OliveTin Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
github.com/OliveTin/OliveTin
|
Go |
< 0.0.0-20260708085316-e421780c9885
|
0.0.0-20260708085316-e421780c9885
|
References
Frequently Asked Questions
What is CVE-2026-67439?
Which OliveTin versions are affected?
What version fixes CVE-2026-67439?
Is github.com/OliveTin/OliveTin affected?
What is the CVSS score of CVE-2026-67439?
What CWE is associated with CVE-2026-67439?
How can I check Go dependencies for CVE-2026-67439?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-jm28-2wcr-qf3h",
"modified" : "2026-07-30T14:25:20Z",
"published" : "2026-07-30T14:25:20Z",
"aliases" : [ "CVE-2026-67439" ],
"summary" : "OliveTin: StartActionAndWait Endpoints Bypass `logs` Permission and Return Action Output",
"details" : "## Summary\n\nThe synchronous execution RPCs `StartActionAndWait` and `StartActionByGetAndWait` return the full `LogEntry` for the just-executed action without checking whether the caller is allowed to read that action's logs.\n\nOliveTin's ACL model separates `exec` from `logs`. A deployment can intentionally allow a user to run an action while denying access to its historical or live output. That separation is enforced in `GetLogs`, `GetActionLogs`, `ExecutionStatus`, and `EventStream`, but it is not enforced in the synchronous `...AndWait` endpoints.\n\nAs a result, any user who can execute an action through these endpoints can read the action output immediately even when the action's ACL explicitly sets `logs:false`.\n\n## Details\n\nOliveTin defines separate per-action permissions:\n\n```go\n// service/internal/config/config.go\ntype PermissionsList struct {\n View bool `koanf:\"view\"`\n Exec bool `koanf:\"exec\"`\n Logs bool `koanf:\"logs\"`\n Kill bool `koanf:\"kill\"`\n}\n```\n\nThe normal log and streaming paths correctly enforce `logs` permission:\n\n```go\n// service/internal/api/api.go\nfunc (api *oliveTinAPI) isLogEntryAllowed(e *executor.InternalLogEntry, user *authpublic.AuthenticatedUser) bool {\n if user == nil || !isValidLogEntry(e) {\n return false\n }\n return acl.IsAllowedLogs(api.cfg, user, e.Binding.Action)\n}\n```\n\nThat check is used by:\n\n- `GetLogs`\n- `GetActionLogs`\n- `ExecutionStatus`\n- `EventStream`\n\nHowever, the synchronous execution endpoints directly return the created `LogEntry` without any `logs` ACL check:\n\n```go\n// service/internal/api/api.go\nfunc (api *oliveTinAPI) StartActionAndWait(ctx ctx.Context, req *connect.Request[apiv1.StartActionAndWaitRequest]) (*connect.Response[apiv1.StartActionAndWaitResponse], error) {\n ...\n internalLogEntry, ok := api.startActionAndWaitRun(binding, args, user)\n if !ok {\n return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf(\"execution not found\"))\n }\n return connect.NewResponse(&apiv1.StartActionAndWaitResponse{\n LogEntry: api.internalLogEntryToPb(internalLogEntry, user),\n }), nil\n}\n\nfunc (api *oliveTinAPI) StartActionByGetAndWait(ctx ctx.Context, req *connect.Request[apiv1.StartActionByGetAndWaitRequest]) (*connect.Response[apiv1.StartActionByGetAndWaitResponse], error) {\n ...\n internalLogEntry, ok := api.executor.GetLog(execReq.TrackingID)\n if ok {\n return connect.NewResponse(&apiv1.StartActionByGetAndWaitResponse{\n LogEntry: api.internalLogEntryToPb(internalLogEntry, user),\n }), nil\n }\n return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf(\"execution not found\"))\n}\n```\n\nAnd `internalLogEntryToPb()` includes the full output:\n\n```go\n// service/internal/api/api.go\nfunc (api *oliveTinAPI) internalLogEntryToPb(logEntry *executor.InternalLogEntry, authenticatedUser *authpublic.AuthenticatedUser) *apiv1.LogEntry {\n pble := &apiv1.LogEntry{\n ActionTitle: logEntry.ActionTitle,\n Output: logEntry.Output,\n ExitCode: logEntry.ExitCode,\n ExecutionTrackingId: logEntry.ExecutionTrackingID,\n ...\n }\n ...\n return pble\n}\n```\n\nThe executor separately enforces `exec` permission, but there is no subsequent check that the response should omit or deny `Output` when `logs:false`.\n\n## Local Reproduction\n\nI verified this locally with a one-off test against the real `StartActionAndWait` handler.\n\nConfiguration used:\n\n- action `secret_action` with shell `echo SECRET_FROM_ACTION`\n- user `low` matched by ACL:\n - `exec: true`\n - `logs: false`\n - `view: false`\n - `kill: false`\n\nThen I invoked `StartActionAndWait` as `low` through the real handler path using header-based auth.\n\nObserved output from the test run:\n\n```text\n=== RUN TestTempStartActionAndWaitLeaksOutputWithoutLogsPermission\ntime=\"2026-03-12T23:36:33+01:00\" level=info msg=\"Action requested\" actionTitle=secret-action tags=\"[]\"\ntime=\"2026-03-12T23:36:33+01:00\" level=info msg=\"Action parse args - Before\" actionTitle=secret-action cmd=\"echo SECRET_FROM_ACTION\"\ntime=\"2026-03-12T23:36:33+01:00\" level=info msg=\"Action parse args - After\" actionTitle=secret-action cmd=\"echo SECRET_FROM_ACTION\"\ntime=\"2026-03-12T23:36:33+01:00\" level=info msg=\"Action started\" actionTitle=secret-action timeout=5\ntime=\"2026-03-12T23:36:33+01:00\" level=info msg=\"Action finished\" actionTitle=secret-action exit=0 outputLength=40 timedOut=false\n temp_acl_bypass_test.go:56: output=\"S\\x00E\\x00C\\x00R\\x00E\\x00T\\x00_\\x00F\\x00R\\x00O\\x00M\\x00_\\x00A\\x00C\\x00T\\x00I\\x00O\\x00N\\x00\\r\\x00\\n\\x00\" blocked=false action=\"secret-action\"\n--- PASS: TestTempStartActionAndWaitLeaksOutputWithoutLogsPermission (0.03s)\n```\n\nThe UTF-16LE formatting is from Windows `echo`, but the key result is that the response returned the real command output even though the caller's ACL explicitly denied log access.\n\n## Impact\n\n- **Bypass of log confidentiality controls:** Operators may configure actions to be executable but not log-readable. The `...AndWait` endpoints break that separation.\n- **Disclosure of secrets printed by actions:** Many OliveTin actions wrap administrative scripts and commands whose stdout/stderr may contain credentials, internal paths, hostnames, tokens, or sensitive operational data.\n- **Adjacent to previous output-leak bugs:** OliveTin already had an EventStream output disclosure bug. This is a separate response-path authorization gap on the synchronous execution APIs.\n\n## Recommended Fix\n\nEnforce `logs` permission before returning `LogEntry` content from synchronous execution endpoints.\n\nTwo reasonable fixes:\n\n1. Deny the endpoint response when `logs:false`\n\n```go\nif !acl.IsAllowedLogs(api.cfg, user, binding.Action) {\n return nil, connect.NewError(connect.CodePermissionDenied, fmt.Errorf(\"permission denied to view action output\"))\n}\n```\n\n2. Or redact log-bearing fields when `logs:false`\n\n```go\npb := api.internalLogEntryToPb(internalLogEntry, user)\nif !acl.IsAllowedLogs(api.cfg, user, binding.Action) {\n pb.Output = \"\"\n pb.ExitCode = 0\n}\nreturn connect.NewResponse(&apiv1.StartActionAndWaitResponse{LogEntry: pb}), nil\n```\n\nThe same fix should be applied to both:\n\n- `StartActionAndWait`\n- `StartActionByGetAndWait`\n\n## References\n\n- `service/internal/api/api.go`\n- `service/internal/config/config.go`\n- `service/internal/acl/acl.go`",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Go",
"name" : "github.com/OliveTin/OliveTin"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "0.0.0-20260708085316-e421780c9885"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/OliveTin/OliveTin/security/advisories/GHSA-jm28-2wcr-qf3h"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-67439"
}, {
"type" : "WEB",
"url" : "https://github.com/OliveTin/OliveTin/commit/e421780c9885aa5024d2f47b4ed4898f2f18eb90"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/OliveTin/OliveTin"
}, {
"type" : "WEB",
"url" : "https://github.com/OliveTin/OliveTin/releases/tag/3000.17.0"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-863" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-07-30T14:25:20Z",
"nvd_published_at" : "2026-07-29T21:17:48Z"
}
}