OWASP Juice Shop: a deliberately vulnerable app for security training and tool testing
OWASP Juice Shop: Probably the most modern and sophisticated insecure web application.
At a glance
- What is it?
- Juice Shop is an intentionally insecure web application used for security training, awareness demos, CTFs and as a target for scanners. This article covers how to install and run it, what it gives you, and where it stops being the right tool.
- Who is it for?
- Adopt Juice Shop if you need a legal, self-hosted target for security training, a CTF, or a scanner smoke test, and you want the whole OWASP Top Ten represented in one application. Do not adopt it as a reference for how to build a secure Node.js service, and do not point it at anything you care about: it is insecure by design and its own README warns against using the public demo instance for your own hacking.
- 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 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Juice Shop is for, and who it is aimed at
Juice Shop is an intentionally broken online shop. The README describes it as an insecure web application that can be used in security trainings, awareness demos, CTFs and as a guinea pig for security tools, and states that it encompasses vulnerabilities from the entire OWASP Top Ten along with many other security flaws found in real-world applications. That sentence is the whole product definition: the bugs are the feature.
The audience follows from that. Application security trainers who need a target that behaves like a real shop rather than a toy login form. Teams running internal capture-the-flag events who want a scoring board without building one. Tool vendors and engineers evaluating a scanner, proxy or fuzzer who need a target that is guaranteed to contain a known set of flaws. Developers who want to practise exploitation against something they are allowed to break.
It is not a hardening guide and not a starter template. Nothing in the repository is meant to be copied into a production service, and the package.json marks the package as private. If you want a shop, this is the wrong repository.
How the application is put together
The repository is a TypeScript Node.js application with an Angular frontend in frontend/. The server entry points are app.ts and server.ts at the top level, with routes/, models/, lib/ and data/ holding the request handlers, data models, shared code and the seed data for the shop. The Dockerfile builds the frontend first, then compiles the server with tsc into build/app.js, which is the command the container starts.
Two details matter for anyone running it. First, the application is stateful: the Dockerfile creates a logs directory and chowns it to uid 65532, and it sets group ownership and permissions on ftp/, frontend/dist/, logs/, data/ and i18n/ so the non-root user can write to them. Second, the image is built on a distroless Node.js base and runs as user 65532, so there is no shell inside the container to poke at. Persistence and debugging both have to be planned around that.
The repository also carries a swagger.yml, a threat-model.json, a monitoring/ directory and an ftp/ directory, which is a fair summary of the surface area: a documented API, a threat model for the application itself, and deliberately exposed services. The README points to the official project page for a full architecture overview, and that is where the detail lives rather than in the repository readme.
Installing Juice Shop from sources or Docker
The README gives four setup paths: from sources, packaged distributions, a Docker container, and Vagrant. The Docker route is the shortest and the one most people should start with, because it avoids the Node.js version question entirely.
Pull the image and run it bound to localhost only. The README's own command uses --rm and maps port 3000 on 127.0.0.1:
docker pull bkimminich/juice-shop
docker run --rm -p 127.0.0.1:3000:3000 bkimminich/juice-shopBrowse to http://localhost:3000 and the shop frontend loads. On macOS and Windows the README notes that if you are using docker-machine rather than the native Docker installation, you should browse to http://192.168.99.100:3000 instead.
The source route is four commands after you have a supported Node.js installed. The README's steps are:
git clone https://github.com/juice-shop/juice-shop.git --depth 1
cd juice-shop
npm install
npm startnpm install only has to be run before the first start or when you change the source code. Note that the postinstall script in package.json installs the frontend dependencies and builds the frontend, so the first install is not a quick one. The packaged distributions work differently: you download juice-shop-<version>_<node-version>_<os>_x64.zip or .tgz from the latest release, unpack it, and run npm start. The README warns that each packaged distribution includes binaries for sqlite3 and libxmljs2 bound to the operating system and Node.js version that npm install was executed on, which is the reason those archives are split per OS and per Node version rather than shipped as one file.
The demo instance and what it is not for
The README links to a public demo at http://demo.owasp-juice.shop, and immediately qualifies it. The wording is blunt: it is a deployment-test and sneak-peek instance only, you are not supposed to use it for your own hacking endeavours, there is no guaranteed uptime, and there are guaranteed stern looks if you break it.
That qualification is worth taking literally. If you are running a training session, a CTF or a scanner comparison, run your own instance. The demo is shared, so any state you create is visible to other people and any state they create is visible to you. The scoreboard, progress and any uploaded files are not yours. For a quick look at the UI before you commit to an install, it is fine. For anything that produces findings you intend to report, it is not.
The same logic applies to the challenge progress stored in your own instance: if you are using it for a class, decide up front whether you want a fresh database per student or a shared one, because the shop keeps state and the Dockerfile's permission fixes exist precisely because the app writes to disk.
Node.js version compatibility is a real constraint
The README carries a compatibility table mapping Node.js major versions to supported, tested, packaged distributions and Docker image tags. In the visible portion of that table, 26.x and 24.x are both marked supported and tested, 25.x is marked as supported in parentheses but not tested, and 23.x is marked unsupported. The Docker images are tagged latest from master and snapshot from develop, published for linux/amd64 and linux/arm64, and the packaged distributions for Node 24.x cover Windows x64, MacOS x64 and Linux x64.
The practical consequence: if you install from source on an odd-numbered or older Node.js release, you are outside what the project says it supports, and the failure will most likely appear in the native modules rather than in the TypeScript. That is also why the packaged distributions are pinned to a Node version. If you need a specific Node.js version for other reasons, the Docker image is the cleaner choice because the base image pins it for you.
The README also notes that some challenges require an AI/LLM provider to work properly, and points to a separate document on setting up external dependencies for configuring local or cloud-based AI providers. If your training plan includes those challenges, budget time for that configuration; the repository readme does not spell it out.
Where Juice Shop is the wrong tool
The most common misuse is treating it as a secure coding reference. It is the opposite. Every route, model and piece of seed data in this repository exists to be attacked, and the threat-model.json and the deliberately exposed ftp/ directory are part of the exercise rather than oversights. Reading the code to learn how to structure authentication or file upload handling will teach you the wrong lesson.
A second limit is scoring. The project ships a scoreboard and a CTF mode, but the README does not document rollback, per-user reset or how to isolate one trainee's progress from another's. If you need strict per-student state, you are looking at running one instance per student, which changes your infrastructure plan from a single container to a fleet.
A third is that it is a web application. If your team works on mobile clients, embedded systems, network protocols or cloud infrastructure, the OWASP Top Ten coverage here will not map onto your stack, and the time spent learning the shop's quirks buys you nothing transferable. Juice Shop is a target, not a curriculum, and it assumes you already know what you want to practise.
Alternatives and how they differ
The obvious comparison is OWASP WebGoat, the other long-running deliberately insecure teaching application in the OWASP family. The difference in approach is structural rather than cosmetic. WebGoat is organised as a set of lessons: you work through numbered exercises, each tied to a specific vulnerability class, with the lesson text next to the exercise. Juice Shop is organised as an application: you get a shop with a scoreboard and a list of challenges, and you have to find the flaws yourself, with no in-page explanation of what you are supposed to be looking for.
That makes WebGoat the better choice for a self-paced learner who needs the concept explained before the exercise, and Juice Shop the better choice for a CTF, a tool test, or a trainer who will supply the explanation. Juice Shop's second advantage is that it is a single coherent application with a REST API documented in swagger.yml, which makes it usable as a target for automated scanning and API testing in a way that a collection of isolated lessons is not.
If your goal is specifically to test a scanner, the relevant alternative is not another teaching app but a purpose-built benchmark with a known ground truth. Juice Shop gives you a target with many flaws; it does not give you a labelled list of exactly which flaws a scanner should have found, so scoring a tool against it requires you to build that list yourself.
Licence, maintenance and upgrade cost
Juice Shop is MIT licensed, both in package.json and in the container image labels, and the repository carries a LICENSE file at the top level. MIT is permissive: you can run it internally, package it into a training environment, and modify it. The one thing the licence does not resolve is the content question. The repository also contains a SOLUTIONS.md and a ctf.key, and if you fork the project for a corporate CTF you need to decide whether those files stay in your fork. That is a decision about your event, not a legal question, and it is worth making before you push the fork anywhere.
On maintenance, the last push to the default branch was on 2026-08-10, matching the v20.2.0 release on the same date. The previous releases, v20.1.0 and v20.1.1, both landed on 2026-06-23. So the project ships in bursts tied to releases rather than continuously, and upgrades should be planned against release tags rather than against the branch.
The upgrade cost is low if you use the Docker image, because the Node.js version and the native sqlite3 and libxmljs2 binaries are handled inside the image. It is higher if you run from sources or from a packaged distribution, because those binaries are bound to the OS and Node.js version that npm install ran on, and the compatibility table is the document you have to check each time you move to a new Node.js major.
Editorial conclusion
Adopt Juice Shop if you need a legal, self-hosted target for security training, a CTF, or a scanner smoke test, and you want the whole OWASP Top Ten represented in one application. Do not adopt it as a reference for how to build a secure Node.js service, and do not point it at anything you care about: it is insecure by design and its own README warns against using the public demo instance for your own hacking. Before you commit, verify the Node.js version against the compatibility table, confirm where the Docker image and packaged releases for your platform come from, and check whether the challenges you plan to run need an external AI/LLM provider. The container runs as user 65532 and exposes port 3000, so a first smoke test is a single docker run against 127.0.0.1.
Frequently asked questions
What is OWASP Juice Shop in cyber security?
It is a deliberately insecure web application maintained by OWASP, used for security trainings, awareness demos, CTFs and as a target for security tools. According to the README, it contains vulnerabilities from the entire OWASP Top Ten plus many other flaws found in real-world applications.
How do I install OWASP Juice Shop?
The README lists four routes: from sources with git clone and npm install followed by npm start, from a packaged distribution downloaded from the latest release, from the Docker image bkimminich/juice-shop, or via Vagrant. All of them end with the app listening on port 3000.
How do I run OWASP Juice Shop with Docker?
Pull the image with docker pull bkimminich/juice-shop, then run docker run --rm -p 127.0.0.1:3000:3000 bkimminich/juice-shop and browse to http://localhost:3000. The README notes that on macOS and Windows with docker-machine you should use http://192.168.99.100:3000 instead.
How do I access the OWASP Juice Shop scoreboard?
The README does not document a scoreboard URL. The visible documentation covers setup, the demo instance, Node.js version compatibility and troubleshooting, and points to the official project page and companion guide for the full feature list, so the scoreboard route is something to confirm there rather than in the repository readme.
How do I set up OWASP Juice Shop on Linux?
The README's source route works on Linux: clone the repository with git clone https://github.com/juice-shop/juice-shop.git --depth 1, run npm install, then npm start, and browse to http://localhost:3000. The packaged distribution for Node 24.x is published for Linux x64, and the Docker images cover linux/amd64 and linux/arm64.
Official sources
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.
[](https://hysenlabs.com/projects/juice-shop-juice-shop)