RSTR-IAC-006 — curl | sh pattern
Summary
A Dockerfile (or build script generally) pipes the output of curl
straight into a shell: curl https://example.com/install.sh | sh.
There is no integrity check on the bytes that the shell ends up
executing. If the upstream is compromised, an attacker on the
network can MITM, DNS gets poisoned, or TLS fails open for any other
reason, the build silently runs whatever bytes arrived.
The pattern is convenient enough that vendors keep recommending it ("for the quickest install, run …"). Convenience does not change the threat model.
Severity
High.
Languages
Dockerfiles, Containerfiles.
What rastray flags
RUN curl -fsSL https://get.example.com | sh # ← flagged
RUN wget -qO- https://example.com/install.sh | bash # ← flagged
RUN curl https://example.com/setup.py | python # ← flagged
What rastray deliberately does not flag
- Downloads written to a file and checksum-verified before execution.
- Installs via the distro package manager (
apt-get,apk,dnf) — those run their own signature verification.
How to fix it
Download, verify, then execute:
RUN curl -fsSL https://example.com/install.sh -o /tmp/install.sh \
&& echo 'deadbeef... /tmp/install.sh' | sha256sum -c - \
&& sh /tmp/install.sh \
&& rm /tmp/install.sh
For tools you install regularly, vendor the installer into your repository and commit the checksum next to it — the chain of custody runs from your reviewers to the binary in one step.
If the vendor signs releases with GPG, prefer that:
RUN curl -fsSL https://example.com/install.sh -o /tmp/install.sh \
&& curl -fsSL https://example.com/install.sh.asc -o /tmp/install.sh.asc \
&& gpg --verify /tmp/install.sh.asc /tmp/install.sh \
&& sh /tmp/install.sh