Self-hosted service
vulhub/vulhub avatar
vulhub/vulhub

Vulhub: one directory per CVE, one compose command, one shallow clone

Pre-Built Vulnerable Environments Based on Docker-Compose

21,492 stars4,811 forksDockerfileMIT

At a glance

What is it?
Vulhub ships vulnerable products as Docker Compose directories: clone the repository shallow, cd into a CVE folder, run one command. The design is documentation you can execute, which makes each per-directory README the only record of whether the reproduction still works.
Who is it for?
Take Vulhub when you need a vulnerable target on demand for research, teaching or a demo, and can treat the environment as disposable, because docker compose down -v discards the volumes and the per-directory README is your only record of how the reproduction should behave. Leave it if you need a long-lived stack, a pinned version, or a run on ARM hardware: the repository publishes no releases, states no minimum Docker version, and does not say which environments skip ARM.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 28 days ago.
What is it written in?
Mainly Dockerfile, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • vulhub/vulhub21,492 ★ · +233
Star history
Repository2026-09-212026-11-14
vulhub/vulhub21.3k21.5k

233 Stars in the last 54 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

A vulnerability is a directory you cd into

Every environment is a directory holding a Docker Compose setup and its own README with reproduction steps and usage instructions. There is nothing to compile and no service to register. You move into the folder for the product and CVE you want and bring the stack up with one command:

bash
cd vulhub/langflow/CVE-2025-3248  # Example: enter a vulnerability directory
docker compose up -d

The shape of that path is the indexing scheme: product first, then the CVE identifier. The top level follows the same convention with directories such as activemq/, adminer/, airflow/, apache-cxf/, flask/, ghostscript/, gitea/ and gitlab/.

The stack then stays up until you take it down, and the cleanup step is docker compose down -v. The -v matters more than it looks. It discards the volumes the environment created, so anything you wrote inside the container while testing goes with it. That is the correct default for a throwaway target and the wrong one for anything you meant to keep.

The per-directory README is the only reproduction record

The work lives in those per-folder READMEs. Vulhub is documentation you can execute: one CVE per directory, a written procedure per directory, and a compose file underneath it.

The cost of that arrangement is that freshness is manual. The quick start gives you no way to tell a working environment from a stale one, states no image versions the compose files pin, and names no minimum Docker version. If a reproduction fails, the only record you can compare against is the prose in that folder, and nothing in the quick start ties a step to the version of the software it was written against.

Two absences matter if you plan to script around this. The top-level README never mentions environments.toml, which sits next to the directories, so the catalogue of what is included is not reachable from the documentation you get here. And the English README is maintained alongside a Chinese version at README.zh-cn.md, so a fix for one may not exist in the other when you are reading.

A shallow clone with no submodule flag

The download step is one line:

bash
git clone --depth 1 https://github.com/vulhub/vulhub

--depth 1 gives you the current tree and no history, a sensible trade for a repository this wide when all you want is to run something. The top level also carries a .gitmodules file, which is where Git records paths that are separate repositories. The documented clone command has no submodule flag and the quick start does not mention one, so any directory recorded there arrives empty after a plain clone.

The failure this produces is easy to misread. You end up inside a product directory with an empty CVE folder, no compose file, and a README describing steps for software you do not have, which looks like a broken environment rather than an incomplete checkout. Check that the directory you are standing in actually has files in it, and whether its path appears in .gitmodules, before spending an afternoon on a reproduction that was never downloaded.

The docs assume a VPS, your own IP, and a gigabyte of RAM

The note under the quick start sets three assumptions. It suggests a VPS or VM with at least 1GB RAM for best results. It says the your-ip placeholder in the documentation refers to your host or VPS IP, not the Docker container IP. And it asks you to ensure Docker has permission to access all files in the current directory to avoid permission errors.

Each one changes how the steps read in practice. A command copied with your-ip still in it points at nothing. If you follow the docs literally on a laptop, your-ip is the machine in front of you rather than a public address, which moves the vulnerability somewhere else than the writer intended. The permission note bites hardest on a shared host or a CI runner where the Docker daemon belongs to a different user than the checkout, and it surfaces as a permission error rather than a missing file.

The same note carries the boundary that matters most: all environments are for testing and educational purposes only, do not use in production. These are deliberately broken services, and what you get is a disclaimer rather than a network boundary, so isolating them is your own problem to solve.

ARM Macs run natively until they do not

Troubleshooting names Apple Silicon first. Most environments run natively on Docker Desktop for Mac with M-series chips, and when one fails the documented fix is to set the platform explicitly:

bash
export DOCKER_DEFAULT_PLATFORM=linux/amd64
docker compose up -d

The override buys you emulation, not support. The quick start note says some environments may not support ARM architectures and points at troubleshooting for detail, and the M-series passage does not enumerate which ones. So an ARM machine has three outcomes available: the environment runs, it runs slowly under the override, or it does not start at all. The documentation tells you in advance that the third case exists without naming it.

The same section covers two other failures with different fixes. Image pulls that fail in mainland China are answered with a registry mirror or a run on an overseas VPS. Environments that fail on Kali Linux are attributed to a low ulimit nofile setting, with the fix handed off to the FAQ at vulhub.org/documentation/faq rather than given in the repository.

Compose plugin syntax is required and its version is never stated

One migration note is explicit: although all Vulhub environments run on Docker Compose, you no longer need to install docker-compose separately, and the built-in docker compose command replaces it. Every command in the quick start follows from that, which makes the plugin style CLI a hard requirement rather than a convenience.

What is missing is a floor. No minimum Docker version appears anywhere in the README, so on an installation old enough that docker compose is not a subcommand, the single command this project is built around does not exist, and the error looks like a missing command rather than an unsupported host.

Docker itself is installed the way the project documents it, for Ubuntu 24.04:

bash
# Install the latest version docker
curl -s https://get.docker.com/ | sh

# Run docker service
systemctl start docker

That pipes a script from the Docker endpoint straight into a shell, which is a trust decision about what that endpoint serves at the moment you run it. Every other operating system is referred to the Docker documentation instead of being given a path here.

No releases and a shallow clone leave no rollback path

The repository publishes no GitHub releases and the default branch is master, so there is no tag to pin a compose file to. The last push was on 2026-10-17, which tells you commits are still landing on master, and a clone taken today gets whatever state that branch is in at that moment.

Put that together with the shallow clone and the position gets narrow: one snapshot, no release name, no history to diff against when an environment stops matching its README. If you need the same setup next month, keeping your own copy of the repository is the only route, and pinning a commit inside your own fork is the only lever the repository itself offers.

Contributions run through CONTRIBUTING.md, and the support channels the project names are a Discord server and its account on X.

Editorial conclusion

Take Vulhub when you need a vulnerable target on demand for research, teaching or a demo, and can treat the environment as disposable, because docker compose down -v discards the volumes and the per-directory README is your only record of how the reproduction should behave. Leave it if you need a long-lived stack, a pinned version, or a run on ARM hardware: the repository publishes no releases, states no minimum Docker version, and does not say which environments skip ARM. Before the first run, confirm the directory has files in it after the shallow clone, and keep the stack off any network you care about.

Frequently asked questions

vulhub vs vulnhub: which one is this?

vulhub/vulhub is a collection of pre-built vulnerable Docker environments for security research, learning and demonstration, each launched with docker compose up -d. The README does not describe any other project with a similar name.

Is VulnHub still active?

The vulhub/vulhub repository is not archived and its last push was on 2026-10-17. It publishes no GitHub releases, so changes land on the master branch rather than on tags.

How do I launch a Vulhub environment?

Clone with git clone --depth 1 https://github.com/vulhub/vulhub, change into the directory for the environment, for example vulhub/langflow/CVE-2025-3248, and run docker compose up -d. Each directory has its own README with reproduction steps, and docker compose down -v tears the stack down and discards its volumes.

Do I need to install docker-compose separately for Vulhub?

No. The README states that all environments run on Docker Compose but that docker-compose no longer has to be installed separately, and that the built-in docker compose command starts them instead.

Why does a Vulhub environment fail on an M-series Mac?

Most environments run natively on Docker Desktop for Mac with M-series chips. When one fails, the documented fix is export DOCKER_DEFAULT_PLATFORM=linux/amd64 followed by docker compose up -d, and the quick start notes that some environments may not support ARM architectures at all.

Official sources

  1. Issues
  2. License: MIT
  3. Project website
  4. README
  5. vulhub/vulhub on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/vulhub-vulhub.svg)](https://hysenlabs.com/projects/vulhub-vulhub)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/vulhub-vulhub.svg)](https://hysenlabs.com/projects/vulhub-vulhub)

Was this useful?