Summary
A privilege misconfiguration in Gitea act_runner's Docker backend allows workflow-controlled container options to bypass the intended non-privileged setting.
By merging user-specified Docker options such as host PID namespaces and additional capabilities while only disabling the Privileged flag, a user who can run workflows may create containers that effectively run with host-level access and escape to the host as root.
A privilege misconfiguration in Gitea act_runner's Docker backend allows workflow-controlled container options to bypass the intended non-privileged setting.
By merging user-specified Docker options such as host PID namespaces and additional capabilities while only disabling the Privileged flag, a user who can run workflows may create containers that effectively run with host-level access and escape to the host as root.
Affected context
This vulnerability affects environments where Gitea act_runner is configured with the Docker backend (via act 0.262.0) and users are allowed to define or influence workflow container options. It is most relevant when operators assume that setting privileged: false enforces strong isolation, but still permit flags like --pid=host, --cap-add, or --security-opt to be merged into the Docker HostConfig. The risk is higher in runners that execute workflows from untrusted or semi-trusted repositories, or where runner hosts have broad system access.
This vulnerability affects environments where Gitea act_runner is configured with the Docker backend (via act 0.262.0) and users are allowed to define or influence workflow container options. It is most relevant when operators assume that setting privileged: false enforces strong isolation, but still permit flags like --pid=host, --cap-add, or --security-opt to be merged into the Docker HostConfig. The risk is higher in runners that execute workflows from untrusted or semi-trusted repositories, or where runner hosts have broad system access.
Exploit preconditions
- Attack surface: CI/CD runner using act_runner with Docker backend
- Required access: Ability to create or modify workflows that run on the affected runner
- Trigger point: Workflow execution where container.options is passed into the Docker job container's HostConfig
- Why exploitation is possible: The implementation disables only the
Privilegedflag while keeping other powerful Docker options intact, allowing job containers to gain host namespaces and broad Linux capabilities that enable escape to the host as root.
- Attack surface: CI/CD runner using act_runner with Docker backend
- Required access: Ability to create or modify workflows that run on the affected runner
- Trigger point: Workflow execution where container.options is passed into the Docker job container's HostConfig
- Why exploitation is possible: The implementation disables only the
Privilegedflag while keeping other powerful Docker options intact, allowing job containers to gain host namespaces and broad Linux capabilities that enable escape to the host as root.
Why this happens
The underlying issue is a privilege management error in how act_runner interprets and merges workflow-provided container options into Docker's HostConfig. Rather than enforcing a coherent security policy for non-privileged containers, the code selectively turns off the Privileged flag but leaves other options—such as host PID namespaces, capability additions, and security options—unchanged.
This maps to CWE-269: Privilege Management Error, where controls intended to restrict privilege are implemented incompletely. The design treats privilege as a single switch instead of validating and constraining all related options that can effectively elevate container privileges or break isolation.
The underlying issue is a privilege management error in how act_runner interprets and merges workflow-provided container options into Docker's HostConfig. Rather than enforcing a coherent security policy for non-privileged containers, the code selectively turns off the Privileged flag but leaves other options—such as host PID namespaces, capability additions, and security options—unchanged.
This maps to CWE-269: Privilege Management Error, where controls intended to restrict privilege are implemented incompletely. The design treats privilege as a single switch instead of validating and constraining all related options that can effectively elevate container privileges or break isolation.
Potential impact
- Job containers may escape to the Docker host and execute commands as root
- Full compromise of the CI runner host operating system
- Ability to read, modify, or delete data accessible on the runner host
- Lateral movement into other services or infrastructure reachable from the compromised host
- Tampering with build artifacts, secrets, and CI/CD pipelines
- Job containers may escape to the Docker host and execute commands as root
- Full compromise of the CI runner host operating system
- Ability to read, modify, or delete data accessible on the runner host
- Lateral movement into other services or infrastructure reachable from the compromised host
- Tampering with build artifacts, secrets, and CI/CD pipelines
General mitigation guidance
Effective mitigation focuses on enforcing a consistent low-privilege container policy and reducing trust in workflow-supplied options. Common defensive patterns include:
- Validating and whitelisting allowed Docker options for non-privileged containers, rejecting host namespaces, broad capability additions, and permissive security options.
- Implementing a clear separation between trusted and untrusted workflows, with untrusted workloads running in hardened, isolated runner environments.
- Applying least-privilege at the host level by limiting runner host capabilities, filesystem access, and network exposure, so that a container escape has constrained impact.
- Using secure-by-default container profiles (e.g., restrictive seccomp and capability sets) that cannot be overridden by workflow configuration.
- Treating workflow configuration as untrusted input and applying policy enforcement before constructing Docker HostConfig objects.
Effective mitigation focuses on enforcing a consistent low-privilege container policy and reducing trust in workflow-supplied options. Common defensive patterns include:
- Validating and whitelisting allowed Docker options for non-privileged containers, rejecting host namespaces, broad capability additions, and permissive security options.
- Implementing a clear separation between trusted and untrusted workflows, with untrusted workloads running in hardened, isolated runner environments.
- Applying least-privilege at the host level by limiting runner host capabilities, filesystem access, and network exposure, so that a container escape has constrained impact.
- Using secure-by-default container profiles (e.g., restrictive seccomp and capability sets) that cannot be overridden by workflow configuration.
- Treating workflow configuration as untrusted input and applying policy enforcement before constructing Docker HostConfig objects.
How teams detect issues like this
Organizations can detect this class of issue and its abuse through several high-level strategies:
- Static analysis or configuration linting for runner code and policies, ensuring that privilege-related options (namespaces, capabilities, security options) are consistently constrained when
privileged: falseis set. - Code review practices that flag any path where user-controlled workflow configuration is merged directly into container runtime configuration without policy enforcement.
- Monitoring runner hosts for anomalous container configurations, such as containers running with host PID/IPC/NET namespaces or unexpected capabilities, especially when marked as non-privileged.
- Log analysis and security tooling that track Docker API calls, highlighting workflows that request potentially dangerous options.
- Policy enforcement via admission controllers, security agents, or CI guardrails that prevent job containers from obtaining host-level access regardless of workflow content.
Organizations can detect this class of issue and its abuse through several high-level strategies:
- Static analysis or configuration linting for runner code and policies, ensuring that privilege-related options (namespaces, capabilities, security options) are consistently constrained when
privileged: falseis set. - Code review practices that flag any path where user-controlled workflow configuration is merged directly into container runtime configuration without policy enforcement.
- Monitoring runner hosts for anomalous container configurations, such as containers running with host PID/IPC/NET namespaces or unexpected capabilities, especially when marked as non-privileged.
- Log analysis and security tooling that track Docker API calls, highlighting workflows that request potentially dangerous options.
- Policy enforcement via admission controllers, security agents, or CI guardrails that prevent job containers from obtaining host-level access regardless of workflow content.

