CVE-2026-73802 Elastic Security · Elastic

Detect Gitea Runner Privilege Escalation via container.options Host Namespace/Capability Injection (CVE-2026-73802) in Elastic Security

Detects exploitation of CVE-2026-73802, a CWE-269 improper privilege management flaw in gitea.com/gitea/runner (Act Runner) versions prior to 1.0.9-0.20260731160927-34bfa1915022 / v3.0.0. When privileged mode is disabled in the runner configuration, the runner still forwards attacker-controlled values from the workflow's `container.options` field (e.g. `--privileged`, `--cap-add`, `--pid=host`, `--network=host`, `--userns=host`, `--device`, volume mounts) directly to the Docker/container backend. A user who can push a workflow to a repository served by a vulnerable self-hosted runner can therefore break the intended sandbox, obtain host namespaces and elevated Linux capabilities, mount the host filesystem or Docker socket, and escalate to full host compromise (CVSS 9.9). This detection surfaces runner job containers created with host namespaces, added capabilities, privileged flags, or sensitive host mounts, and correlates them with workflow/pipeline execution context.

MITRE ATT&CK

Tactic
Privilege Escalation Execution Lateral Movement

Elastic Detection Query

Elastic Security (Elastic)
eql
process where event.type == "start" and
  (process.name in ("docker","dockerd","containerd","runc","podman") or process.command_line : ("*docker run*","*container create*","*docker create*")) and
  (process.parent.name in ("act_runner","gitea-runner") or process.command_line : ("*act_runner*","*GITEA_*")) and
  process.command_line : ("*--privileged*","*--pid=host*","*--network=host*","*--net=host*","*--userns=host*","*--ipc=host*","*--uts=host*","*--cap-add*","*CAP_SYS_ADMIN*","*--device*","*/var/run/docker.sock*","*docker.sock*")
critical severity high confidence

Elastic EQL rule matching container start events spawned by act_runner carrying dangerous container.options flags.

Data Sources

Elastic DefendAuditbeat process events

Required Tables

logs-endpoint.events.process-*auditbeat-*

False Positives & Tuning

  • Trusted internal privileged build jobs
  • DinD pipelines mounting the docker socket intentionally
  • Device passthrough for sanctioned hardware tests

Other platforms for CVE-2026-73802


Testing Methodology

Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Privileged flag injected via container.options (lab)

    Expected signal: Process-creation/Docker event for `docker run` with --privileged spawned under the testing shell (simulating act_runner parent).

  2. Test 2Host PID namespace and docker socket mount (lab)

    Expected signal: Docker container create with PidMode=host and a Bind mount of /var/run/docker.sock.

  3. Test 3Capability addition via container.options (lab)

    Expected signal: Docker container create event with CapAdd including CAP_SYS_ADMIN.


Response Playbook

Triage

  1. Identify the host running act_runner and pull the exact container create/run command line that triggered the alert; note which dangerous flags (--privileged, --pid=host, --cap-add, --device, docker.sock mount) were present.
  2. Correlate the container launch timestamp with the gitea runner job logs to identify the repository, workflow file, branch/PR, and the user who pushed the triggering commit.
  3. Confirm the runner version: check the act_runner binary (`act_runner --version`) against the fixed version 1.0.9-0.20260731160927-34bfa1915022 / v3.0.0 to determine whether the instance is vulnerable.
  4. Review the workflow YAML's `container.options` field for injected flags to confirm intentional exploitation versus a sanctioned privileged job.

Containment

  1. Immediately stop/disable the affected act_runner instance and drain its job queue to prevent further privileged container launches.
  2. Revoke or restrict the offending repository's ability to register jobs on the shared runner, and disable the triggering user's push access pending investigation.
  3. Isolate the runner host from sensitive network segments if host compromise (docker socket access or host-namespace breakout) is suspected.

Evidence Collection

  1. Capture the full container runtime args, container ID, image, and mounted volumes from Docker/containerd logs and `docker inspect` for the suspicious container.
  2. Preserve the gitea runner job logs, the workflow YAML from the repository at the triggering commit, and auditd/process-creation telemetry for the host for the relevant window.

Escalation Criteria

  • !Escalate to IR as a confirmed host compromise if the container mounted /var/run/docker.sock, mounted the host root filesystem, or ran with --privileged/--pid=host and subsequently spawned processes outside the container namespace.
  • !Escalate if the triggering commit originated from an external/untrusted contributor or an account showing other signs of compromise, indicating active adversary exploitation rather than internal misuse.

Investigation Guide

Related Techniques

Forensic Artifacts

  • >Docker/containerd container create records showing HostConfig with Privileged=true, CapAdd, PidMode=host, NetworkMode=host, or Binds including /var/run/docker.sock or /
  • >act_runner job execution logs tying the container to a specific repository, workflow, and committing user
  • >Workflow YAML in the repository git history containing the malicious `container.options` string
  • >auditd/EDR process-creation events for processes spawned inside the privileged container and any resulting host-level activity

Tuning Guidance

Baseline which repositories and runners legitimately require privileged/DinD jobs and allowlist those (runner host + repo) combinations. Focus alerting on shared runners that should enforce privileged=false and on jobs triggered by untrusted/external contributors. If a runner is intentionally privileged, exclude it but ensure it is dedicated and isolated. Reduce noise by requiring the InitiatingProcess to be act_runner/gitea-runner rather than alerting on all privileged containers host-wide.


Hunting Queries

Retro-hunt 30 days of runner-spawned container commands for any dangerous container.options flags to find prior exploitation or misconfiguration.

Hunting — KQL
kql
DeviceProcessEvents | where Timestamp > ago(30d) | where InitiatingProcessFileName in~ ("act_runner","gitea-runner") | where ProcessCommandLine has_any ("--privileged","--pid=host","--cap-add","--userns=host","docker.sock","--device") | summarize count(), make_set(ProcessCommandLine) by DeviceName, bin(Timestamp,1d)
Hunting — SPL
spl
index=* (parent_process="act_runner" OR "act_runner") ("--privileged" OR "--pid=host" OR "--cap-add" OR "--userns=host" OR "docker.sock" OR "--device") earliest=-30d | stats count values(process) by host, user

Atomic Red Team Tests

Test 1 Privileged flag injected via container.options (lab)
linux

Simulate a workflow whose container.options requests --privileged, as the runner would forward it on a vulnerable instance.

Command

bash
docker run --rm --privileged --name cve_2026_73802_test alpine sh -c 'capsh --print | head; echo PRIV_TEST'

Cleanup

bash
docker rm -f cve_2026_73802_test 2>/dev/null || true

Expected Telemetry

Process-creation/Docker event for `docker run` with --privileged spawned under the testing shell (simulating act_runner parent).

Expected Detection

Detection fires on the --privileged flag in the container run command.

Test 2 Host PID namespace and docker socket mount (lab)
linux

Simulate container.options granting host PID namespace and mounting the docker socket, enabling host breakout.

Command

bash
docker run --rm --pid=host -v /var/run/docker.sock:/var/run/docker.sock --name cve_2026_73802_pid alpine sh -c 'ls -la /var/run/docker.sock; echo PIDHOST_TEST'

Cleanup

bash
docker rm -f cve_2026_73802_pid 2>/dev/null || true

Expected Telemetry

Docker container create with PidMode=host and a Bind mount of /var/run/docker.sock.

Expected Detection

Detection fires on --pid=host and the docker.sock mount.

Test 3 Capability addition via container.options (lab)
linux

Simulate container.options adding CAP_SYS_ADMIN, which the vulnerable runner forwards despite privileged mode being disabled.

Command

bash
docker run --rm --cap-add=CAP_SYS_ADMIN --name cve_2026_73802_cap alpine sh -c 'capsh --print | grep -i sys_admin; echo CAPADD_TEST'

Cleanup

bash
docker rm -f cve_2026_73802_cap 2>/dev/null || true

Expected Telemetry

Docker container create event with CapAdd including CAP_SYS_ADMIN.

Expected Detection

Detection fires on the --cap-add / CAP_SYS_ADMIN tokens in the command line.

Related Detections