TL;DR: Not the username. What matters is every privilege transition the process can reach: its own capabilities, sudo rules for its user, setuid and setgid programs, writable files that something privileged later runs or reads, secrets it can read, privileged sockets and APIs it can talk to (the Docker socket is root), the kernel surface it can call, and whether
no_new_privsand a sandbox profile are set. Answer as a reviewer: enumerate those transitions for the service's identity, close each one you can, and make the rest observable.
How to approach it
Treat it as a reachability question: from this process, with these credentials, what can cause code to run with more privilege? Group the paths into what the process already holds, what it can trigger, what it can tamper with, and what it can read. Then state what you would check, in order of likelihood, and what a hardened unit file looks like.
A strong answer
Compromised service
user www
Reachable transitions
what can it touch?
Root
or equivalent
Doors to check and close
Granted privilege
- Capabilities, sudo rules, setuid programs
Writable things root uses
- Cron scripts, unit files, configs, plugin directories
Privileged endpoints
- Docker socket, cloud metadata, admin APIs
Kernel surface
- No seccomp profile, no no_new_privs, old kernel
What the process already holds.
- Capabilities. Linux splits root into capabilities, and a "non-root" service can still hold some.
CAP_SYS_ADMINis broad enough to be close to root;CAP_DAC_OVERRIDEignores file permissions;CAP_SYS_PTRACEcan inject into other processes;CAP_SYS_MODULEloads kernel code. Check/proc/<pid>/status(CapEff,CapBnd) and the unit file. - Group memberships. Membership in
docker,disk,adm,wheelorlxdgroups is often equivalent to root or to reading everything. - Open handles and inherited descriptors. A descriptor to a privileged file or socket inherited from a parent survives the privilege drop.
What it can trigger.
- sudo rules for the service user. Any rule allowing an editor, an interpreter,
find,taror a script the user can modify is a root shell by another name. - setuid and setgid binaries. Each is privileged code reading the attacker's arguments and environment. Unusual or outdated ones are the risk; a minimal system has very few.
- Privileged daemons it can talk to. The Docker or containerd socket lets the caller start a container that mounts the host filesystem. A local admin API, D-Bus services with weak policy, or a database running as root are similar.
What it can tamper with. Files that something privileged later executes or reads: scripts in root's cron, systemd unit files and their ExecStart targets, directories in a privileged program's PATH or library search path, configuration files of privileged services, Python packages imported by a root process. Write access to any of these converts to root at the next run.
What it can read. Credentials for more privileged identities: SSH keys, cloud credentials in environment files, database passwords, tokens for an orchestration API, the instance metadata service if the host's role is powerful. Often the fastest path to root is a credential, not an exploit.
The kernel. If nothing else works, the attacker targets the kernel through the system calls they can make. An unpatched kernel plus an unrestricted system call surface is the last-resort path, which is why patching and seccomp both matter.
What you check, in order. Capabilities and groups; sudo rules; writable paths used by privileged processes (find for files writable by the service user outside its own data directories); setuid inventory; reachable privileged sockets; readable secrets; kernel version and seccomp status.
What the hardened version looks like. A dedicated user with no shell and no group memberships; in the systemd unit, NoNewPrivileges=yes (so setuid binaries no longer elevate), CapabilityBoundingSet= limited to what is needed (often empty), ProtectSystem=strict and ProtectHome=yes (read-only system, no home directories), PrivateTmp=yes, ReadWritePaths= for its own data only, SystemCallFilter=@system-service, and an AppArmor or SELinux profile. Secrets come from a manager at runtime with only this service's scope. Then a successful compromise of the service gives the attacker the service's data and nothing else, which is the design goal.
What interviewers probe next
- "Why is membership in the docker group equivalent to root?" The daemon runs as root and will start a container with the host's root filesystem mounted and privileged mode on request.
- "What does
no_new_privschange?" After it is set,execvecan no longer grant privileges: setuid bits and file capabilities are ignored for that process and its children. It is also required before an unprivileged process can install a seccomp filter. - "How would you detect an attempt?" Process events where the service's descendants run as root, execution of sudo or setuid binaries by the service user, writes to cron or unit directories, and connections to the Docker socket.
What if?
What if · interview follow-ups
Hold your answer as the constraints change
An attacker has code execution as a web service account on a Linux host, and the team assumes they are safe because the account is not root.
Start here
What actually matters, if not the username?
What can the process reach that leads to more privilege?
Every privilege transition the process can reach: its capabilities, sudo rules, setuid and setgid programs, writable files something privileged runs or reads, secrets it can read, privileged sockets and APIs, and the kernel surface it can reach.
Carry it forwardReachable transitions matter, not the name.
Weak answerEquating non-root with safe.
Constraint changes
Why is the Docker socket special?
What can a Docker API client start?
Anyone who can talk to the Docker socket can start a privileged container with the host filesystem mounted, which is effectively root on the host.
Carry it forwardDocker socket access equals root.
Weak answerMounting the socket into application containers.
Constraint changes
What about secrets the service holds?
Where can the service's credentials take an attacker?
Database credentials, cloud tokens and API keys let the attacker escalate outside the host: reading all data or calling cloud APIs. Often more valuable than root on one box.
Carry it forwardService secrets extend escalation beyond the host.
Weak answerSecuring the host but not the credentials.
Constraint changes
How would a defender enumerate the paths?
What would you inventory?
List capabilities, sudo rules, setuid binaries, writable paths used by privileged processes, readable secrets, accessible sockets and network services, and check kernel patch status, then remove what is not needed.
Carry it forwardEnumerate and close each transition.
Weak answerAd hoc checks.
Constraint changes
How do you constrain the service by design?
What would the attacker find after compromise?
Systemd sandboxing (no new privileges, read-only filesystem, private tmp), no capabilities, seccomp, a MAC profile, narrowly scoped and short-lived secrets, and no access to privileged sockets.
Carry it forwardDesign the service to have nothing to escalate with.
Weak answerDefault service units.
Now defend it
How would you assess and reduce the risk?
Enumerate reachable transitions (capabilities, sudo, setuid, writable privileged paths, secrets, sockets including Docker, kernel surface) and remove them; sandbox the service with systemd hardening, seccomp and MAC; scope and shorten secrets; and monitor for escalation attempts.
How it's scored
Weak: "It runs as a normal user, so it is fine unless there is a kernel exploit."
Hire: Lists capabilities, sudo, setuid binaries, writable privileged files and readable credentials, and proposes a dedicated user with least privilege.
Strong Hire: Frames it as reachable privilege transitions, includes privileged sockets and group memberships, gives a concrete hardened unit (NoNewPrivileges, empty capability set, filesystem protection, system call filter, MAC profile), and pairs it with detections.
Common mistakes
- Equating non-root with low privilege while ignoring capabilities and groups.
- Forgetting writable files that privileged processes execute.
- Missing the Docker socket and similar privileged APIs.
- Treating kernel patching as the only control.