OliveTin is a self-hosted web UI for exposing predefined shell commands to end users. This repository contains a proof-of-concept demonstrating two independent OS command injection vectors in OliveTin's Shell mode execution path, both of which bypass the application's intended shell-argument safety checks.
| CVE ID | CVE-2026-27626 |
| Component | OliveTin |
| Vulnerability Class | CWE-78: Improper Neutralization of Special Elements used in an OS Command |
| CVSS 3.1 | 9.9–10.0 (Critical) — AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H |
| Affected Versions | All versions ≤ 3000.10.0 (commits prior to 0.0.0-20260222101908-4bbd2eab1532) |
| Fixed Version | 0.0.0-20260222101908-4bbd2eab1532 or later |
| Advisory | GHSA-49gm-hh7w-wfvf |
| Disclosed | 2026-02-22 (advisory), 2026-02-25 (NVD) |
OliveTin is a self-hosted web UI for exposing predefined shell commands to end users. This repository contains a proof-of-concept demonstrating two independent OS command injection vectors in OliveTin's Shell mode execution path, both of which bypass the application's intended shell-argument safety checks.
OliveTin lets an admin define Actions — shell commands with parameterized arguments — that authenticated (or, depending on config, anonymous) users can trigger from a web UI or via webhooks. To prevent users from breaking out of the intended command via argument values, OliveTin runs every user-supplied argument through checkShellArgumentSafety() before templating it into a command string and handing it to sh -c.
This is the security boundary the vulnerability breaks. OliveTin explicitly distinguishes "admin defines the command" from "user supplies the value" — the safety check exists specifically so a user can't turn an argument value into a way to run arbitrary commands.
password argument type is uncheckedcheckShellArgumentSafety() only sanitizes a fixed allow-list of argument types:
func checkShellArgumentSafety(argType string, value string) bool {
dangerousTypes := []string{"string", "int", "bool", "choice"}
for _, dt := range dangerousTypes {
if argType == dt {
return sanitizeInput(value)
}
}
// BUG: "password" type not checked
return true // Assumes safe
}
password is a documented, intended argument type for accepting sensitive user input — but it isn't in dangerousTypes, so it falls through to return true unsanitized. Any user able to populate a password-typed argument on a Shell-mode Action can inject shell metacharacters (;, |, `, $(), etc.) that execute arbitrary commands as the OliveTin process user.
Exploitability here is amplified by OliveTin's defaults: self-registration is enabled and authType: none out of the box, so in many real deployments "authenticated user" requires no real barrier at all.
Independent of Vector 1, OliveTin's webhook handler extracts arbitrary key/value pairs from an inbound webhook's JSON body and injects them directly into ExecutionRequest.Arguments (service/internal/executor/handler.go:153-157).
Because these webhook-derived keys have no corresponding ActionArgument defined in the action's config, parseActionArguments() (arguments.go) finds no argument type to check against and skips checkShellArgumentSafety() entirely — not just for password, but for every type. The raw value is templated into the shell command and passed to sh -c with zero validation.
Since receiving inbound webhooks from external/untrusted sources is one of OliveTin's primary supported use cases, this vector requires no authentication at all.
An OliveTin instance running Shell mode with any webhook-triggered Action is vulnerable to unauthenticated remote code execution, with the privileges of the OliveTin process — potentially full host compromise depending on how OliveTin is deployed (bare metal vs. container, capabilities granted, etc.).
You are likely vulnerable if your OliveTin instance:
password-typed argument exposed to untrusted/lower-privileged users (Vector 1), orpython3 CVE-2026-27626.py -u <TARGET> [OPTIONS]
| Option | Description | Default |
|---|---|---|
-u, --url | Target host/IP | Required |
-p, --port | OliveTin port | 1337 |
-x, --cmd | Command to execute | id |
0.0.0-20260222101908-4bbd2eab1532 or later as soon as it's available in your update channel.password-typed arguments on any Action reachable by untrusted users.authType other than none).| Date | Event |
|---|---|
| 2026-02-20 | CVE reserved |
| 2026-02-22 | GitHub Security Advisory published |
| 2026-02-25 | NVD publication |
| 2026-02-27 | Advisory updated |
This PoC is published for defensive research, detection-engineering, and authorized penetration testing purposes only. Do not run it against systems you do not own or do not have explicit written authorization to test. Misuse of this code against third-party systems may violate computer crime laws (e.g., CFAA in the US, Computer Misuse Act in the UK, and equivalent statutes elsewhere) and is solely the responsibility of the person executing it.
Md Saikat (0xh7ml)