{
  "id": "CB-UBU-FS-011",
  "standard": "ubuntu",
  "version": "0.1.2",
  "url": "https://baselines.cirsec.org/b/ubuntu/v0.1.2/CB-UBU-FS-011",
  "json": "https://baselines.cirsec.org/b/ubuntu/v0.1.2/CB-UBU-FS-011.json",
  "yaml": "https://baselines.cirsec.org/b/ubuntu/v0.1.2/CB-UBU-FS-011.yml",
  "profiles_effective": [
    "core",
    "server",
    "server-hardened",
    "desktop",
    "desktop-hardened"
  ],
  "license": "Text CC BY 4.0, code Apache-2.0",
  "attribution": "CIRSEC Baselines, https://baselines.cirsec.org",
  "control": {
    "id": "CB-UBU-FS-011",
    "title": "Keep system programs and libraries owned by root and not writable by others",
    "finding": {
      "title": "System programs or libraries can be changed by a non-root account",
      "description": "A user or service that can write to a system program or library runs code as every user who calls it, root included."
    },
    "status": "active",
    "profiles": [
      "core"
    ],
    "risk": {
      "severity": "high"
    },
    "assessment": "automated",
    "tags": [
      "permissions",
      "binaries",
      "libraries"
    ],
    "description": "In the system program and library directories (`/usr/bin`, `/usr/sbin`, `/usr/lib`,\n`/usr/lib64`, `/usr/libexec`, `/usr/local/bin`, `/usr/local/sbin`, `/usr/local/lib`, and\n`/bin`, `/sbin`, `/lib`, `/lib64` when they are real directories):\n\n- every directory belongs to `root:root` and is not writable by group or others;\n- every file belongs to `root` and is not writable by group or others.\n\nFiles may belong to another group: Ubuntu ships setgid helpers owned by groups such as\n`shadow`, `_ssh` or `messagebus`. Two packaging exceptions are accepted:\n\n- the files of `{{ owner_exceptions }}` (format `path:owner`) may belong to that owner, as long\n  as group and others cannot write them;\n- directories under `/usr/local` may be `root:staff` and writable by group `staff`, as long as\n  that group has no member.\n",
    "rationale": "Programs in these directories run as root through services, cron, sudo and package scripts, and\nlibraries are loaded into every process. Write access for anyone but root lets that account\nreplace them and gain root, or persist unnoticed.\n",
    "impact": "None on a standard system, where packages install everything as root. Software installed by\nhand under `/usr/local` by a regular user must be given to root.\n",
    "notes": "A deviation here usually means software installed outside the package manager, or tampering.\nThe fix is therefore manual: find the cause before changing the owner, because `chown` also\nclears setuid and setgid bits.\n\nUbuntu 20.04 has both exceptions on a fresh install: the `at` package installs `/usr/bin/at`\nsetuid and setgid `daemon:daemon`, and Python creates `/usr/local/lib/python3.8` group-writable\nby `staff`, an old Debian convention for letting local administrators install into\n`/usr/local`. Members of `staff` can plant code that root runs (a Python module, for example),\nso they count as root: the check fails as soon as the group has a member. Ubuntu 22.04 and\nlater no longer have either.\n",
    "parameters": [
      {
        "name": "owner_exceptions",
        "type": "list",
        "description": "Files accepted with a non-root owner, as path:owner.",
        "default": [
          "/usr/bin/at:daemon"
        ]
      }
    ],
    "audit": {
      "manual": "Run, for each of the directories above that exists and is not a symbolic link:\n```\nfind <dir> -xdev \\( -type d \\( ! -user root -o ! -group root -o -perm /022 \\) \\) -o \\( ! -type d ! -type l \\( ! -user root -o -perm /022 \\) \\) -print\n```\nThe command must print nothing.\n",
      "checks": [
        {
          "id": "system-dirs",
          "engine": "shell",
          "description": "Owner, group and write bits of directories and files in system program and library directories.",
          "spec": {
            "script": "out=$(for d in /usr/bin /usr/sbin /usr/lib /usr/lib64 /usr/libexec /usr/local/bin /usr/local/sbin /usr/local/lib /bin /sbin /lib /lib64; do\n  [ -d \"$d\" ] && [ ! -L \"$d\" ] || continue\n  find \"$d\" -xdev \\( \\( -type d \\( ! -user root -o ! -group root -o -perm /022 \\) \\) -o \\\n    \\( ! -type d ! -type l \\( ! -user root -o -perm /022 \\) \\) \\) -print 2>/dev/null\ndone | sort -u)\nstaff=$(getent group staff | cut -d: -f4)\nbad=\nwhile IFS= read -r f; do\n  [ -n \"$f\" ] || continue\n  u=$(stat -c %U \"$f\") g=$(stat -c %G \"$f\") m=$(stat -c %a \"$f\")\n  ok=0\n  for e in $CB_OWNER_EXCEPTIONS; do [ \"$e\" = \"$f:$u\" ] && ok=1; done\n  if [ \"$ok\" = 1 ] && [ $((0$m & 022)) -eq 0 ]; then\n    echo \"accepted: $f owned by $u\"; continue\n  fi\n  case $f in /usr/local/*)\n    if [ -d \"$f\" ] && [ \"$u:$g\" = root:staff ] && [ -z \"$staff\" ] && [ $((0$m & 02)) -eq 0 ]; then\n      echo \"accepted: $f writable by group staff, which has no member\"; continue\n    fi ;;\n  esac\n  bad=\"$bad$f\n\"\ndone <<EOF\n$out\nEOF\n[ -z \"$bad\" ] && { echo \"system programs and libraries belong to root and are not writable by others\"; exit 0; }\necho \"$(printf '%s' \"$bad\" | wc -l) item(s):\"\nprintf '%s' \"$bad\" | head -n 20 | while IFS= read -r f; do stat -c '%A %U:%G %n' \"$f\"; done\nexit 1\n"
          }
        }
      ]
    },
    "remediation": {
      "manual": "For each reported item (the exceptions of the description aside):\n1. Find its package with `dpkg -S <path>` and check it with `dpkg --verify <package>`. A\n   changed file from a package is a possible compromise: investigate first, then reinstall the\n   package with `apt-get install --reinstall <package>`.\n2. For files installed by hand, run `chown root <path>` (then restore any setuid or setgid\n   bit that was intended) and `chmod go-w <path>`; for directories, `chown root:root <dir>`\n   and `chmod go-w <dir>`.\n3. Under `/usr/local`, either keep group `staff` without members, or run\n   `chmod -R g-w /usr/local` and `chgrp -R root /usr/local`.\n"
    },
    "references": [
      {
        "title": "file-hierarchy(7), Ubuntu manual pages",
        "url": "https://manpages.ubuntu.com/manpages/noble/man7/file-hierarchy.7.html",
        "publisher": "Canonical",
        "kind": "vendor-doc",
        "accessed": "2026-10-19"
      },
      {
        "title": "dpkg(1), Ubuntu manual pages (--verify)",
        "url": "https://manpages.ubuntu.com/manpages/noble/man1/dpkg.1.html",
        "publisher": "Canonical",
        "kind": "vendor-doc",
        "accessed": "2026-10-19"
      },
      {
        "title": "ANSSI-BP-028 v2.0 - Recommandations de configuration d'un système GNU/Linux (R50)",
        "url": "https://messervices.cyber.gouv.fr/documents-guides/fr_np_linux_configuration-v2.0.pdf",
        "publisher": "ANSSI",
        "kind": "guide",
        "accessed": "2026-10-19"
      }
    ],
    "mappings": [
      {
        "framework": "anssi-linux",
        "framework_version": "2.0",
        "id": "R50",
        "relation": "partial",
        "note": "R50 covers every sensitive file; this control covers system programs and libraries."
      },
      {
        "framework": "nist-800-53r5",
        "framework_version": "5.1.1",
        "id": "CM-5(6)",
        "relation": "equivalent"
      }
    ],
    "threats": [
      {
        "framework": "mitre-attack",
        "id": "T1574.006"
      },
      {
        "framework": "mitre-attack",
        "id": "T1554"
      },
      {
        "framework": "cwe",
        "id": "CWE-732"
      }
    ],
    "related_controls": [
      {
        "id": "CB-UBU-FS-010",
        "type": "related"
      }
    ],
    "authors": [
      {
        "name": "Alice",
        "github": "Sn0wAlice"
      }
    ],
    "verified": [
      {
        "date": "2026-10-19",
        "by": "Sn0wAlice",
        "versions": [
          "20.04"
        ],
        "environment": "Proxmox VM 2520, Ubuntu 20.04 cloud image, kernel 5.4.0-216-generic",
        "notes": "Passes on fresh install with the two exceptions reported (/usr/bin/at owned by daemon, /usr/local/lib/python3.8 group staff); fails once staff has a member; group-writable file owned by nobody in /usr/local/bin detected."
      },
      {
        "date": "2026-10-19",
        "by": "Sn0wAlice",
        "versions": [
          "22.04"
        ],
        "environment": "Proxmox VM 2522, Ubuntu 22.04 cloud image, kernel 5.15.0-198-generic",
        "notes": "Passes on fresh install; group-writable file owned by nobody in /usr/local/bin detected."
      },
      {
        "date": "2026-10-19",
        "by": "Sn0wAlice",
        "versions": [
          "24.04"
        ],
        "environment": "Proxmox VM 2524, Ubuntu 24.04 cloud image, kernel 6.8.0-147-generic",
        "notes": "Passes on fresh install."
      },
      {
        "date": "2026-10-19",
        "by": "Sn0wAlice",
        "versions": [
          "26.04"
        ],
        "environment": "Proxmox VM 2526, Ubuntu 26.04 cloud image, kernel 7.0.0-38-generic",
        "notes": "Passes on fresh install; group-writable file owned by nobody in /usr/local/bin detected."
      }
    ],
    "introduced_in": "0.1.0",
    "created": "2026-10-19",
    "updated": "2026-10-19"
  }
}