CVE-2026-67439

mediumpriority · track · 0OT risk · elevatedEPSS 0.004 · 37 %ileEUUS
grimoire priorityP3 · Track
Exploitable?
—
no known exploitation
Likely / severe?
0.43% (37th) EPSS
CVSS 4.3 · medium
Is it mine?
2 products
Check your exposure
Who says so?
3 sources
cnnvd · enisa_euvd · osv

EPSS · scored 2026-10-27

OliveTin gives safe and simple access to predefined shell commands from a web interface. Prior to 3000.17.0, the service/internal/api/api.go StartActionAndWait and StartActionByGetAndWait endpoints return full LogEntry output after execution without enforcing the logs permission, allowing a user with exec permission but logs:false to read action output. This issue is fixed in version 3000.17.0.

01

cvss

Technical severity, 0–10. One row per scoring source.

4.3
010

base score 0–10 · higher = more severe · hover a vector to decode

v3.14.3mediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:Nsecondary · ENISA EU
v3.14.3mediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:Nsecondary · security-advisories@github.comexploitability 2.8 · impact 1.4
v3.14.3mediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:Nsecondary · OSV
v3.14mediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N/E:Usecondary · CVSS-BT (t0sche)
02

ssvc

A stakeholder decision — act, attend, or track — from exploitation and impact.

Exploitation: poc · Automatable: no · Technical Impact: partialcoordinatorcisa_ssvcUS
03

weaknesses

The CWE weakness classes this flaw belongs to.

04

affected products (2)

Products and version ranges known to be affected.

05

advisories (2)

Vendor and ecosystem advisories describing this.

  • GHSA-jm28-2wcr-qf3hOliveTin: StartActionAndWait Endpoints Bypass `logs` Permission and Return Action Output2026-07-30ghsa · osvUS

    ## Summary The 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. OliveTin'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. As 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`. ## Details OliveTin defines separate per-action permissions: ```go // service/internal/config/config.go type PermissionsList struct { View bool `koanf:"view"` Exec bool `koanf:"exec"` Logs bool `koanf:"logs"` Kill bool `koanf:"kill"` } ``` The normal log and streaming paths correctly enforce `logs` permission: ```go // service/internal/api/api.go func (api *oliveTinAPI) isLogEntryAllowed(e *executor.InternalLogEntry, user *authpublic.AuthenticatedUser) bool { if user == nil || !isValidLogEntry(e) { return false } return acl.IsAllowedLogs(api.cfg, user, e.Binding.Action) } ``` That check is used by: - `GetLogs` - `GetActionLogs` - `ExecutionStatus` - `EventStream` However, the synchronous execution endpoints directly return the created `LogEntry` without any `logs` ACL check: ```go // service/internal/api/api.go func (api *oliveTinAPI) StartActionAndWait(ctx ctx.Context, req *connect.Request[apiv1.StartActionAndWaitRequest]) (*connect.Response[apiv1.StartActionAndWaitResponse], error) { ... internalLogEntry, ok := api.startActionAndWaitRun(binding, args, user) if !ok { return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("execution not found")) } return connect.NewResponse(&apiv1.StartActionAndWaitResponse{ LogEntry: api.internalLogEntryToPb(internalLogEntry, user), }), nil } func (api *oliveTinAPI) StartActionByGetAndWait(ctx ctx.Context, req *connect.Request[apiv1.StartActionByGetAndWaitRequest]) (*connect.Response[apiv1.StartActionByGetAndWaitResponse], error) { ... internalLogEntry, ok := api.executor.GetLog(execReq.TrackingID) if ok { return connect.NewResponse(&apiv1.StartActionByGetAndWaitResponse{ LogEntry: api.internalLogEntryToPb(internalLogEntry, user), }), nil } return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("execution not found")) } ``` And `internalLogEntryToPb()` includes the full output: ```go // service/internal/api/api.go func (api *oliveTinAPI) internalLogEntryToPb(logEntry *executor.InternalLogEntry, authenticatedUser *authpublic.AuthenticatedUser) *apiv1.LogEntry { pble := &apiv1.LogEntry{ ActionTitle: logEntry.ActionTitle, Output: logEntry.Output, ExitCode: logEntry.ExitCode, ExecutionTrackingId: logEntry.ExecutionTrackingID, ... } ... return pble } ``` The executor separately enforces `exec` permission, but there is no subsequent check that the response should omit or deny `Output` when `logs:false`. ## Local Reproduction I verified this locally with a one-off test against the real `StartActionAndWait` handler. Configuration used: - action `secret_action` with shell `echo SECRET_FROM_ACTION` - user `low` matched by ACL: - `exec: true` - `logs: false` - `view: false` - `kill: false` Then I invoked `StartActionAndWait` as `low` through the real handler path using header-based auth. Observed output from the test run: ```text === RUN TestTempStartActionAndWaitLeaksOutputWithoutLogsPermission time="2026-03-12T23:36:33+01:00" level=info msg="Action requested" actionTitle=secret-action tags="[]" time="2026-03-12T23:36:33+01:00" level=info msg="Action parse args - Before" actionTitle=secret-action cmd="echo SECRET_FROM_ACTION" time="2026-03-12T23:36:33+01:00" level=info msg="Action parse args - After" actionTitle=secret-action cmd="echo SECRET_FROM_ACTION" time="2026-03-12T23:36:33+01:00" level=info msg="Action started" actionTitle=secret-action timeout=5 time="2026-03-12T23:36:33+01:00" level=info msg="Action finished" actionTitle=secret-action exit=0 outputLength=40 timedOut=false 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" --- PASS: TestTempStartActionAndWaitLeaksOutputWithoutLogsPermission (0.03s) ``` The 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. ## Impact - **Bypass of log confidentiality controls:** Operators may configure actions to be executable but not log-readable. The `...AndWait` endpoints break that separation. - **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. - **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. ## Recommended Fix Enforce `logs` permission before returning `LogEntry` content from synchronous execution endpoints. Two reasonable fixes: 1. Deny the endpoint response when `logs:false` ```go if !acl.IsAllowedLogs(api.cfg, user, binding.Action) { return nil, connect.NewError(connect.CodePermissionDenied, fmt.Errorf("permission denied to view action output")) } ``` 2. Or redact log-bearing fields when `logs:false` ```go pb := api.internalLogEntryToPb(internalLogEntry, user) if !acl.IsAllowedLogs(api.cfg, user, binding.Action) { pb.Output = "" pb.ExitCode = 0 } return connect.NewResponse(&apiv1.StartActionAndWaitResponse{LogEntry: pb}), nil ``` The same fix should be applied to both: - `StartActionAndWait` - `StartActionByGetAndWait` ## References - `service/internal/api/api.go` - `service/internal/config/config.go` - `service/internal/acl/acl.go`

  • GO-2026-6144OliveTin: StartActionAndWait Endpoints Bypass `logs` Permission and Return Action Output in github.com/OliveTin/OliveTin2026-08-18vendor · osvUS

    OliveTin: StartActionAndWait Endpoints Bypass `logs` Permission and Return Action Output in github.com/OliveTin/OliveTin

06

also known as (5)

Other names and identifiers for this entity.

07

sources

Which sources assert this record, and when.

published 2026-07-29modified 2026-07-30
08

references (10)

External citations — patches, advisories, analysis.

scry

Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.

Free scan