build: Dockerfile: mod "new user to avoid using root" to support UID=0
What changed, and why it matters
This commit changes several Docker build files so the build containers can optionally run as the root user (UID 0) instead of always creating a normal 'user' account. By default it still uses UID 1000, but when the build is invoked with UID=0 it skips creating an unprivileged user and runs everything as root. This is a build-hardening regression: it weakens the principle of least privilege in the build environment, but it does not directly introduce a vulnerability in the Electrum wallet software that end users run.
Treat this as a build-hardening note rather than a CVE-worthy vulnerability. If reviewing supply-chain posture, consider whether the CI pipeline truly requires root, and if so, apply compensating controls such as read-only root filesystems, minimal base images, reproducible builds, artifact checksum verification, and restricted network access. No emergency patch to end-user software is needed.
Security signals we found
Build containers can now run as root (UID=0) when ARG UID=0 is supplied
Conditional skip of unprivileged user creation removes a defense-in-depth control
NOPASSWD sudo configuration remains present, but is less meaningful when already running as root
Change is build-environment hardening regression, not a runtime wallet vulnerability
Evidence from the diff
The patch modifies four Dockerfiles (Android, AppImage, sdist, Wine) used to produce Electrum release binaries. Previously they always created a non-root user named ‘user’ and switched to it with USER. The new logic conditionally skips user creation when ARG UID=0, resolves HOME_DIR via getent for UID 0 (/root), and uses USER ${UID}. The commit message explicitly states this is to allow build.sh to run directly on Cirrus CI runners as root. Running container builds as root increases the blast radius of supply-chain attacks (e.g., a compromised dependency or build script can modify the container filesystem, install persistent malware, or tamper with artifacts more easily), but the change itself is not an exploitable bug in the shipped application.
Changed components
contrib/android/Dockerfilecontrib/build-linux/appimage/Dockerfilecontrib/build-linux/sdist/Dockerfilecontrib/build-wine/DockerfileInspect captured patch +26 / −30
diff --git a/contrib/android/Dockerfile b/contrib/android/Dockerfile
index d1f1c21..74f5392 100644
--- a/contrib/android/Dockerfile
+++ b/contrib/android/Dockerfile
@@ -174,17 +174,16 @@ RUN apt -y update -qq \
# create new user to avoid using root; but with sudo access and no password for convenience.
ARG UID=1000
-ENV USER="user"
-ENV HOME_DIR="/home/${USER}"
+RUN if [ "$UID" != "0" ] ; then useradd --uid $UID --create-home --shell /bin/bash "user" ; fi
+RUN usermod -append --groups sudo $(id -nu $UID || echo "user")
+RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
+RUN HOME_DIR=$(getent passwd $UID | cut -d: -f6)
ENV WORK_DIR="${HOME_DIR}/wspace" \
PATH="${HOME_DIR}/.local/bin:${PATH}"
-RUN useradd --uid $UID --create-home --shell /bin/bash ${USER}
-RUN usermod -append --groups sudo ${USER}
-RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
WORKDIR ${WORK_DIR}
-RUN chown --recursive ${USER} ${WORK_DIR} ${ANDROID_SDK_HOME}
-RUN chown ${USER} /opt
-USER ${USER}
+RUN chown --recursive ${UID} ${WORK_DIR} ${ANDROID_SDK_HOME}
+RUN chown ${UID} /opt
+USER ${UID}
# venv, VIRTUAL_ENV is used by buildozer to indicate a venv environment
ENV VIRTUAL_ENV=/opt/venv
diff --git a/contrib/build-linux/appimage/Dockerfile b/contrib/build-linux/appimage/Dockerfile
index 2b5148c..5f43ac9 100644
--- a/contrib/build-linux/appimage/Dockerfile
+++ b/contrib/build-linux/appimage/Dockerfile
@@ -75,13 +75,12 @@ RUN apt-get update -q && \
# create new user to avoid using root; but with sudo access and no password for convenience.
ARG UID=1000
-ENV USER="user"
-ENV HOME_DIR="/home/${USER}"
+RUN if [ "$UID" != "0" ] ; then useradd --uid $UID --create-home --shell /bin/bash "user" ; fi
+RUN usermod -append --groups sudo $(id -nu $UID || echo "user")
+RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
+RUN HOME_DIR=$(getent passwd $UID | cut -d: -f6)
ENV WORK_DIR="${HOME_DIR}/wspace" \
PATH="${HOME_DIR}/.local/bin:${PATH}"
-RUN useradd --uid $UID --create-home --shell /bin/bash ${USER}
-RUN usermod -append --groups sudo ${USER}
-RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
WORKDIR ${WORK_DIR}
-RUN chown --recursive ${USER} ${WORK_DIR}
-USER ${USER}
+RUN chown --recursive ${UID} ${WORK_DIR}
+USER ${UID}
diff --git a/contrib/build-linux/sdist/Dockerfile b/contrib/build-linux/sdist/Dockerfile
index d397e85..3b6f121 100644
--- a/contrib/build-linux/sdist/Dockerfile
+++ b/contrib/build-linux/sdist/Dockerfile
@@ -18,13 +18,12 @@ RUN apt-get update -q && \
# create new user to avoid using root; but with sudo access and no password for convenience.
ARG UID=1000
-ENV USER="user"
-ENV HOME_DIR="/home/${USER}"
+RUN if [ "$UID" != "0" ] ; then useradd --uid $UID --create-home --shell /bin/bash "user" ; fi
+RUN usermod -append --groups sudo $(id -nu $UID || echo "user")
+RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
+RUN HOME_DIR=$(getent passwd $UID | cut -d: -f6)
ENV WORK_DIR="${HOME_DIR}/wspace" \
PATH="${HOME_DIR}/.local/bin:${PATH}"
-RUN useradd --uid $UID --create-home --shell /bin/bash ${USER}
-RUN usermod -append --groups sudo ${USER}
-RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
WORKDIR ${WORK_DIR}
-RUN chown --recursive ${USER} ${WORK_DIR}
-USER ${USER}
+RUN chown --recursive ${UID} ${WORK_DIR}
+USER ${UID}
diff --git a/contrib/build-wine/Dockerfile b/contrib/build-wine/Dockerfile
index f62b1da..4a7022b 100644
--- a/contrib/build-wine/Dockerfile
+++ b/contrib/build-wine/Dockerfile
@@ -58,16 +58,15 @@ RUN DEBIAN_CODENAME=$(lsb_release --codename --short) && \
# create new user to avoid using root; but with sudo access and no password for convenience.
ARG UID=1000
-ENV USER="user"
-ENV HOME_DIR="/home/${USER}"
+RUN if [ "$UID" != "0" ] ; then useradd --uid $UID --create-home --shell /bin/bash "user" ; fi
+RUN usermod -append --groups sudo $(id -nu $UID || echo "user")
+RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
+RUN HOME_DIR=$(getent passwd $UID | cut -d: -f6)
ENV WORK_DIR="${HOME_DIR}/wspace" \
PATH="${HOME_DIR}/.local/bin:${PATH}"
-RUN useradd --uid $UID --create-home --shell /bin/bash ${USER}
-RUN usermod -append --groups sudo ${USER}
-RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
WORKDIR ${WORK_DIR}
-RUN chown --recursive ${USER} ${WORK_DIR}
-RUN chown ${USER} /opt
-USER ${USER}
+RUN chown --recursive ${UID} ${WORK_DIR}
+RUN chown ${UID} /opt
+USER ${UID}
RUN mkdir --parents "/opt/wine64/drive_c/electrum"
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.