From 6471aa815d0864f415d80a1863ae45b31d217d0c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Apr 2026 18:30:12 +0000 Subject: [PATCH] feat: add no_new_privileges config for non-root containers Agent-Logs-Url: https://github.com/nextcloud/all-in-one/sessions/486c681f-f240-4505-9fc9-b143b50348f5 Co-authored-by: szaimen <42591237+szaimen@users.noreply.github.com> --- php/containers-schema.json | 3 +++ php/containers.json | 36 +++++++++++++++++--------- php/src/Container/Container.php | 1 + php/src/ContainerDefinitionFetcher.php | 6 +++++ php/src/Docker/DockerActionManager.php | 10 ++++--- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/php/containers-schema.json b/php/containers-schema.json index fc0e03dc..9a013bbb 100644 --- a/php/containers-schema.json +++ b/php/containers-schema.json @@ -197,6 +197,9 @@ "read_only": { "type": "boolean" }, + "no_new_privileges": { + "type": "boolean" + }, "init": { "type": "boolean" }, diff --git a/php/containers.json b/php/containers.json index ce6f08f6..a06dabe1 100644 --- a/php/containers.json +++ b/php/containers.json @@ -81,7 +81,8 @@ ], "cap_drop": [ "NET_RAW" - ] + ], + "no_new_privileges": true }, { "container_name": "nextcloud-aio-database", @@ -138,7 +139,8 @@ ], "cap_drop": [ "NET_RAW" - ] + ], + "no_new_privileges": true }, { "container_name": "nextcloud-aio-nextcloud", @@ -321,7 +323,8 @@ "read_only": true, "cap_drop": [ "NET_RAW" - ] + ], + "no_new_privileges": true }, { "container_name": "nextcloud-aio-redis", @@ -363,7 +366,8 @@ "read_only": true, "cap_drop": [ "NET_RAW" - ] + ], + "no_new_privileges": true }, { "container_name": "nextcloud-aio-collabora", @@ -413,7 +417,8 @@ ], "cap_drop": [ "NET_RAW" - ] + ], + "no_new_privileges": true }, { "container_name": "nextcloud-aio-talk", @@ -484,7 +489,8 @@ ], "cap_drop": [ "NET_RAW" - ] + ], + "no_new_privileges": true }, { "container_name": "nextcloud-aio-talk-recording", @@ -538,7 +544,8 @@ ], "cap_drop": [ "NET_RAW" - ] + ], + "no_new_privileges": true }, { "container_name": "nextcloud-aio-borgbackup", @@ -665,7 +672,8 @@ ], "cap_drop": [ "NET_RAW" - ] + ], + "no_new_privileges": true }, { "container_name": "nextcloud-aio-clamav", @@ -712,7 +720,8 @@ ], "cap_drop": [ "NET_RAW" - ] + ], + "no_new_privileges": true }, { "container_name": "nextcloud-aio-onlyoffice", @@ -798,7 +807,8 @@ ], "secrets": [ "IMAGINARY_SECRET" - ] + ], + "no_new_privileges": true }, { "container_name": "nextcloud-aio-fulltextsearch", @@ -850,7 +860,8 @@ ], "cap_drop": [ "NET_RAW" - ] + ], + "no_new_privileges": true }, { "container_name": "nextcloud-aio-docker-socket-proxy", @@ -965,7 +976,8 @@ "read_only": true, "cap_drop": [ "NET_RAW" - ] + ], + "no_new_privileges": true } ] } diff --git a/php/src/Container/Container.php b/php/src/Container/Container.php index 6b6c5af9..05dbca8c 100644 --- a/php/src/Container/Container.php +++ b/php/src/Container/Container.php @@ -33,6 +33,7 @@ readonly class Container { public array $backupVolumes, public array $nextcloudExecCommands, public bool $readOnlyRootFs, + public bool $noNewPrivileges, public array $tmpfs, public bool $init, public string $imageTag, diff --git a/php/src/ContainerDefinitionFetcher.php b/php/src/ContainerDefinitionFetcher.php index e4625a24..af500084 100644 --- a/php/src/ContainerDefinitionFetcher.php +++ b/php/src/ContainerDefinitionFetcher.php @@ -323,6 +323,11 @@ readonly class ContainerDefinitionFetcher { $readOnlyRootFs = $entry['read_only']; } + $noNewPrivileges = false; + if (isset($entry['no_new_privileges'])) { + $noNewPrivileges = $entry['no_new_privileges']; + } + $tmpfs = []; if (isset($entry['tmpfs'])) { $tmpfs = $entry['tmpfs']; @@ -365,6 +370,7 @@ readonly class ContainerDefinitionFetcher { $backupVolumes, $nextcloudExecCommands, $readOnlyRootFs, + $noNewPrivileges, $tmpfs, $init, $imageTag, diff --git a/php/src/Docker/DockerActionManager.php b/php/src/Docker/DockerActionManager.php index ca6a4d72..703f6a52 100644 --- a/php/src/Docker/DockerActionManager.php +++ b/php/src/Docker/DockerActionManager.php @@ -405,10 +405,14 @@ readonly class DockerActionManager { } // Disable SELinux for AIO containers so that it does not break them - $requestBody['HostConfig']['SecurityOpt'] = ["label:disable"]; + $securityOpts = ["label:disable"]; if ($container->apparmorUnconfined) { - $requestBody['HostConfig']['SecurityOpt'] = ["apparmor:unconfined", "label:disable"]; + $securityOpts[] = "apparmor:unconfined"; } + if ($container->noNewPrivileges) { + $securityOpts[] = "no-new-privileges:true"; + } + $requestBody['HostConfig']['SecurityOpt'] = $securityOpts; $mounts = []; @@ -463,7 +467,7 @@ readonly class DockerActionManager { if (!$this->configurationManager->collaboraSeccompDisabled) { // Load reference seccomp profile for collabora $seccompProfile = (string)file_get_contents(DataConst::GetCollaboraSeccompProfilePath()); - $requestBody['HostConfig']['SecurityOpt'] = ["label:disable", "seccomp=$seccompProfile"]; + $requestBody['HostConfig']['SecurityOpt'][] = "seccomp=$seccompProfile"; } // Additional Collabora options