OWASP Juice Shop 是目前安全社区中使用最广泛的 Web 漏洞靶场之一,它模拟了一个功能完整的在线果汁商店,内置了从 OWASP Top 10 经典漏洞到业务逻辑缺陷的近百个挑战关卡。与 DVWA 这类偏重单一漏洞类型的靶场不同,Juice Shop 采用 Node.js、Express 和 Angular 构建的前后端分离架构,更贴近真实电商平台的业务场景,因此特别适合用来练习漏洞验证、编写复现记录,以及检验防护设备或代码审计规则的有效性。
对于安全从业者、开发者和运维人员来说,把 Juice Shop 部署在本机隔离环境中,意味着你拥有一个完全可控、可随时重置的实验沙箱。你可以在这个环境里放心地执行 SQL 注入、XSS payload 探测、越权访问尝试等操作,而不用担心影响任何真实业务。更重要的是,通过规范的部署、验证和清理流程,你能把一次简单的“装个靶场”升级为可复核、可回滚的安全实验工作流,这对于团队培训、漏洞报告撰写和个人技能沉淀都很有价值。
部署前的准备与授权边界
在开始之前,先明确一个基本原则:Juice Shop 只能用于你有明确授权或完全自有的实验环境。它不适合部署在公网服务器上供人随意访问,也不应作为扫描真实站点的跳板。本地部署时,建议使用 Docker 容器进行隔离,这样既能快速启动和销毁,也能避免在宿主机上遗留不必要的依赖和文件。
部署前需要确认以下前提条件:
- 已安装 Docker Engine(linux)或 Docker Desktop(Windows / macOS),并确保 Docker 守护进程正常运行。
- 本机 3000 端口未被占用,或者你愿意修改端口映射。
- 有稳定的网络连接用于拉取镜像,镜像体积约在 1GB 左右。
如果你使用的是 macOS(包括 Apple Silicon 芯片)或 Windows,Docker Desktop 已经包含了容器运行时和 Compose 插件,无需额外安装。linux 用户则需要确保 docker-compose 插件可用,较新版本的 Docker Engine 已原生支持 docker compose 子命令。
最小运行示例:一条命令启动靶场
Juice Shop 官方提供了预构建的 Docker 镜像,这是最快、最不容易出错的部署方式。打开终端,执行以下命令即可完成拉取和启动:
docker run -d --name juice-shop -p 3000:3000 bkimminich/juice-shop
命令参数说明:
-d:后台运行容器,避免终端被日志刷屏。--name juice-shop:为容器指定名称,后续停止、删除时可以直接引用。-p 3000:3000:将宿主机的 3000 端口映射到容器内的 3000 端口。
启动后,在浏览器中访问 http://localhost:3000,你应该能看到 Juice Shop 的商店首页。右上角的“账户”菜单可以注册新用户,而底部的“Score Board”链接则指向挑战进度面板——这是你后续验证漏洞是否利用成功的主要依据。
如果希望使用 Docker Compose 管理(便于后续扩展配置),可以创建一个 docker-compose.yml 文件:
services:
juice-shop:
image: bkimminich/juice-shop
container_name: juice-shop
ports:
- "3000:3000"
restart: unless-stopped
然后在同一目录下执行 docker compose up -d 即可。这种方式的好处是配置可版本化,方便团队共享统一的实验环境。
验证靶场可用性:从访问到确认漏洞响应
仅仅看到页面加载出来还不够,你需要确认靶场确实处于“可被攻击”的状态,并且漏洞响应符合预期。这可以通过几个快速检查来完成:
检查容器运行状态。 执行 docker ps,确认 juice-shop 容器的状态为 Up,端口映射显示 0.0.0.0:3000->3000/tcp。
验证 HTTP 响应。 使用 curl 检查首页响应码和关键内容:
curl -I http://localhost:3000
正常应返回 200 OK,且响应头中包含 X-Powered-By: Express 之类的信息。你也可以用 curl http://localhost:3000/rest/products/search?q=apple 测试 API 接口是否响应 JSON 数据。
确认漏洞入口存在。 Juice Shop 的搜索框是一个典型的 SQL 注入测试点。在搜索框中输入 '(单引号),如果页面出现数据库错误信息或异常行为,说明注入点处于活跃状态。另一个更直观的验证方式是直接访问 Score Board 页面(通常位于 /#/score-board),确认挑战列表能够正常加载。
这些检查的意义在于:你不仅确认了服务在运行,还确认了漏洞确实可以被触发。这为后续的复现记录提供了“基线证据”——你知道环境是正常工作的,那么后续的验证结果才具有可信度。
数据隔离与实验记录留存
在靶场环境中,你可能会进行多次尝试,产生注册用户、订单数据、上传文件等各类“脏数据”。为了避免实验之间相互干扰,需要理解 Juice Shop 的数据存储方式,并建立合适的隔离策略。
Juice Shop 默认使用 SQLite 数据库,数据文件存放在容器内的 /juice-shop/data/juice-shop.sqlite。默认情况下,容器停止后数据仍然保留在容器可写层中,但一旦你删除容器(docker rm),所有数据将随之消失。这其实是一个不错的特性:每次重新创建容器,你就获得了一个全新的靶场环境。
如果你希望保留某些实验数据(例如已经解锁的挑战进度),可以采用数据卷或主机目录挂载的方式:
docker run -d --name juice-shop -p 3000:3000 -v $(pwd)/juice-data:/juice-shop/data bkimminich/juice-shop
这样数据库文件会持久化到宿主机的 ./juice-data 目录。需要注意的是,如果你在多个实验之间共享同一份数据,后续实验可能会受到前一次实验遗留状态的影响。因此,建议按实验主题或日期分别创建不同的数据目录,例如 ./experiments/2025-06-sqli。
关于实验记录,建议采用以下工作流:
- 每次实验前,记录环境指纹(容器 ID、镜像版本、启动时间)。
- 执行漏洞验证时,保存完整的请求报文和响应报文,可以使用 Burp Suite 或
curl -v输出。 - 验证成功后,截图 Score Board 上对应挑战变为“已解决”的状态,作为证据留存。
- 将复现步骤、关键 payload 和结果写入 Markdown 文件,与实验数据目录放在一起。
这套流程看似繁琐,但当你需要向团队汇报漏洞验证结果,或者回溯某个漏洞的利用条件时,规范化的记录能节省大量时间。
常见启动故障与排查方法
即使是最简单的 Docker 部署,也可能遇到环境差异导致的问题。以下是几个高频故障及对应的排查思路:
端口被占用。 如果启动时提示 port is already allocated,说明 3000 端口已被其他进程占用。可以先执行 lsof -i :3000(macOS/Linux)或 netstat -ano | findstr :3000(Windows)查找占用进程,然后更换映射端口,例如 -p 3001:3000。
镜像拉取缓慢或超时。 这通常与网络环境有关。可以配置 Docker 镜像加速器(国内用户常用),或者尝试更换网络后重试。如果多次拉取失败,也可以考虑从源码构建,但耗时更长,不推荐作为首选方案。
容器启动后立即退出。 执行 docker logs juice-shop 查看日志。常见原因包括:镜像与宿主机 CPU 架构不兼容(老旧镜像在 ARM 平台上可能出现)、内存不足、或者容器内端口配置异常。对于 Apple Silicon 用户,建议拉取最新版本的镜像,旧版本可能未提供 ARM64 构建。
页面能打开但接口报错。 如果首页正常但 API 请求返回 500,可能是数据库初始化失败。删除容器并重新创建(不挂载数据卷)通常可以解决。如果使用了自定义数据卷,检查目录权限是否允许容器内用户写入。
访问速度极慢。 首次启动时应用需要完成数据库初始化和静态资源编译,通常需要 30 秒到一分钟。如果持续缓慢,可以检查宿主机资源占用情况,并确认 Docker 分配的内存是否充足(Docker Desktop 默认 2GB,建议调整为 4GB 以上)。
停止、清理与恢复:让实验环境可回滚
实验结束后,合理的清理操作能避免资源占用和潜在的安全风险。以下命令按需使用:
# 停止容器(保留容器和数据)
docker stop juice-shop
# 启动已停止的容器
docker start juice-shop
# 删除容器(数据将丢失,除非使用了数据卷)
docker rm juice-shop
# 删除容器并清理数据卷
docker rm -v juice-shop
# 删除镜像(释放磁盘空间)
docker rmi bkimminich/juice-shop
如果你使用了 Docker Compose,可以在项目目录下执行 docker compose down 停止并删除容器,docker compose down -v 会同时删除数据卷。
恢复环境时,有两种路径:如果你保留了数据卷,重新执行 docker run 命令并挂载相同的数据卷,即可恢复到上次实验结束时的状态;如果你希望从零开始,直接删除旧容器并重新创建即可。
需要特别提醒的是:Juice Shop 的容器默认以非 root 用户运行(官方镜像已做安全加固),但如果你在挂载主机目录时设置了不恰当的权限,仍可能带来文件权限风险。建议数据目录的属主与容器内运行用户 UID 保持一致,或者使用 Docker 命名卷(docker volume create)来避免权限问题。
从靶场到工作流:把实验沉淀为能力
部署 Juice Shop 只是第一步,真正有价值的是如何把它纳入你的日常安全实践。一个推荐的用法是:在每次代码评审或上线前,针对新发现的漏洞类型,先在 Juice Shop 中找到对应的挑战进行验证,确认漏洞的触发条件和影响范围,再回到自己的代码中检查是否存在类似问题。这种“先验证、后排查”的方式,比直接阅读漏洞描述要直观得多。
对于团队培训场景,可以结合 Score Board 的挑战难度分级,设计从易到难的练习路径。Juice Shop 的挑战覆盖了注入、认证失效、敏感数据泄露、越权、XSS 等 OWASP Top 10 主要类别,每个挑战都有对应的提示和官方解决方案文档(位于 https://pwning.owasp-juice.shop/),方便学员自学和复盘。
最后,记得定期更新镜像以获取最新的漏洞场景和修复。Juice Shop 项目保持活跃维护,新版本会引入新的挑战类型和功能模块。更新时,先停止并删除旧容器,然后 docker pull bkimminich/juice-shop 拉取最新镜像,再重新创建容器即可。由于默认数据不持久化,更新通常不会带来兼容性问题。
把靶场当作一个可重复、可验证、可回滚的实验基础设施来管理,你获得的将不仅仅是一个练习工具,而是一套支撑安全能力持续提升的方法论。

甘肃省 1F
用 Docker 装确实方便,一条命令就起来了
上海市崇明县 B1
@ 纸人司命 确实,比手动装环境省太多事了
重庆市 2F
自己搭过一次,验证完之后容器删掉就干净了
广东省深圳市 3F
拉镜像总是超时,国内网络太折腾了
重庆市 B1
@ 月光猫 我都是提前配好镜像加速器再拉,会快不少
广东省深圳市 B1
@ 月光猫 配合镜像加速器会好点,或者干脆挂代理拉
广东省深圳市 4F
那个 Score Board 解锁的时候特别有成就感
山东省烟台市 5F
端口冲突太真实了,上次就栽在这上面
甘肃省 B1
@ 元素之怒 换端口前先看下谁占用了,省得白折腾
山东省烟台市 6F
相当于一个本地练手的模拟器,适合新手先试手
重庆市 B1
@ 镜中星 新手确实友好,踩坑成本低,随便试都不心疼
重庆市 7F
如果能按 Web 漏洞类型分得再细一点就好了
广东省深圳市 8F
之前用 DVWA 练过,对比下来这个更像真实业务场景
广东省深圳市 9F
Docker 加数据卷,实验完直接删掉重来,太省心了
甘肃省 10F
这个镜像体积有点大,第一次拉的时候等了好久
山东省烟台市 11F
准备拿它练越权那块,正好缺个真实点的场景
重庆市 12F
用数据卷按日期分开存,复盘的时候好找
重庆市 B1
@ 青柠微酸 我都是按实验主题建目录,日期放文件名里
广东省深圳市 13F
curl 验证那步挺实用,能确认漏洞真能触发
山东省烟台市 14F
清理命令写得很全,省得自己一个个查
广东省深圳市 15F
容器删了数据就没了,这个特性反而省心
广东省深圳市福田区 16F
希望多来点业务逻辑漏洞的案例
重庆市 17F
团队培训按难度分级排确实好安排
山东省烟台市 18F
新手问一下,这个对电脑配置要求高吗
广东省深圳市 19F
玩到后面挑战难度跨度挺大的,容易卡关
重庆市 20F
准备先照着官方文档把环境跑通再说
山东省烟台市 21F
有没有人试过把 juice-shop 接进 CI 里做自动化验证
上海市 22F
Docker Desktop 内存默认2G,跑这个够不够用
重庆市 23F
用 Compose 管理之后,团队环境统一多了
广东省深圳市 24F
之前一直在找能练越权的地方,这个算是比较全的
甘肃省 25F
想看看有没有人整理过挑战的详细解法
山东省烟台市 26F
现在更新镜像也会定时去拉一下,反正删了重来不心疼