diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 557a2577d7e..24e29c16786 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: steps: - name: "Check out Git repository" uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f #v2: v2.3.4 available - - name: "Use Node.js 16" + - name: "Use Node.js 18" uses: actions/setup-node@f1f314fca9dfce2769ece7d933488f076716723e #v1: v2.x available with: node-version: 18 @@ -57,7 +57,7 @@ jobs: steps: - name: "Check out Git repository" uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f #v2: v2.3.4 available - - name: "Use Node.js 16" + - name: "Use Node.js 18" uses: actions/setup-node@f1f314fca9dfce2769ece7d933488f076716723e #v1: v2.x available with: node-version: 18 @@ -72,7 +72,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - node-version: [14, 16, 18, 19] + node-version: [16, 18, 20] steps: - name: "Check out Git repository" if: github.repository == 'juice-shop/juice-shop' || github.repository != 'juice-shop/juice-shop' && matrix.os == 'ubuntu-latest' && matrix.node-version == '16' @@ -112,7 +112,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - node-version: [14, 16, 18, 19] + node-version: [16, 18, 20] steps: - name: "Check out Git repository" if: github.repository == 'juice-shop/juice-shop' || github.repository != 'juice-shop/juice-shop' && matrix.os == 'ubuntu-latest' && matrix.node-version == '16' @@ -184,7 +184,7 @@ jobs: steps: - name: "Check out Git repository" uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f #v2: v2.3.4 available - - name: "Use Node.js 16" + - name: "Use Node.js 18" uses: actions/setup-node@f1f314fca9dfce2769ece7d933488f076716723e #v1: v2.x available with: node-version: 18 @@ -220,7 +220,7 @@ jobs: steps: - name: "Check out Git repository" uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f #v2: v2.3.4 available - - name: "Use Node.js 16" + - name: "Use Node.js 18" uses: actions/setup-node@f1f314fca9dfce2769ece7d933488f076716723e #v1: v2.x available with: node-version: 18 @@ -261,7 +261,7 @@ jobs: steps: - name: "Check out Git repository" uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f #v2: v2.3.4 available - - name: "Use Node.js 16" + - name: "Use Node.js 18" uses: actions/setup-node@f1f314fca9dfce2769ece7d933488f076716723e #v1: v2.x available with: node-version: 18 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2b842077222..7e79dd9a7b6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - node-version: [14, 16, 18] + node-version: [16, 18, 20] steps: - name: "Check out Git repository" uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f #v2: v2.3.4 available diff --git a/Dockerfile b/Dockerfile index 10f8c04bbb6..69c555827b1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,7 @@ LABEL maintainer="Bjoern Kimminich " \ org.opencontainers.image.vendor="Open Web Application Security Project" \ org.opencontainers.image.documentation="https://help.owasp-juice.shop" \ org.opencontainers.image.licenses="MIT" \ - org.opencontainers.image.version="14.5.1" \ + org.opencontainers.image.version="15.0.0" \ org.opencontainers.image.url="https://owasp-juice.shop" \ org.opencontainers.image.source="https://github.com/juice-shop/juice-shop" \ org.opencontainers.image.revision=$VCS_REF \ diff --git a/HALL_OF_FAME.md b/HALL_OF_FAME.md index b7dbfb81ee0..94669264fca 100644 --- a/HALL_OF_FAME.md +++ b/HALL_OF_FAME.md @@ -11,7 +11,7 @@ ## GitHub Contributors -As reported by [`git-stats -a -s '2014'`](https://www.npmjs.com/package/git-stats) analysis of `master` as of Tue, 14 Feb +As reported by [`git-stats -a -s '2014'`](https://www.npmjs.com/package/git-stats) analysis of `master` as of Fri, 19 May 2023 after deduplication with `.mailmap`. ![Top git contributors](screenshots/git-stats.png) @@ -63,12 +63,6 @@ Giovanni (cruzgio), Alexander Nissen (Nissen96), fabrizio1979, OrNol (TRNSRL), J of [@SecureState](https://github.com/SecureState)) * Wallpaper artworks by Mike Branscum (courtesy of [@daylightstudio](https://github.com/daylightstudio)) -* [Pwning OWASP Juice Shop](https://leanpub.com/juice-shop) cover artwork - by [Patch Kroll](https://99designs.de/profiles/3099878) -* [Banner](https://github.com/OWASP/owasp-swag/tree/master/projects/juice-shop/banners) - and - [flyer](https://github.com/OWASP/owasp-swag/tree/master/projects/juice-shop/flyers) - artwork by [logicainfo](https://99designs.de/profiles/logicainfo) * Official [OWASP Juice Shop Jingle](https://soundcloud.com/braimee/owasp-juice-shop-jingle) written and performed by [Brian Johnson](https://github.com/braimee) @@ -77,6 +71,15 @@ Giovanni (cruzgio), Alexander Nissen (Nissen96), fabrizio1979, OrNol (TRNSRL), J * Admin profile picture artworks by Kharisma Mulyana (courtesy of [Timo Pagel](https://github.com/wurstbrot/)) +Additional thanks goes to the contractors we were able to hire for specific work packages over the years with OWASP funding: + +* [Pwning OWASP Juice Shop](https://leanpub.com/juice-shop) cover artwork + by [Patch Kroll](https://99designs.de/profiles/3099878) +* [Banner](https://github.com/OWASP/owasp-swag/tree/master/projects/juice-shop/banners) + and + [flyer](https://github.com/OWASP/owasp-swag/tree/master/projects/juice-shop/flyers) + artwork by [logicainfo](https://99designs.de/profiles/logicainfo) + ## Stargazers (over time) [![Stargazers over time](https://starchart.cc/juice-shop/juice-shop.svg)](https://starchart.cc/juice-shop/juice-shop) diff --git a/README.md b/README.md index 0c773168dbf..408174dd00d 100644 --- a/README.md +++ b/README.md @@ -216,9 +216,7 @@ offered accordingly. | 18.x | :heavy_check_mark: | :heavy_check_mark: | Windows (`x64`), MacOS (`x64`), Linux (`x64`) | `latest` (`linux/amd64`, `linux/arm64`) | `snapshot` (`linux/amd64`, `linux/arm64`) | | 17.x | (:heavy_check_mark:) | :x: | | | | | 16.x | :heavy_check_mark: | :heavy_check_mark: | Windows (`x64`), MacOS (`x64`), Linux (`x64`) | | | -| 15.x | (:heavy_check_mark:) | :x: | | | | -| 14.x | :heavy_check_mark: | :heavy_check_mark: | Windows (`x64`), MacOS (`x64`), Linux (`x64`) | | ` | -| <14.x | :x: | :x: | | | | +| <16.x | :x: | :x: | | | | Juice Shop is automatically tested _only on the latest `.x` minor version_ of each node.js version mentioned above! There is no guarantee that older minor node.js releases will always work with Juice Shop! diff --git a/REFERENCES.md b/REFERENCES.md index 720f9a666aa..f4716eaeb62 100644 --- a/REFERENCES.md +++ b/REFERENCES.md @@ -11,6 +11,26 @@ mentioned or used! > tackling these challenges yourself! :mega: marks short friendly shout > outs. Finally, the :dollar: bill marks commercial resources. +## Table of contents + +* [Awards](#awards--trophy-) +* [Web Links](#web-links) + + [Pod- & Webcasts](#pod---webcasts) + + [Blogs & Articles](#blogs--articles) +* [Lectures and Trainings](#lectures-and-trainings) +* [Summits & Open Source Events](#summits--open-source-events) + + [Google Summer of Code](#googlesummerofcode) +* [Conference and Meetup Appearances](#conference-and-meetup-appearances) + - [2023](#2023) + - [2022](#2022) + - [2021](#2021) + - [2020](#2020) + - [2019](#2019) + - [2018](#2018) + - [2017](#2017) + - [2016](#2016) + - [2015](#2015) + ## Awards :trophy: * [Heroku Button of the Month](https://hello.heroku.com/webmail/36622/679286305/8049a634b1a01b0aa75c0966325856dc9a463b7f1beeb6a2f32cbb30248b5bc6) @@ -280,11 +300,16 @@ mentioned or used! ## Conference and Meetup Appearances +> Upcoming events are marked with :date:. The availability of link destinations for past events cannot be guaranteed. + #### 2023 -* [Squeezing the last drop out of OWASP Juice Shop](https://owasp2023globalappsecdublin.sched.com/event/1FWfq/squeezing-the-last-drop-out-of-owasp-juice-shop) by Björn Kimminich, [OWASP 2023 Global AppSec Dublin](https://dublin.globalappsec.org/), 15.02.2023 [YouTube](https://youtu.be/m1f2fPC8hLU) +* :date: [Track keynote: OWASP Juice Shop](https://sikkerhetsfestivalen.no/program-2023) by Björn Kimminich, [Sikkerhetsfestivalen 2023](https://sikkerhetsfestivalen.no/). 29.08.2023 +* :date: [Juice Shop Update³](https://god.owasp.de/2023/schedule/index.html) by Björn Kimminich, [German OWASP Day 2023](https://god.owasp.de/2023). 31.05.2023 +* :date: [Juice Shop Training: Train the Trainer Edition](https://god.owasp.de/2023/schedule/index.html) with Björn Kimminich, [German OWASP Day 2023](https://god.owasp.de/2023). 30.05.2023 * [OWASP Juice Shop](https://www.meetup.com/owasp-chapter-netherlands-meetup/events/292323208) - by Björn Kimminich, [April 2023 OWASP Chapter Netherlands Meetup](https://www.meetup.com/owasp-chapter-netherlands-meetup/), 20.04.2023 + by Björn Kimminich, [April 2023 OWASP Chapter Netherlands Meetup](https://www.meetup.com/owasp-chapter-netherlands-meetup/), 20.04.2023 [YouTube](https://www.youtube.com/live/Bhp3LpgtNZ4?feature=share&t=3856) +* [Squeezing the last drop out of OWASP Juice Shop](https://owasp2023globalappsecdublin.sched.com/event/1FWfq/squeezing-the-last-drop-out-of-owasp-juice-shop) by Björn Kimminich, [OWASP 2023 Global AppSec Dublin](https://dublin.globalappsec.org/), 15.02.2023 [YouTube](https://youtu.be/m1f2fPC8hLU) #### 2022 @@ -553,3 +578,6 @@ mentioned or used! by Björn Kimminich, [17. OWASP Stammtisch Hamburg](http://lanyrd.com/2015/owasp-de/), 27.01.2015 +## Usage in Tools & Products + +* [How to try GitHub Advanced Security with your team](https://resources.github.com/security/tools/ghas-trial/) uses Juice Shop as an example for CI/CD integration in [Code scanning in action with Juice Shop](https://resources.github.com/security/tools/ghas-trial/#code-scanning-in-action-with-juice-shop) diff --git a/SECURITY.md b/SECURITY.md index f50041ad35d..93728b40890 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -12,8 +12,8 @@ We provide security patches for the latest released minor version. | Version | Supported | |:--------|:-------------------| -| 14.5.x | :white_check_mark: | -| <14.5 | :x: | +| 15.0.x | :white_check_mark: | +| <15.0 | :x: | ## Reporting a Vulnerability diff --git a/SOLUTIONS.md b/SOLUTIONS.md index e1bcfb4c084..7045035a1ab 100644 --- a/SOLUTIONS.md +++ b/SOLUTIONS.md @@ -15,6 +15,12 @@ file and open a PR! The same goes for any scripts or automated tools you made fo > that a solution/script/tool is supposedly working with or that a video > guide/solution was recorded for. +## Table of contents + +* [Hacking Videos](#hacking-videos) +* [Walkthroughs](#walkthroughs) +* [Scripts & Tools](#scripts--tools) + ## Hacking Videos * [How to Solve Juiceshop Challenges - Intern Talks](https://www.youtube.com/watch?v=dqxdbIWFD5c) by [Indian Servers University](https://www.youtube.com/c/IndianServersUniversity) (🧃`v11.x`) @@ -140,7 +146,7 @@ file and open a PR! The same goes for any scripts or automated tools you made fo [7MS #229: Intro to Docker for Pentesters](https://7ms.us/7ms-229-intro-to-docker-for-pentesters/) ([Youtube](https://youtu.be/WIpxvBpnylI?t=407)) -### Walkthroughs +## Walkthroughs * Blog post (:myanmar:) on [LOL Security](http://location-href.com/): [Juice Shop Walkthrough](http://location-href.com/owasp-juice-shop-walkthroughs/) @@ -149,7 +155,7 @@ file and open a PR! The same goes for any scripts or automated tools you made fo [Hacking(and automating!) the OWASP Juice Shop](https://incognitjoe.github.io/hacking-the-juice-shop.html) (🧃`v2.x`) -### Scripts & Tools +## Scripts & Tools * [Session management script for OWASP Juice Shop](https://github.com/zaproxy/zaproxy/blob/master/zap/src/main/dist/scripts/templates/session/Juice%20Shop%20Session%20Management.js) distributed as a scripting template with diff --git a/config.schema.yml b/config.schema.yml index 73f67cd7c14..3e6e50c2dc5 100644 --- a/config.schema.yml +++ b/config.schema.yml @@ -106,8 +106,7 @@ application: clientId: type: string authorizedRedirects: - - - uri: + - uri: type: string proxy: type: string @@ -138,8 +137,7 @@ hackingInstructor: hintPlaybackSpeed: type: string products: - - - name: + - name: type: string price: type: number @@ -164,17 +162,14 @@ products: fileForRetrieveBlueprintChallenge: type: string exifForBlueprintChallenge: - - - type: string + - type: string reviews: - - - text: + - text: type: string author: type: string memories: - - - image: + - image: type: string caption: type: string @@ -699,3 +694,8 @@ ctf: type: string code: type: string + emptyUserRegistration: + name: + type: string + code: + type: string \ No newline at end of file diff --git a/config/fbctf.yml b/config/fbctf.yml index 729190ab808..304a2a06726 100644 --- a/config/fbctf.yml +++ b/config/fbctf.yml @@ -318,3 +318,6 @@ ctf: closeNotificationsChallenge: name: Zambia code: ZM + emptyUserRegistration: + name: Kenya + code: KE \ No newline at end of file diff --git a/data/datacreator.ts b/data/datacreator.ts index acb97fc90e9..aaa84c4b14c 100644 --- a/data/datacreator.ts +++ b/data/datacreator.ts @@ -21,15 +21,15 @@ import { SecurityQuestionModel } from '../models/securityQuestion' import { UserModel } from '../models/user' import { WalletModel } from '../models/wallet' import { Address, Card, Challenge, Delivery, Memory, Product, SecurityQuestion, User } from './types' +import logger from '../lib/logger' +import config from 'config' +import path from 'path' +import * as utils from '../lib/utils' const datacache = require('./datacache') -const config = require('config') -const utils = require('../lib/utils') const mongodb = require('./mongodb') const security = require('../lib/insecurity') -const logger = require('../lib/logger') const fs = require('fs') -const path = require('path') const util = require('util') const { safeLoad } = require('js-yaml') const Entities = require('html-entities').AllHtmlEntities @@ -93,7 +93,7 @@ async function createChallenges () { hint: showHints ? hint : null, hintUrl: showHints ? hintUrl : null, mitigationUrl: showMitigations ? mitigationUrl : null, - disabledEnv: config.get('challenges.safetyOverride') ? null : effectiveDisabledEnv, + disabledEnv: config.get('challenges.safetyOverride') ? null : effectiveDisabledEnv, tutorialOrder: tutorial ? tutorial.order : null, codingChallengeStatus: 0 }) @@ -236,7 +236,7 @@ async function createRandomFakeUsers () { async function createQuantity () { return await Promise.all( - config.get('products').map(async (product: Product, index: number) => { + config.get('products').map(async (product: Product, index: number) => { return await QuantityModel.create({ ProductId: index + 1, quantity: product.quantity !== undefined ? product.quantity : Math.floor(Math.random() * 70 + 30), @@ -262,7 +262,7 @@ async function createMemories () { if (utils.isUrl(memory.image)) { const imageUrl = memory.image tmpImageFileName = utils.extractFilename(memory.image) - utils.downloadToFile(imageUrl, 'frontend/dist/frontend/assets/public/images/uploads/' + tmpImageFileName) + void utils.downloadToFile(imageUrl, 'frontend/dist/frontend/assets/public/images/uploads/' + tmpImageFileName) } if (memory.geoStalkingMetaSecurityQuestion && memory.geoStalkingMetaSecurityAnswer) { await createSecurityAnswer(datacache.users.john.id, memory.geoStalkingMetaSecurityQuestion, memory.geoStalkingMetaSecurityAnswer) @@ -296,7 +296,7 @@ async function createProducts () { if (utils.isUrl(product.image)) { const imageUrl = product.image product.image = utils.extractFilename(product.image) - utils.downloadToFile(imageUrl, 'frontend/dist/frontend/assets/public/images/products/' + product.image) + void utils.downloadToFile(imageUrl, 'frontend/dist/frontend/assets/public/images/products/' + product.image) } return product }) @@ -607,7 +607,7 @@ async function createSecurityAnswer (UserId: number, SecurityQuestionId: number, } async function createOrders () { - const products = config.get('products') + const products = config.get('products') const basket1Products = [ { quantity: 3, diff --git a/data/static/challenges.yml b/data/static/challenges.yml index 1dd27c6f874..9f1b4a5228f 100644 --- a/data/static/challenges.yml +++ b/data/static/challenges.yml @@ -223,6 +223,15 @@ hintUrl: 'https://pwning.owasp-juice.shop/part2/sensitive-data-exposure.html#perform-an-unwanted-information-disclosure-by-accessing-data-cross-domain' mitigationUrl: ~ key: emailLeakChallenge +- + name: 'Empty User Registration' + category: 'Improper Input Validation' + description: 'Register a user with an empty email and password.' + difficulty: 2 + hint: 'Consider intercepting and playing with the request payload.' + hintUrl: https://pwning.owasp-juice.shop/part2/improper-input-validation.html#register-a-user-account-with-an-empty-email-and-password + mitigationUrl: ~ + key: emptyUserRegistration - name: 'Ephemeral Accountant' category: 'Injection' diff --git a/data/static/codefixes/exposedMetricsChallenge_1.ts b/data/static/codefixes/exposedMetricsChallenge_1.ts index 70975a5f510..9b825c485a3 100644 --- a/data/static/codefixes/exposedMetricsChallenge_1.ts +++ b/data/static/codefixes/exposedMetricsChallenge_1.ts @@ -18,10 +18,10 @@ export async function start (readyCallback: Function) { metricsUpdateLoop = Metrics.updateLoop() server.listen(port, () => { - logger.info(colors.cyan(`Server listening on port ${colors.bold(port)}`)) + logger.info(colors.cyan(`Server listening on port ${colors.bold(`${port}`)}`)) startupGauge.set({ task: 'ready' }, (Date.now() - startTime) / 1000) if (process.env.BASE_PATH !== '') { - logger.info(colors.cyan(`Server using proxy base path ${colors.bold(process.env.BASE_PATH)} for redirects`)) + logger.info(colors.cyan(`Server using proxy base path ${colors.bold(`${process.env.BASE_PATH}`)} for redirects`)) } registerWebsocketEvents(server) if (readyCallback) { diff --git a/data/static/codefixes/exposedMetricsChallenge_2.ts b/data/static/codefixes/exposedMetricsChallenge_2.ts index 31b781b9f61..2cb4fa2ee21 100644 --- a/data/static/codefixes/exposedMetricsChallenge_2.ts +++ b/data/static/codefixes/exposedMetricsChallenge_2.ts @@ -15,10 +15,10 @@ export async function start (readyCallback: Function) { process.env.BASE_PATH = process.env.BASE_PATH ?? config.get('server.basePath') server.listen(port, () => { - logger.info(colors.cyan(`Server listening on port ${colors.bold(port)}`)) + logger.info(colors.cyan(`Server listening on port ${colors.bold(`${port}`)}`)) startupGauge.set({ task: 'ready' }, (Date.now() - startTime) / 1000) if (process.env.BASE_PATH !== '') { - logger.info(colors.cyan(`Server using proxy base path ${colors.bold(process.env.BASE_PATH)} for redirects`)) + logger.info(colors.cyan(`Server using proxy base path ${colors.bold(`${process.env.BASE_PATH}`)} for redirects`)) } registerWebsocketEvents(server) if (readyCallback) { diff --git a/data/static/codefixes/exposedMetricsChallenge_3_correct.ts b/data/static/codefixes/exposedMetricsChallenge_3_correct.ts index 16cd7a22b46..e7ed765b18e 100644 --- a/data/static/codefixes/exposedMetricsChallenge_3_correct.ts +++ b/data/static/codefixes/exposedMetricsChallenge_3_correct.ts @@ -18,10 +18,10 @@ export async function start (readyCallback: Function) { metricsUpdateLoop = Metrics.updateLoop() server.listen(port, () => { - logger.info(colors.cyan(`Server listening on port ${colors.bold(port)}`)) + logger.info(colors.cyan(`Server listening on port ${colors.bold(`${port}`)}`)) startupGauge.set({ task: 'ready' }, (Date.now() - startTime) / 1000) if (process.env.BASE_PATH !== '') { - logger.info(colors.cyan(`Server using proxy base path ${colors.bold(process.env.BASE_PATH)} for redirects`)) + logger.info(colors.cyan(`Server using proxy base path ${colors.bold(`${process.env.BASE_PATH}`)} for redirects`)) } registerWebsocketEvents(server) if (readyCallback) { diff --git a/data/static/codefixes/redirectChallenge_1.ts b/data/static/codefixes/redirectChallenge_1.ts index 4a67fb11ee7..e9d83f4be08 100644 --- a/data/static/codefixes/redirectChallenge_1.ts +++ b/data/static/codefixes/redirectChallenge_1.ts @@ -1,4 +1,4 @@ -const redirectAllowlist = new Set([ +export const redirectAllowlist = new Set([ 'https://github.com/bkimminich/juice-shop', 'https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm', 'https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW', @@ -8,9 +8,8 @@ const redirectAllowlist = new Set([ 'https://www.stickeryou.com/products/owasp-juice-shop/794', 'http://leanpub.com/juice-shop' ]) -exports.redirectAllowlist = redirectAllowlist -exports.isRedirectAllowed = (url: string) => { +export const isRedirectAllowed = (url: string) => { let allowed = false for (const allowedUrl of redirectAllowlist) { allowed = allowed || url.includes(encodeURI(allowedUrl)) diff --git a/data/static/codefixes/redirectChallenge_2.ts b/data/static/codefixes/redirectChallenge_2.ts index 7491b8c622d..6c8e0c82d91 100644 --- a/data/static/codefixes/redirectChallenge_2.ts +++ b/data/static/codefixes/redirectChallenge_2.ts @@ -1,4 +1,4 @@ -const redirectAllowlist = new Set([ +export const redirectAllowlist = new Set([ 'https://github.com/bkimminich/juice-shop', 'https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm', 'https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW', @@ -8,9 +8,8 @@ const redirectAllowlist = new Set([ 'https://www.stickeryou.com/products/owasp-juice-shop/794', 'http://leanpub.com/juice-shop' ]) -exports.redirectAllowlist = redirectAllowlist -exports.isRedirectAllowed = (url: string) => { +export const isRedirectAllowed = (url: string) => { let allowed = false for (const allowedUrl of redirectAllowlist) { allowed = allowed && url.includes(allowedUrl) diff --git a/data/static/codefixes/redirectChallenge_3.ts b/data/static/codefixes/redirectChallenge_3.ts index c72e969c31a..d95aec73ab5 100644 --- a/data/static/codefixes/redirectChallenge_3.ts +++ b/data/static/codefixes/redirectChallenge_3.ts @@ -1,4 +1,4 @@ -const redirectAllowlist = new Set([ +export const redirectAllowlist = new Set([ 'https://github.com/bkimminich/juice-shop', 'https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm', 'https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW', @@ -8,9 +8,8 @@ const redirectAllowlist = new Set([ 'https://www.stickeryou.com/products/owasp-juice-shop/794', 'http://leanpub.com/juice-shop' ]) -exports.redirectAllowlist = redirectAllowlist -exports.isRedirectAllowed = (url: string) => { +export const isRedirectAllowed = (url: string) => { let allowed = false for (const allowedUrl of redirectAllowlist) { allowed = allowed || url.includes(escapeHTML(allowedUrl)) diff --git a/data/static/codefixes/redirectChallenge_4_correct.ts b/data/static/codefixes/redirectChallenge_4_correct.ts index dfb43a5637e..49a988a3c30 100644 --- a/data/static/codefixes/redirectChallenge_4_correct.ts +++ b/data/static/codefixes/redirectChallenge_4_correct.ts @@ -1,4 +1,4 @@ -const redirectAllowlist = new Set([ +export const redirectAllowlist = new Set([ 'https://github.com/bkimminich/juice-shop', 'https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm', 'https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW', @@ -8,9 +8,8 @@ const redirectAllowlist = new Set([ 'https://www.stickeryou.com/products/owasp-juice-shop/794', 'http://leanpub.com/juice-shop' ]) -exports.redirectAllowlist = redirectAllowlist -exports.isRedirectAllowed = (url: string) => { +export const isRedirectAllowed = (url: string) => { let allowed = false for (const allowedUrl of redirectAllowlist) { allowed = allowed || url === allowedUrl diff --git a/data/static/codefixes/redirectCryptoCurrencyChallenge_1.ts b/data/static/codefixes/redirectCryptoCurrencyChallenge_1.ts index 7c41ed8e336..0a013c95050 100644 --- a/data/static/codefixes/redirectCryptoCurrencyChallenge_1.ts +++ b/data/static/codefixes/redirectCryptoCurrencyChallenge_1.ts @@ -1,4 +1,4 @@ -const redirectAllowlist = new Set([ +export const redirectAllowlist = new Set([ 'https://github.com/bkimminich/juice-shop', 'https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW', 'https://etherscan.io/address/0x0f933ab9fcaaa782d0279c300d73750e1311eae6', @@ -7,9 +7,8 @@ const redirectAllowlist = new Set([ 'https://www.stickeryou.com/products/owasp-juice-shop/794', 'http://leanpub.com/juice-shop' ]) -exports.redirectAllowlist = redirectAllowlist -exports.isRedirectAllowed = (url: string) => { +export const isRedirectAllowed = (url: string) => { let allowed = false for (const allowedUrl of redirectAllowlist) { allowed = allowed || url.includes(allowedUrl) diff --git a/data/static/codefixes/redirectCryptoCurrencyChallenge_2.ts b/data/static/codefixes/redirectCryptoCurrencyChallenge_2.ts index 2101f393ecb..9f59837d5f0 100644 --- a/data/static/codefixes/redirectCryptoCurrencyChallenge_2.ts +++ b/data/static/codefixes/redirectCryptoCurrencyChallenge_2.ts @@ -1,4 +1,4 @@ -const redirectAllowlist = new Set([ +export const redirectAllowlist = new Set([ 'https://github.com/bkimminich/juice-shop', 'https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm', 'https://etherscan.io/address/0x0f933ab9fcaaa782d0279c300d73750e1311eae6', @@ -7,9 +7,8 @@ const redirectAllowlist = new Set([ 'https://www.stickeryou.com/products/owasp-juice-shop/794', 'http://leanpub.com/juice-shop' ]) -exports.redirectAllowlist = redirectAllowlist -exports.isRedirectAllowed = (url: string) => { +export const isRedirectAllowed = (url: string) => { let allowed = false for (const allowedUrl of redirectAllowlist) { allowed = allowed || url.includes(allowedUrl) diff --git a/data/static/codefixes/redirectCryptoCurrencyChallenge_3_correct.ts b/data/static/codefixes/redirectCryptoCurrencyChallenge_3_correct.ts index 7c6dbfbff19..71601c84694 100644 --- a/data/static/codefixes/redirectCryptoCurrencyChallenge_3_correct.ts +++ b/data/static/codefixes/redirectCryptoCurrencyChallenge_3_correct.ts @@ -1,13 +1,12 @@ -const redirectAllowlist = new Set([ +export const redirectAllowlist = new Set([ 'https://github.com/bkimminich/juice-shop', 'http://shop.spreadshirt.com/juiceshop', 'http://shop.spreadshirt.de/juiceshop', 'https://www.stickeryou.com/products/owasp-juice-shop/794', 'http://leanpub.com/juice-shop' ]) -exports.redirectAllowlist = redirectAllowlist -exports.isRedirectAllowed = (url: string) => { +export const isRedirectAllowed = (url: string) => { let allowed = false for (const allowedUrl of redirectAllowlist) { allowed = allowed || url.includes(allowedUrl) diff --git a/data/static/codefixes/redirectCryptoCurrencyChallenge_4.ts b/data/static/codefixes/redirectCryptoCurrencyChallenge_4.ts index 5150c77c03c..19fec507661 100644 --- a/data/static/codefixes/redirectCryptoCurrencyChallenge_4.ts +++ b/data/static/codefixes/redirectCryptoCurrencyChallenge_4.ts @@ -1,4 +1,4 @@ -const redirectAllowlist = new Set([ +export const redirectAllowlist = new Set([ 'https://github.com/bkimminich/juice-shop', 'https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm', 'https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW', @@ -7,9 +7,8 @@ const redirectAllowlist = new Set([ 'https://www.stickeryou.com/products/owasp-juice-shop/794', 'http://leanpub.com/juice-shop' ]) -exports.redirectAllowlist = redirectAllowlist -exports.isRedirectAllowed = (url: string) => { +export const isRedirectAllowed = (url: string) => { let allowed = false for (const allowedUrl of redirectAllowlist) { allowed = allowed || url.includes(allowedUrl) diff --git a/data/static/i18n/bn_BD.json b/data/static/i18n/bn_BD.json new file mode 100644 index 00000000000..22dc6bf17a6 --- /dev/null +++ b/data/static/i18n/bn_BD.json @@ -0,0 +1,456 @@ +{ + "Find the carefully hidden 'Score Board' page.": "Find the carefully hidden 'Score Board' page.", + "Try to find a reference or clue behind the scenes. Or simply guess what URL the Score Board might have.": "Try to find a reference or clue behind the scenes. Or simply guess what URL the Score Board might have.", + "Perform a persisted XSS attack with <iframe src=\"javascript:alert(`xss`)\"> without using the frontend application at all.": "Perform a persisted XSS attack with <iframe src=\"javascript:alert(`xss`)\"> without using the frontend application at all.", + "You need to work with the server-side API directly. Try different HTTP verbs on different entities exposed through the API.": "You need to work with the server-side API directly. Try different HTTP verbs on different entities exposed through the API.", + "Gain access to any access log file of the server.": "Gain access to any access log file of the server.", + "Who would want a server access log to be accessible through a web application?": "Who would want a server access log to be accessible through a web application?", + "Register as a user with administrator privileges.": "Register as a user with administrator privileges.", + "You have to assign the unassignable.": "You have to assign the unassignable.", + "Access the administration section of the store.": "Access the administration section of the store.", + "It is just slightly harder to find than the score board link.": "It is just slightly harder to find than the score board link.", + "Overwrite the Legal Information file.": "Overwrite the Legal Information file.", + "Look out for a tweet praising new functionality of the web shop. Then find a third party vulnerability associated with it.": "Look out for a tweet praising new functionality of the web shop. Then find a third party vulnerability associated with it.", + "Reset the password of Bjoern's OWASP account via the Forgot Password mechanism with the original answer to his security question.": "Reset the password of Bjoern's OWASP account via the Forgot Password mechanism with the original answer to his security question.", + "He might have spoilered it on at least one occasion where a camera was running. Maybe elsewhere as well.": "He might have spoilered it on at least one occasion where a camera was running. Maybe elsewhere as well.", + "Learn about the Token Sale before its official announcement.": "Learn about the Token Sale before its official announcement.", + "The developers truly believe in \"Security through Obscurity\" over actual access restrictions.": "The developers truly believe in \"Security through Obscurity\" over actual access restrictions.", + "Perform a Remote Code Execution that would keep a less hardened application busy forever.": "Perform a Remote Code Execution that would keep a less hardened application busy forever.", + "The feature you need to exploit for this challenge is not directly advertised anywhere.": "The feature you need to exploit for this challenge is not directly advertised anywhere.", + "Submit 10 or more customer feedbacks within 20 seconds.": "Submit 10 or more customer feedbacks within 20 seconds.", + "After finding a CAPTCHA bypass, write a script that automates feedback submission. Or open many browser tabs and be really quick.": "After finding a CAPTCHA bypass, write a script that automates feedback submission. Or open many browser tabs and be really quick.", + "Change Bender's password into slurmCl4ssic without using SQL Injection or Forgot Password.": "Change Bender's password into slurmCl4ssic without using SQL Injection or Forgot Password.", + "In previous releases this challenge was wrongly accused of being based on CSRF.": "In previous releases this challenge was wrongly accused of being based on CSRF.", + "Order the Christmas special offer of 2014.": "Order the Christmas special offer of 2014.", + "Find out how the application handles unavailable products and try to find a loophole.": "Find out how the application handles unavailable products and try to find a loophole.", + "Bypass the Content Security Policy and perform an XSS attack with <script>alert(`xss`)</script> on a legacy page within the application.": "Bypass the Content Security Policy and perform an XSS attack with <script>alert(`xss`)</script> on a legacy page within the application.", + "What is even \"better\" than a legacy page with a homegrown RegEx sanitizer? Having CSP injection issues on the exact same page as well!": "What is even \"better\" than a legacy page with a homegrown RegEx sanitizer? Having CSP injection issues on the exact same page as well!", + "Perform a persisted XSS attack with <iframe src=\"javascript:alert(`xss`)\"> bypassing a client-side security mechanism.": "Perform a persisted XSS attack with <iframe src=\"javascript:alert(`xss`)\"> bypassing a client-side security mechanism.", + "Only some input fields validate their input. Even less of these are persisted in a way where their content is shown on another screen.": "Only some input fields validate their input. Even less of these are persisted in a way where their content is shown on another screen.", + "Access a confidential document.": "Access a confidential document.", + "Analyze and tamper with links in the application that deliver a file directly.": "Analyze and tamper with links in the application that deliver a file directly.", + "Perform a DOM XSS attack with <iframe src=\"javascript:alert(`xss`)\">.": "Perform a DOM XSS attack with <iframe src=\"javascript:alert(`xss`)\">.", + "Look for an input field where its content appears in the HTML when its form is submitted.": "Look for an input field where its content appears in the HTML when its form is submitted.", + "Exfiltrate the entire DB schema definition via SQL Injection.": "Exfiltrate the entire DB schema definition via SQL Injection.", + "Find out where this information could come from. Then craft a UNION SELECT attack string against an endpoint that offers an unnecessary way to filter data.": "Find out where this information could come from. Then craft a UNION SELECT attack string against an endpoint that offers an unnecessary way to filter data.", + "Use a deprecated B2B interface that was not properly shut down.": "Use a deprecated B2B interface that was not properly shut down.", + "The developers who disabled the interface think they could go invisible by just closing their eyes.": "The developers who disabled the interface think they could go invisible by just closing their eyes.", + "Find the hidden easter egg.": "Find the hidden easter egg.", + "If you solved one of the three file access challenges, you already know where to find the easter egg.": "If you solved one of the three file access challenges, you already know where to find the easter egg.", + "Perform an unwanted information disclosure by accessing data cross-domain.": "Perform an unwanted information disclosure by accessing data cross-domain.", + "Try to find and attack an endpoint that responds with user information. SQL Injection is not the solution here.": "Try to find and attack an endpoint that responds with user information. SQL Injection is not the solution here.", + "Log in with the (non-existing) accountant acc0unt4nt@juice-sh.op without ever registering that user.": "Log in with the (non-existing) accountant acc0unt4nt@juice-sh.op without ever registering that user.", + "Try to create the needed user \"out of thin air\".": "Try to create the needed user \"out of thin air\".", + "Provoke an error that is neither very gracefully nor consistently handled.": "Provoke an error that is neither very gracefully nor consistently handled.", + "Try to submit bad input to forms. Alternatively tamper with URL paths or parameters.": "Try to submit bad input to forms. Alternatively tamper with URL paths or parameters.", + "Successfully redeem an expired campaign coupon code.": "Successfully redeem an expired campaign coupon code.", + "Try to identify past special event or holiday campaigns of the shop first.": "Try to identify past special event or holiday campaigns of the shop first.", + "Retrieve the language file that never made it into production.": "Retrieve the language file that never made it into production.", + "Brute force is not the only option for this challenge, but a perfectly viable one.": "Brute force is not the only option for this challenge, but a perfectly viable one.", + "Get rid of all 5-star customer feedback.": "Get rid of all 5-star customer feedback.", + "Once you found admin section of the application, this challenge is almost trivial.": "Once you found admin section of the application, this challenge is almost trivial.", + "Forge a coupon code that gives you a discount of at least 80%.": "Forge a coupon code that gives you a discount of at least 80%.", + "Try either a) a knowledgable brute force attack or b) reverse engineering or c) some research in the cloud.": "Try either a) a knowledgable brute force attack or b) reverse engineering or c) some research in the cloud.", + "Post some feedback in another user's name.": "Post some feedback in another user's name.", + "You can solve this by tampering with the user interface or by intercepting the communication with the RESTful backend.": "You can solve this by tampering with the user interface or by intercepting the communication with the RESTful backend.", + "Post a product review as another user or edit any user's existing review.": "Post a product review as another user or edit any user's existing review.", + "Observe the flow of product review posting and editing and see if you can exploit it.": "Observe the flow of product review posting and editing and see if you can exploit it.", + "Forge an almost properly RSA-signed JWT token that impersonates the (non-existing) user rsa_lord@juice-sh.op.": "Forge an almost properly RSA-signed JWT token that impersonates the (non-existing) user rsa_lord@juice-sh.op.", + "This challenge is explicitly not about acquiring the RSA private key used for JWT signing.": "This challenge is explicitly not about acquiring the RSA private key used for JWT signing.", + "Access a developer's forgotten backup file.": "Access a developer's forgotten backup file.", + "You need to trick a security mechanism into thinking that the file you want has a valid file type.": "You need to trick a security mechanism into thinking that the file you want has a valid file type.", + "Access a salesman's forgotten backup file.": "Access a salesman's forgotten backup file.", + "Inform the shop about a typosquatting imposter that dug itself deep into the frontend. (Mention the exact name of the culprit)": "Inform the shop about a typosquatting imposter that dug itself deep into the frontend. (Mention the exact name of the culprit)", + "This challenge has nothing to do with mistyping web domains. There is no conveniently misplaced file helping you with this one either. Or is there?": "This challenge has nothing to do with mistyping web domains. There is no conveniently misplaced file helping you with this one either. Or is there?", + "Log in with Chris' erased user account.": "Log in with Chris' erased user account.", + "Turns out that something is technically and legally wrong with the implementation of the \"right to be forgotten\" for users.": "Turns out that something is technically and legally wrong with the implementation of the \"right to be forgotten\" for users.", + "Steal someone else's personal data without using Injection.": "Steal someone else's personal data without using Injection.", + "Trick the regular Data Export to give you more than actually belongs to you.": "Trick the regular Data Export to give you more than actually belongs to you.", + "Perform a persisted XSS attack with <iframe src=\"javascript:alert(`xss`)\"> through an HTTP header.": "Perform a persisted XSS attack with <iframe src=\"javascript:alert(`xss`)\"> through an HTTP header.", + "Finding a piece of displayed information that could originate from an HTTP header is part of this challenge.": "Finding a piece of displayed information that could originate from an HTTP header is part of this challenge.", + "Solve challenge #999. Unfortunately, this challenge does not exist.": "Solve challenge #999. Unfortunately, this challenge does not exist.", + "You need to trick the hacking progress persistence feature into thinking you solved challenge #999.": "You need to trick the hacking progress persistence feature into thinking you solved challenge #999.", + "Dumpster dive the Internet for a leaked password and log in to the original user account it belongs to. (Creating a new account with the same password does not qualify as a solution.)": "Dumpster dive the Internet for a leaked password and log in to the original user account it belongs to. (Creating a new account with the same password does not qualify as a solution.)", + "Once you have it, a technique called \"Password Spraying\" might prove useful.": "Once you have it, a technique called \"Password Spraying\" might prove useful.", + "Identify an unsafe product that was removed from the shop and inform the shop which ingredients are dangerous.": "Identify an unsafe product that was removed from the shop and inform the shop which ingredients are dangerous.", + "Your own SQLi and someone else's Ctrl-V will be your accomplices in this challenge!": "Your own SQLi and someone else's Ctrl-V will be your accomplices in this challenge!", + "Inform the shop about a typosquatting trick it has been a victim of at least in v6.2.0-SNAPSHOT. (Mention the exact name of the culprit)": "Inform the shop about a typosquatting trick it has been a victim of at least in v6.2.0-SNAPSHOT. (Mention the exact name of the culprit)", + "This challenge has nothing to do with mistyping web domains. Investigate the forgotten developer's backup file instead.": "This challenge has nothing to do with mistyping web domains. Investigate the forgotten developer's backup file instead.", + "Log in with the administrator's user account.": "Log in with the administrator's user account.", + "Try different SQL Injection attack patterns depending whether you know the admin's email address or not.": "Try different SQL Injection attack patterns depending whether you know the admin's email address or not.", + "Log in with Amy's original user credentials. (This could take 93.83 billion trillion trillion centuries to brute force, but luckily she did not read the \"One Important Final Note\")": "Log in with Amy's original user credentials. (This could take 93.83 billion trillion trillion centuries to brute force, but luckily she did not read the \"One Important Final Note\")", + "This challenge will make you go after a needle in a haystack.": "This challenge will make you go after a needle in a haystack.", + "Log in with Bender's user account.": "Log in with Bender's user account.", + "If you know Bender's email address, try SQL Injection. Bender's password hash might not help you very much.": "If you know Bender's email address, try SQL Injection. Bender's password hash might not help you very much.", + "Log in with Bjoern's Gmail account without previously changing his password, applying SQL Injection, or hacking his Google account.": "Log in with Bjoern's Gmail account without previously changing his password, applying SQL Injection, or hacking his Google account.", + "The security flaw behind this challenge is 100% OWASP Juice Shop's fault and 0% Google's.": "The security flaw behind this challenge is 100% OWASP Juice Shop's fault and 0% Google's.", + "Exploit OAuth 2.0 to log in with the Chief Information Security Officer's user account.": "Exploit OAuth 2.0 to log in with the Chief Information Security Officer's user account.", + "Don't try to beat Google's OAuth 2.0 service. Rather investigate implementation flaws on OWASP Juice Shop's end.": "Don't try to beat Google's OAuth 2.0 service. Rather investigate implementation flaws on OWASP Juice Shop's end.", + "Log in with Jim's user account.": "Log in with Jim's user account.", + "Try cracking Jim's password hash if you harvested it already. Alternatively, if you know Jim's email address, try SQL Injection.": "Try cracking Jim's password hash if you harvested it already. Alternatively, if you know Jim's email address, try SQL Injection.", + "Log in with MC SafeSearch's original user credentials without applying SQL Injection or any other bypass.": "Log in with MC SafeSearch's original user credentials without applying SQL Injection or any other bypass.", + "You should listen to MC's hit song \"Protect Ya Passwordz\".": "You should listen to MC's hit song \"Protect Ya Passwordz\".", + "Log in with the support team's original user credentials without applying SQL Injection or any other bypass.": "Log in with the support team's original user credentials without applying SQL Injection or any other bypass.", + "The underlying flaw of this challenge is a lot more human error than technical weakness.": "The underlying flaw of this challenge is a lot more human error than technical weakness.", + "Put an additional product into another user's shopping basket.": "Put an additional product into another user's shopping basket.", + "Have an eye on the HTTP traffic while placing products in the shopping basket. Changing the quantity of products already in the basket doesn't count.": "Have an eye on the HTTP traffic while placing products in the shopping basket. Changing the quantity of products already in the basket doesn't count.", + "Access a misplaced SIEM signature file.": "Access a misplaced SIEM signature file.", + "Like any review at least three times as the same user.": "Like any review at least three times as the same user.", + "Punctuality is the politeness of kings.": "Punctuality is the politeness of kings.", + "Apply some advanced cryptanalysis to find the real easter egg.": "Apply some advanced cryptanalysis to find the real easter egg.", + "You might have to peel through several layers of tough-as-nails encryption for this challenge.": "You might have to peel through several layers of tough-as-nails encryption for this challenge.", + "Let the server sleep for some time. (It has done more than enough hard work for you)": "Let the server sleep for some time. (It has done more than enough hard work for you)", + "This challenge is essentially a stripped-down Denial of Service (DoS) attack.": "This challenge is essentially a stripped-down Denial of Service (DoS) attack.", + "All your orders are belong to us! Even the ones which don't.": "All your orders are belong to us! Even the ones which don't.", + "Take a close look on how the $where query operator works in MongoDB.": "Take a close look on how the $where query operator works in MongoDB.", + "Update multiple product reviews at the same time.": "Update multiple product reviews at the same time.", + "Take a close look on how the equivalent of UPDATE-statements in MongoDB work.": "Take a close look on how the equivalent of UPDATE-statements in MongoDB work.", + "Let us redirect you to one of our crypto currency addresses which are not promoted any longer.": "Let us redirect you to one of our crypto currency addresses which are not promoted any longer.", + "We might have failed to take this out of our code properly.": "We might have failed to take this out of our code properly.", + "Log in with the administrator's user credentials without previously changing them or applying SQL Injection.": "Log in with the administrator's user credentials without previously changing them or applying SQL Injection.", + "This one should be equally easy to a) brute force, b) crack the password hash or c) simply guess.": "This one should be equally easy to a) brute force, b) crack the password hash or c) simply guess.", + "Place an order that makes you rich.": "Place an order that makes you rich.", + "You literally need to make the shop owe you any amount of money.": "You literally need to make the shop owe you any amount of money.", + " Unlock Premium Challenge to access exclusive content.": " Unlock Premium Challenge to access exclusive content.", + "You do not have to pay anything to unlock this challenge! Nonetheless, donations are very much appreciated.": "You do not have to pay anything to unlock this challenge! Nonetheless, donations are very much appreciated.", + "Read our privacy policy.": "Read our privacy policy.", + "We won't even ask you to confirm that you did. Just read it. Please. Pretty please.": "We won't even ask you to confirm that you did. Just read it. Please. Pretty please.", + "Prove that you actually read our privacy policy.": "Prove that you actually read our privacy policy.", + "Only by visiting a special URL you can confirm that you read it carefully.": "Only by visiting a special URL you can confirm that you read it carefully.", + "Change the href of the link within the OWASP SSL Advanced Forensic Tool (O-Saft) product description into https://owasp.slack.com.": "Change the href of the link within the OWASP SSL Advanced Forensic Tool (O-Saft) product description into https://owasp.slack.com.", + "Look for one of the following: a) broken admin functionality, b) holes in RESTful API or c) possibility for SQL Injection.": "Look for one of the following: a) broken admin functionality, b) holes in RESTful API or c) possibility for SQL Injection.", + "Perform a reflected XSS attack with <iframe src=\"javascript:alert(`xss`)\">.": "Perform a reflected XSS attack with <iframe src=\"javascript:alert(`xss`)\">.", + "Look for an input field where its content appears in the response HTML when its form is submitted.": "Look for an input field where its content appears in the response HTML when its form is submitted.", + "Follow the DRY principle while registering a user.": "Follow the DRY principle while registering a user.", + "You can solve this by cleverly interacting with the UI or bypassing it altogether.": "You can solve this by cleverly interacting with the UI or bypassing it altogether.", + "Reset Bender's password via the Forgot Password mechanism with the original answer to his security question.": "Reset Bender's password via the Forgot Password mechanism with the original answer to his security question.", + "Not as trivial as Jim's but still not too difficult with some \"Futurama\" background knowledge.": "Not as trivial as Jim's but still not too difficult with some \"Futurama\" background knowledge.", + "Reset the password of Bjoern's internal account via the Forgot Password mechanism with the original answer to his security question.": "Reset the password of Bjoern's internal account via the Forgot Password mechanism with the original answer to his security question.", + "Nothing a little bit of Facebook stalking couldn't reveal. Might involve a historical twist.": "Nothing a little bit of Facebook stalking couldn't reveal. Might involve a historical twist.", + "Reset Jim's password via the Forgot Password mechanism with the original answer to his security question.": "Reset Jim's password via the Forgot Password mechanism with the original answer to his security question.", + "It's hard for celebrities to pick a security question from a hard-coded list where the answer is not publicly exposed.": "It's hard for celebrities to pick a security question from a hard-coded list where the answer is not publicly exposed.", + "Reset Morty's password via the Forgot Password mechanism with his obfuscated answer to his security question.": "Reset Morty's password via the Forgot Password mechanism with his obfuscated answer to his security question.", + "Find a way to bypass the rate limiting and brute force the obfuscated answer to Morty's security question.": "Find a way to bypass the rate limiting and brute force the obfuscated answer to Morty's security question.", + "Deprive the shop of earnings by downloading the blueprint for one of its products.": "Deprive the shop of earnings by downloading the blueprint for one of its products.", + "The product you might want to give a closer look is the OWASP Juice Shop Logo (3D-printed).": "The product you might want to give a closer look is the OWASP Juice Shop Logo (3D-printed).", + "Request a hidden resource on server through server.": "Request a hidden resource on server through server.", + "Reverse engineering something bad can make good things happen.": "Reverse engineering something bad can make good things happen.", + "Infect the server with juicy malware by abusing arbitrary command execution.": "Infect the server with juicy malware by abusing arbitrary command execution.", + "\"SSTi\" is a clear indicator that this has nothing to do with anything Angular. Also, make sure to use only our non-malicious malware.": "\"SSTi\" is a clear indicator that this has nothing to do with anything Angular. Also, make sure to use only our non-malicious malware.", + "Behave like any \"white-hat\" should before getting into the action.": "Behave like any \"white-hat\" should before getting into the action.", + "Undoubtably you want to read our security policy before conducting any research on our application.": "Undoubtably you want to read our security policy before conducting any research on our application.", + "Perform a persisted XSS attack with <iframe src=\"javascript:alert(`xss`)\"> bypassing a server-side security mechanism.": "Perform a persisted XSS attack with <iframe src=\"javascript:alert(`xss`)\"> bypassing a server-side security mechanism.", + "The \"Comment\" field in the \"Customer Feedback\" screen is where you want to put your focus on.": "The \"Comment\" field in the \"Customer Feedback\" screen is where you want to put your focus on.", + "Rat out a notorious character hiding in plain sight in the shop. (Mention the exact name of the character)": "Rat out a notorious character hiding in plain sight in the shop. (Mention the exact name of the character)", + "No matter how good your eyes are, you will need tool assistance for this challenge.": "No matter how good your eyes are, you will need tool assistance for this challenge.", + "Perform a Remote Code Execution that occupies the server for a while without using infinite loops.": "Perform a Remote Code Execution that occupies the server for a while without using infinite loops.", + "Your attack payload must not trigger the protection against too many iterations.": "Your attack payload must not trigger the protection against too many iterations.", + "This vulnerability will not affect any customer of the shop. It is aimed exclusively at its developers.": "This vulnerability will not affect any customer of the shop. It is aimed exclusively at its developers.", + "Solve the 2FA challenge for user \"wurstbrot\". (Disabling, bypassing or overwriting his 2FA settings does not count as a solution)": "Solve the 2FA challenge for user \"wurstbrot\". (Disabling, bypassing or overwriting his 2FA settings does not count as a solution)", + "The 2FA implementation requires to store a secret for every user. You will need to find a way to access this secret in order to solve this challenge.": "The 2FA implementation requires to store a secret for every user. You will need to find a way to access this secret in order to solve this challenge.", + "Forge an essentially unsigned JWT token that impersonates the (non-existing) user jwtn3d@juice-sh.op.": "Forge an essentially unsigned JWT token that impersonates the (non-existing) user jwtn3d@juice-sh.op.", + "This challenge exploits a weird option that is supported when signing tokens with JWT.": "This challenge exploits a weird option that is supported when signing tokens with JWT.", + "Upload a file larger than 100 kB.": "Upload a file larger than 100 kB.", + "You can attach a small file to the \"Complaint\" form. Investigate how this upload actually works.": "You can attach a small file to the \"Complaint\" form. Investigate how this upload actually works.", + "Upload a file that has no .pdf or .zip extension.": "Upload a file that has no .pdf or .zip extension.", + "You can attach a PDF or ZIP file to the \"Complaint\" form. Investigate how this upload actually works.": "You can attach a PDF or ZIP file to the \"Complaint\" form. Investigate how this upload actually works.", + "Retrieve a list of all user credentials via SQL Injection.": "Retrieve a list of all user credentials via SQL Injection.", + "Gather information on where user data is stored and how it is addressed. Then craft a corresponding UNION SELECT attack.": "Gather information on where user data is stored and how it is addressed. Then craft a corresponding UNION SELECT attack.", + "Embed an XSS payload </script><script>alert(`xss`)</script> into our promo video.": "Embed an XSS payload </script><script>alert(`xss`)</script> into our promo video.", + "You have to reuse the vulnerability behind one other 6-star challenge to be able to solve this one.": "You have to reuse the vulnerability behind one other 6-star challenge to be able to solve this one.", + "View another user's shopping basket.": "View another user's shopping basket.", + "Have an eye on the HTTP traffic while shopping. Alternatively try to find a client-side association of users to their basket.": "Have an eye on the HTTP traffic while shopping. Alternatively try to find a client-side association of users to their basket.", + "Inform the shop about a vulnerable library it is using. (Mention the exact library name and version in your comment)": "Inform the shop about a vulnerable library it is using. (Mention the exact library name and version in your comment)", + "Report one of two possible answers via the \"Customer Feedback\" form. Do not forget to submit the library's version as well.": "Report one of two possible answers via the \"Customer Feedback\" form. Do not forget to submit the library's version as well.", + "Inform the shop about an algorithm or library it should definitely not use the way it does.": "Inform the shop about an algorithm or library it should definitely not use the way it does.", + "Report one of four possible answers via the \"Customer Feedback\" form.": "Report one of four possible answers via the \"Customer Feedback\" form.", + "Enforce a redirect to a page you are not supposed to redirect to.": "Enforce a redirect to a page you are not supposed to redirect to.", + "You have to find a way to beat the allowlist of allowed redirect URLs.": "You have to find a way to beat the allowlist of allowed redirect URLs.", + "Retrieve the content of C:\\Windows\\system.ini or /etc/passwd from the server.": "Retrieve the content of C:\\Windows\\system.ini or /etc/passwd from the server.", + "The leverage point for this challenge is the deprecated B2B interface.": "The leverage point for this challenge is the deprecated B2B interface.", + "Give the server something to chew on for quite a while.": "Give the server something to chew on for quite a while.", + "It is not as easy as sending a large amount of data directly to the deprecated B2B interface.": "It is not as easy as sending a large amount of data directly to the deprecated B2B interface.", + "Give a devastating zero-star feedback to the store.": "Give a devastating zero-star feedback to the store.", + "Before you invest time bypassing the API, you might want to play around with the UI a bit.": "Before you invest time bypassing the API, you might want to play around with the UI a bit.", + "Your eldest siblings middle name?": "Your eldest siblings middle name?", + "Mother's maiden name?": "Mother's maiden name?", + "Mother's birth date? (MM/DD/YY)": "Mother's birth date? (MM/DD/YY)", + "Father's birth date? (MM/DD/YY)": "Father's birth date? (MM/DD/YY)", + "Maternal grandmother's first name?": "Maternal grandmother's first name?", + "Paternal grandmother's first name?": "Paternal grandmother's first name?", + "Name of your favorite pet?": "Name of your favorite pet?", + "Last name of dentist when you were a teenager? (Do not include 'Dr.')": "Last name of dentist when you were a teenager? (Do not include 'Dr.')", + "Your ZIP/postal code when you were a teenager?": "Your ZIP/postal code when you were a teenager?", + "Company you first work for as an adult?": "Company you first work for as an adult?", + "Your favorite book?": "Your favorite book?", + "Your favorite movie?": "Your favorite movie?", + "Number of one of your customer or ID cards?": "Number of one of your customer or ID cards?", + "Apple Juice (1000ml)": "Apple Juice (1000ml)", + "The all-time classic.": "The all-time classic.", + "Orange Juice (1000ml)": "Orange Juice (1000ml)", + "Made from oranges hand-picked by Uncle Dittmeyer.": "Made from oranges hand-picked by Uncle Dittmeyer.", + "Eggfruit Juice (500ml)": "Eggfruit Juice (500ml)", + "Now with even more exotic flavour.": "Now with even more exotic flavour.", + "Raspberry Juice (1000ml)": "Raspberry Juice (1000ml)", + "Made from blended Raspberry Pi, water and sugar.": "Made from blended Raspberry Pi, water and sugar.", + "Lemon Juice (500ml)": "Lemon Juice (500ml)", + "Sour but full of vitamins.": "Sour but full of vitamins.", + "Banana Juice (1000ml)": "Banana Juice (1000ml)", + "Monkeys love it the most.": "Monkeys love it the most.", + "OWASP Juice Shop T-Shirt": "OWASP Juice Shop T-Shirt", + "Real fans wear it 24/7!": "Real fans wear it 24/7!", + "OWASP Juice Shop CTF Girlie-Shirt": "OWASP Juice Shop CTF Girlie-Shirt", + "For serious Capture-the-Flag heroines only!": "For serious Capture-the-Flag heroines only!", + "OWASP SSL Advanced Forensic Tool (O-Saft)": "OWASP SSL Advanced Forensic Tool (O-Saft)", + "O-Saft is an easy to use tool to show information about SSL certificate and tests the SSL connection according given list of ciphers and various SSL configurations. More...": "O-Saft is an easy to use tool to show information about SSL certificate and tests the SSL connection according given list of ciphers and various SSL configurations. More...", + "Christmas Super-Surprise-Box (2014 Edition)": "Christmas Super-Surprise-Box (2014 Edition)", + "Contains a random selection of 10 bottles (each 500ml) of our tastiest juices and an extra fan shirt for an unbeatable price! (Seasonal special offer! Limited availability!)": "Contains a random selection of 10 bottles (each 500ml) of our tastiest juices and an extra fan shirt for an unbeatable price! (Seasonal special offer! Limited availability!)", + "Rippertuer Special Juice": "Rippertuer Special Juice", + "Contains a magical collection of the rarest fruits gathered from all around the world, like Cherymoya Annona cherimola, Jabuticaba Myrciaria cauliflora, Bael Aegle marmelos... and others, at an unbelievable price!
This item has been made unavailable because of lack of safety standards. (This product is unsafe! We plan to remove it from the stock!)": "Contains a magical collection of the rarest fruits gathered from all around the world, like Cherymoya Annona cherimola, Jabuticaba Myrciaria cauliflora, Bael Aegle marmelos... and others, at an unbelievable price!
This item has been made unavailable because of lack of safety standards. (This product is unsafe! We plan to remove it from the stock!)", + "OWASP Juice Shop Sticker (2015/2016 design)": "OWASP Juice Shop Sticker (2015/2016 design)", + "Die-cut sticker with the official 2015/2016 logo. By now this is a rare collectors item. Out of stock!": "Die-cut sticker with the official 2015/2016 logo. By now this is a rare collectors item. Out of stock!", + "OWASP Juice Shop Iron-Ons (16pcs)": "OWASP Juice Shop Iron-Ons (16pcs)", + "Upgrade your clothes with washer safe iron-ons of the OWASP Juice Shop or CTF Extension logo!": "Upgrade your clothes with washer safe iron-ons of the OWASP Juice Shop or CTF Extension logo!", + "OWASP Juice Shop Magnets (16pcs)": "OWASP Juice Shop Magnets (16pcs)", + "Your fridge will be even cooler with these OWASP Juice Shop or CTF Extension logo magnets!": "Your fridge will be even cooler with these OWASP Juice Shop or CTF Extension logo magnets!", + "OWASP Juice Shop Sticker Page": "OWASP Juice Shop Sticker Page", + "Massive decoration opportunities with these OWASP Juice Shop or CTF Extension sticker pages! Each page has 16 stickers on it.": "Massive decoration opportunities with these OWASP Juice Shop or CTF Extension sticker pages! Each page has 16 stickers on it.", + "OWASP Juice Shop Sticker Single": "OWASP Juice Shop Sticker Single", + "Super high-quality vinyl sticker single with the OWASP Juice Shop or CTF Extension logo! The ultimate laptop decal!": "Super high-quality vinyl sticker single with the OWASP Juice Shop or CTF Extension logo! The ultimate laptop decal!", + "OWASP Juice Shop Temporary Tattoos (16pcs)": "OWASP Juice Shop Temporary Tattoos (16pcs)", + "Get one of these temporary tattoos to proudly wear the OWASP Juice Shop or CTF Extension logo on your skin! If you tweet a photo of yourself with the tattoo, you get a couple of our stickers for free! Please mention @owasp_juiceshop in your tweet!": "Get one of these temporary tattoos to proudly wear the OWASP Juice Shop or CTF Extension logo on your skin! If you tweet a photo of yourself with the tattoo, you get a couple of our stickers for free! Please mention @owasp_juiceshop in your tweet!", + "OWASP Juice Shop Mug": "OWASP Juice Shop Mug", + "Black mug with regular logo on one side and CTF logo on the other! Your colleagues will envy you!": "Black mug with regular logo on one side and CTF logo on the other! Your colleagues will envy you!", + "OWASP Juice Shop Hoodie": "OWASP Juice Shop Hoodie", + "Mr. Robot-style apparel. But in black. And with logo.": "Mr. Robot-style apparel. But in black. And with logo.", + "OWASP Juice Shop-CTF Velcro Patch": "OWASP Juice Shop-CTF Velcro Patch", + "4x3.5\" embroidered patch with velcro backside. The ultimate decal for every tactical bag or backpack!": "4x3.5\" embroidered patch with velcro backside. The ultimate decal for every tactical bag or backpack!", + "Woodruff Syrup \"Forest Master X-Treme\"": "Woodruff Syrup \"Forest Master X-Treme\"", + "Harvested and manufactured in the Black Forest, Germany. Can cause hyperactive behavior in children. Can cause permanent green tongue when consumed undiluted.": "Harvested and manufactured in the Black Forest, Germany. Can cause hyperactive behavior in children. Can cause permanent green tongue when consumed undiluted.", + "Green Smoothie": "Green Smoothie", + "Looks poisonous but is actually very good for your health! Made from green cabbage, spinach, kiwi and grass.": "Looks poisonous but is actually very good for your health! Made from green cabbage, spinach, kiwi and grass.", + "Quince Juice (1000ml)": "Quince Juice (1000ml)", + "Juice of the Cydonia oblonga fruit. Not exactly sweet but rich in Vitamin C.": "Juice of the Cydonia oblonga fruit. Not exactly sweet but rich in Vitamin C.", + "Apple Pomace": "Apple Pomace", + "Finest pressings of apples. Allergy disclaimer: Might contain traces of worms. Can be sent back to us for recycling.": "Finest pressings of apples. Allergy disclaimer: Might contain traces of worms. Can be sent back to us for recycling.", + "Fruit Press": "Fruit Press", + "Fruits go in. Juice comes out. Pomace you can send back to us for recycling purposes.": "Fruits go in. Juice comes out. Pomace you can send back to us for recycling purposes.", + "OWASP Juice Shop Logo (3D-printed)": "OWASP Juice Shop Logo (3D-printed)", + "This rare item was designed and handcrafted in Sweden. This is why it is so incredibly expensive despite its complete lack of purpose.": "This rare item was designed and handcrafted in Sweden. This is why it is so incredibly expensive despite its complete lack of purpose.", + "Juice Shop Artwork": "Juice Shop Artwork", + "Unique masterpiece painted with different kinds of juice on 90g/m² lined paper.": "Unique masterpiece painted with different kinds of juice on 90g/m² lined paper.", + "Global OWASP WASPY Award 2017 Nomination": "Global OWASP WASPY Award 2017 Nomination", + "Your chance to nominate up to three quiet pillars of the OWASP community ends 2017-06-30! Nominate now!": "Your chance to nominate up to three quiet pillars of the OWASP community ends 2017-06-30! Nominate now!", + "Strawberry Juice (500ml)": "Strawberry Juice (500ml)", + "Sweet & tasty!": "Sweet & tasty!", + "Carrot Juice (1000ml)": "Carrot Juice (1000ml)", + "As the old German saying goes: \"Carrots are good for the eyes. Or has anyone ever seen a rabbit with glasses?\"": "As the old German saying goes: \"Carrots are good for the eyes. Or has anyone ever seen a rabbit with glasses?\"", + "OWASP Juice Shop Sweden Tour 2017 Sticker Sheet (Special Edition)": "OWASP Juice Shop Sweden Tour 2017 Sticker Sheet (Special Edition)", + "10 sheets of Sweden-themed stickers with 15 stickers on each.": "10 sheets of Sweden-themed stickers with 15 stickers on each.", + "Pwning OWASP Juice Shop": "Pwning OWASP Juice Shop", + "Melon Bike (Comeback-Product 2018 Edition)": "Melon Bike (Comeback-Product 2018 Edition)", + "The wheels of this bicycle are made from real water melons. You might not want to ride it up/down the curb too hard.": "The wheels of this bicycle are made from real water melons. You might not want to ride it up/down the curb too hard.", + "OWASP Juice Shop Coaster (10pcs)": "OWASP Juice Shop Coaster (10pcs)", + "Our 95mm circle coasters are printed in full color and made from thick, premium coaster board.": "Our 95mm circle coasters are printed in full color and made from thick, premium coaster board.", + "Retrieve the photo of Bjoern's cat in \"melee combat-mode\".": "Retrieve the photo of Bjoern's cat in \"melee combat-mode\".", + "Check the Photo Wall for an image that could not be loaded correctly.": "Check the Photo Wall for an image that could not be loaded correctly.", + "Stick cute cross-domain kittens all over our delivery boxes.": "Stick cute cross-domain kittens all over our delivery boxes.", + "This challenge would formally have to be in several categories as the developers made multiple gaffes for this to be possible.": "This challenge would formally have to be in several categories as the developers made multiple gaffes for this to be possible.", + "ea.": "ea.", + "Delivery Price": "Delivery Price", + "Total Price": "Total Price", + "Bonus Points Earned": "Bonus Points Earned", + "The bonus points from this order will be added 1:1 to your wallet ¤-fund for future purchases!": "The bonus points from this order will be added 1:1 to your wallet ¤-fund for future purchases!", + "Thank you for your order!": "Thank you for your order!", + "Order Confirmation": "Order Confirmation", + "Customer": "Customer", + "Order": "Order", + "Date": "Date", + "OWASP Juice Shop Holographic Sticker": "OWASP Juice Shop Holographic Sticker", + "Die-cut holographic sticker. Stand out from those 08/15-sticker-covered laptops with this shiny beacon of 80's coolness!": "Die-cut holographic sticker. Stand out from those 08/15-sticker-covered laptops with this shiny beacon of 80's coolness!", + "OWASP Snakes and Ladders - Mobile Apps": "OWASP Snakes and Ladders - Mobile Apps", + "This amazing mobile app security awareness board game is available for Tabletop Simulator on Steam Workshop now!": "This amazing mobile app security awareness board game is available for Tabletop Simulator on Steam Workshop now!", + "OWASP Snakes and Ladders - Web Applications": "OWASP Snakes and Ladders - Web Applications", + "This amazing web application security awareness board game is available for Tabletop Simulator on Steam Workshop now!": "This amazing web application security awareness board game is available for Tabletop Simulator on Steam Workshop now!", + "The official Companion Guide by Björn Kimminich available for free on LeanPub and also readable online!": "The official Companion Guide by Björn Kimminich available for free on LeanPub and also readable online!", + "We are out of stock! Sorry for the inconvenience.": "We are out of stock! Sorry for the inconvenience.", + "Wrong answer to CAPTCHA. Please try again.": "Wrong answer to CAPTCHA. Please try again.", + "Invalid email or password.": "Invalid email or password.", + "Current password is not correct.": "Current password is not correct.", + "Password cannot be empty.": "Password cannot be empty.", + "New and repeated password do not match.": "New and repeated password do not match.", + "Wrong answer to security question.": "Wrong answer to security question.", + "Inform the development team about a danger to some of their credentials. (Send them the URL of the original report or an assigned CVE or another identifier of this vulnerability)": "Inform the development team about a danger to some of their credentials. (Send them the URL of the original report or an assigned CVE or another identifier of this vulnerability)", + "You can order only up to {{quantity}} items of this product.": "You can order only up to {{quantity}} items of this product.", + " (This challenge is not available on Docker!)": " (This challenge is not available on Docker!)", + " (This challenge is not available on Heroku!)": " (This challenge is not available on Heroku!)", + " (This challenge is not available on Gitpod!)": " (This challenge is not available on Gitpod!)", + " (This challenge is potentially harmful on Docker!)": " (This challenge is potentially harmful on Docker!)", + " (This challenge is potentially harmful on Gitpod!)": " (This challenge is potentially harmful on Gitpod!)", + " (This challenge is potentially harmful on Heroku!)": " (This challenge is potentially harmful on Heroku!)", + "Find the endpoint that serves usage data to be scraped by a popular monitoring system.": "Find the endpoint that serves usage data to be scraped by a popular monitoring system.", + "Try to guess what URL the endpoint might have.": "Try to guess what URL the endpoint might have.", + "Look for a url parameter where its value appears in the page it is leading to.": "Look for a url parameter where its value appears in the page it is leading to.", + "Change the name of a user by performing Cross-Site Request Forgery from another origin.": "Change the name of a user by performing Cross-Site Request Forgery from another origin.", + "Use the bonus payload <iframe width="100%" height="166" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/771984076&color=%23ff5500&auto_play=true&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true"></iframe> in the DOM XSS challenge.": "Use the bonus payload <iframe width="100%" height="166" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/771984076&color=%23ff5500&auto_play=true&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true"></iframe> in the DOM XSS challenge.", + "Copy + Paste = Solved!": "Copy + Paste = Solved!", + "Obtain a Deluxe Membership without paying for it.": "Obtain a Deluxe Membership without paying for it.", + "Look closely at what happens when you attempt to upgrade your account.": "Look closely at what happens when you attempt to upgrade your account.", + " (This challenge is not available on Windows!)": " (This challenge is not available on Windows!)", + "Reset Uvogin's password via the Forgot Password mechanism with the original answer to his security question.": "Reset Uvogin's password via the Forgot Password mechanism with the original answer to his security question.", + "You might have to do some OSINT on his social media personas to find out his honest answer to the security question.": "You might have to do some OSINT on his social media personas to find out his honest answer to the security question.", + "Juice Shop Adversary Trading Card (Common)": "Juice Shop Adversary Trading Card (Common)", + "Common rarity \"Juice Shop\" card for the Adversary Trading Cards CCG.": "Common rarity \"Juice Shop\" card for the Adversary Trading Cards CCG.", + "Juice Shop Adversary Trading Card (Super Rare)": "Juice Shop Adversary Trading Card (Super Rare)", + "Super rare \"Juice Shop\" card with holographic foil-coating for the Adversary Trading Cards CCG.": "Super rare \"Juice Shop\" card with holographic foil-coating for the Adversary Trading Cards CCG.", + "OWASP Juice Shop \"King of the Hill\" Facemask": "OWASP Juice Shop \"King of the Hill\" Facemask", + "Facemask with compartment for filter from 50% cotton and 50% polyester.": "Facemask with compartment for filter from 50% cotton and 50% polyester.", + "Determine the answer to John's security question by looking at an upload of him to the Photo Wall and use it to reset his password via the Forgot Password mechanism.": "Determine the answer to John's security question by looking at an upload of him to the Photo Wall and use it to reset his password via the Forgot Password mechanism.", + "Take a look at the meta data of the corresponding photo.": "Take a look at the meta data of the corresponding photo.", + "Determine the answer to Emma's security question by looking at an upload of her to the Photo Wall and use it to reset her password via the Forgot Password mechanism.": "Determine the answer to Emma's security question by looking at an upload of her to the Photo Wall and use it to reset her password via the Forgot Password mechanism.", + "Take a look at the details in the photo to determine the location of where it was taken.": "Take a look at the details in the photo to determine the location of where it was taken.", + "Juice Shop \"Permafrost\" 2020 Edition": "Juice Shop \"Permafrost\" 2020 Edition", + "Bypass a security control with a Poison Null Byte to access a file not meant for your eyes.": "Bypass a security control with a Poison Null Byte to access a file not meant for your eyes.", + "Best Juice Shop Salesman Artwork": "Best Juice Shop Salesman Artwork", + "Unique digital painting depicting Stan, our most qualified and almost profitable salesman. He made a succesful carreer in selling used ships, coffins, krypts, crosses, real estate, life insurance, restaurant supplies, voodoo enhanced asbestos and courtroom souvenirs before finally adding his expertise to the Juice Shop marketing team.": "Unique digital painting depicting Stan, our most qualified and almost profitable salesman. He made a succesful carreer in selling used ships, coffins, krypts, crosses, real estate, life insurance, restaurant supplies, voodoo enhanced asbestos and courtroom souvenirs before finally adding his expertise to the Juice Shop marketing team.", + "20th Anniversary Celebration Ticket": "20th Anniversary Celebration Ticket", + "Get your free 🎫 for OWASP 20th Anniversary Celebration online conference! Hear from world renowned keynotes and special speakers, network with your peers and interact with our event sponsors. With an anticipated 10k+ attendees from around the world, you will not want to miss this live on-line event!": "Get your free 🎫 for OWASP 20th Anniversary Celebration online conference! Hear from world renowned keynotes and special speakers, network with your peers and interact with our event sponsors. With an anticipated 10k+ attendees from around the world, you will not want to miss this live on-line event!", + "OWASP Juice Shop Card (non-foil)": "OWASP Juice Shop Card (non-foil)", + "Mythic rare (obviously...) card \"OWASP Juice Shop\" with three distinctly useful abilities. Alpha printing, mint condition. A true collectors piece to own!": "Mythic rare (obviously...) card \"OWASP Juice Shop\" with three distinctly useful abilities. Alpha printing, mint condition. A true collectors piece to own!", + "Line {{vulnLine}} is responsible for this vulnerability or security flaw. Select it and submit to proceed.": "Line {{vulnLine}} is responsible for this vulnerability or security flaw. Select it and submit to proceed.", + "Lines {{vulnLines}} are responsible for this vulnerability or security flaw. Select them and submit to proceed.": "Lines {{vulnLines}} are responsible for this vulnerability or security flaw. Select them and submit to proceed.", + "Receive a coupon code from the support chatbot.": "Receive a coupon code from the support chatbot.", + "Just keep asking.": "Just keep asking.", + "Permanently disable the support chatbot so that it can no longer answer customer queries.": "Permanently disable the support chatbot so that it can no longer answer customer queries.", + "Think of a way to get a hold of the internal workings on the chatbot API.": "Think of a way to get a hold of the internal workings on the chatbot API.", + "Gain read access to an arbitrary local file on the web server.": "Gain read access to an arbitrary local file on the web server.", + "You should read up on vulnerabilities in popular NodeJs template engines.": "You should read up on vulnerabilities in popular NodeJs template engines.", + "Try to identify where (potentially malicious) user input is coming into the code.": "Try to identify where (potentially malicious) user input is coming into the code.", + "What is the code doing with the user input other than using it to filter the data source?": "What is the code doing with the user input other than using it to filter the data source?", + "Look for a line where the developers fiddled with Angular's built-in security model.": "Look for a line where the developers fiddled with Angular's built-in security model.", + "Using bypassSecurityTrustStyle() instead of bypassSecurityTrustHtml() changes the context for which input sanitization is bypassed. If at all, this switch might only accidentally keep XSS prevention intact. The context where the parameter is used is not CSS, making this switch totally pointless.": "Using bypassSecurityTrustStyle() instead of bypassSecurityTrustHtml() changes the context for which input sanitization is bypassed. If at all, this switch might only accidentally keep XSS prevention intact. The context where the parameter is used is not CSS, making this switch totally pointless.", + "Using bypassSecurityTrustResourceUrl() instead of bypassSecurityTrustHtml() changes the context for which input sanitization is bypassed. This switch might only accidentally keep XSS prevention intact, but the new URL context does not make any sense here.": "Using bypassSecurityTrustResourceUrl() instead of bypassSecurityTrustHtml() changes the context for which input sanitization is bypassed. This switch might only accidentally keep XSS prevention intact, but the new URL context does not make any sense here.", + "Using bypassSecurityTrustScript() instead of bypassSecurityTrustHtml() changes the context for which input sanitization is bypassed. If at all, this switch might only accidentally keep XSS prevention intact. The context where the parameter is used is not a script either, so this switch would be nonsensical.": "Using bypassSecurityTrustScript() instead of bypassSecurityTrustHtml() changes the context for which input sanitization is bypassed. If at all, this switch might only accidentally keep XSS prevention intact. The context where the parameter is used is not a script either, so this switch would be nonsensical.", + "Removing the bypass of sanitization entirely is the best way to fix this vulnerability. Fiddling with Angular's built-in sanitization was entirely unnecessary as the user input for a text search should not be expected to contain HTML that needs to be rendered but merely plain text.": "Removing the bypass of sanitization entirely is the best way to fix this vulnerability. Fiddling with Angular's built-in sanitization was entirely unnecessary as the user input for a text search should not be expected to contain HTML that needs to be rendered but merely plain text.", + "Can you identify one or more routes which have something to do with log files?": "Can you identify one or more routes which have something to do with log files?", + "Did you spot the directory listing clearly linked to log files?": "Did you spot the directory listing clearly linked to log files?", + "Did you notice that there is a seperate route for retrieving individual log files?": "Did you notice that there is a seperate route for retrieving individual log files?", + "Make sure to select both lines responsible for the log file data leakage.": "Make sure to select both lines responsible for the log file data leakage.", + "Switching off the detailed view option is a cosmetic change on the directory listing but still allows the logs to be browsed and accessed.": "Switching off the detailed view option is a cosmetic change on the directory listing but still allows the logs to be browsed and accessed.", + "Removing the route that serves individual log files is likely to plumb the data leak but still provides information to the attacker unnecessarily.": "Removing the route that serves individual log files is likely to plumb the data leak but still provides information to the attacker unnecessarily.", + "Removing only the directory listing will still allow attackers to download individual log files if they can come up with a valid file name.": "Removing only the directory listing will still allow attackers to download individual log files if they can come up with a valid file name.", + "There should generally be no good reason to expose server logs through a web URL of the server itself, epecially not when that server is Internet-facing.": "There should generally be no good reason to expose server logs through a web URL of the server itself, epecially not when that server is Internet-facing.", + "Among the long list of route mappings, can you spot any that seem responsible for admin-related functionality?": "Among the long list of route mappings, can you spot any that seem responsible for admin-related functionality?", + "Luckily the route mappings were originally in alphabetical order before the developers forgot about that rule at some point.": "Luckily the route mappings were originally in alphabetical order before the developers forgot about that rule at some point.", + "Assuming that the original \"AdminGuard\" provided access control only to admin users, switching to \"LoginGuard\" seems like a downgrade that would give access to any authenticated user.": "Assuming that the original \"AdminGuard\" provided access control only to admin users, switching to \"LoginGuard\" seems like a downgrade that would give access to any authenticated user.", + "Obfuscating the path to the administration section does not add any security, even if it wasn't just a trivial Base64 encoding.": "Obfuscating the path to the administration section does not add any security, even if it wasn't just a trivial Base64 encoding.", + "This obfuscation attempt is hard to undo by hand but trivial when executed in a JavaScript console. Regardless, obfuscating the route does not add any level of security.": "This obfuscation attempt is hard to undo by hand but trivial when executed in a JavaScript console. Regardless, obfuscating the route does not add any level of security.", + "While attempts could be made to limit access to administrative functions of a web shop through access control, it is definitely safer to apply the \"separation of concerns\" pattern more strictly by internally hosting a distinct admin backend application with no Internet exposure.": "While attempts could be made to limit access to administrative functions of a web shop through access control, it is definitely safer to apply the \"separation of concerns\" pattern more strictly by internally hosting a distinct admin backend application with no Internet exposure.", + "Can you identify one or more routes which have something to do with file serving?": "Can you identify one or more routes which have something to do with file serving?", + "Did you notice that there are seperate routes the directory listing and retrieving individual files?": "Did you notice that there are seperate routes the directory listing and retrieving individual files?", + "Make sure to select both lines responsible for the data leakage.": "Make sure to select both lines responsible for the data leakage.", + "Removing only the directory listing will still allow attackers to download individual files if they can come up with a valid file name.": "Removing only the directory listing will still allow attackers to download individual files if they can come up with a valid file name.", + "Removing the routes that serve individual files is likely to plumb the data leak but still provides information to the attacker unnecessarily.": "Removing the routes that serve individual files is likely to plumb the data leak but still provides information to the attacker unnecessarily.", + "Switching off the icons is a cosmetic change on the directory listing but still allows the files to be browsed and accessed.": "Switching off the icons is a cosmetic change on the directory listing but still allows the files to be browsed and accessed.", + "Getting rid of the /ftp folder entirely is the only way to plumb this data leakage for good. Valid static content in it needs to be moved to a more suitable location and order confirmation PDFs had no business to be placed there publicly accessible in the first place. Everything else in that folder was just accidentally put & forgotten there anyway.": "Getting rid of the /ftp folder entirely is the only way to plumb this data leakage for good. Valid static content in it needs to be moved to a more suitable location and order confirmation PDFs had no business to be placed there publicly accessible in the first place. Everything else in that folder was just accidentally put & forgotten there anyway.", + "In the long list of API-handling middleware, try to find the ones dealing with products offered in the shop first.": "In the long list of API-handling middleware, try to find the ones dealing with products offered in the shop first.", + "API routes need to specifically define a handler for a HTTP verb if they wish to override the \"allow everything to everyone\" default behavior.": "API routes need to specifically define a handler for a HTTP verb if they wish to override the \"allow everything to everyone\" default behavior.", + "There is one line that is commented out for no good reason among the product-related middleware.": "There is one line that is commented out for no good reason among the product-related middleware.", + "While removing the commented-out line made the code cleaner, it did not change the functionality in any way and thus cannot have improved security either.": "While removing the commented-out line made the code cleaner, it did not change the functionality in any way and thus cannot have improved security either.", + "Removing all dedicated handling of the products API made things worse, as now the default permissions of the underlying API generator will be used: Allowing GET, POST, PUT and DELETE - without any restrictions.": "Removing all dedicated handling of the products API made things worse, as now the default permissions of the underlying API generator will be used: Allowing GET, POST, PUT and DELETE - without any restrictions.", + "You improved security slightly by no longer accepting PUT requests from anonymous API callers. But does the shop even want to allow its authenticated customers to change products themselves?": "You improved security slightly by no longer accepting PUT requests from anonymous API callers. But does the shop even want to allow its authenticated customers to change products themselves?", + "Disabling all HTTP verbs other than GET for the products API is indeed the only safe way to implement secure access control. Shop administrators should not use the customer facing web UI to manage the store's inventory anyway.": "Disabling all HTTP verbs other than GET for the products API is indeed the only safe way to implement secure access control. Shop administrators should not use the customer facing web UI to manage the store's inventory anyway.", + "Try to identify any variables in the code that might contain arbitrary user input.": "Try to identify any variables in the code that might contain arbitrary user input.", + "Follow the user input through the function call and try to spot places where it might be abused for malicious purposes.": "Follow the user input through the function call and try to spot places where it might be abused for malicious purposes.", + "Can you spot a place where a SQL query is being cobbled together in an unsafe way?": "Can you spot a place where a SQL query is being cobbled together in an unsafe way?", + "Trying to prevent any injection attacks with a custom-built blocklist mechanism is doomed to fail. It might work for some simpler attack payloads but an attacker with time and skills can likely bypass it at some point.": "Trying to prevent any injection attacks with a custom-built blocklist mechanism is doomed to fail. It might work for some simpler attack payloads but an attacker with time and skills can likely bypass it at some point.", + "Replacing the template string (`...`) notation with plain string concatenation (\"...\"+\"...\") does not change the behavior of the code in any way. It only makes the code less readable.": "Replacing the template string (`...`) notation with plain string concatenation (\"...\"+\"...\") does not change the behavior of the code in any way. It only makes the code less readable.", + "Using the built-in replacement (or binding) mechanism of Sequelize is equivalent to creating a Prepared Statement. This prevents tampering with the query syntax through malicious user input as it is \"set in stone\" before the criteria parameter is inserted.": "Using the built-in replacement (or binding) mechanism of Sequelize is equivalent to creating a Prepared Statement. This prevents tampering with the query syntax through malicious user input as it is \"set in stone\" before the criteria parameter is inserted.", + "Can you find a HTTP route mapping that deals with metrics?": "Can you find a HTTP route mapping that deals with metrics?", + "Remember: The default behavior of route mappings is to allow access to everyone.": "Remember: The default behavior of route mappings is to allow access to everyone.", + "The metrics route remains publicly accessible. This change only messes with functional settings of the measurement framework unnecessarily.": "The metrics route remains publicly accessible. This change only messes with functional settings of the measurement framework unnecessarily.", + "This fix prevents unauthorized access to the metrics route but overshoots the goal by locking out everyone - including administrators.": "This fix prevents unauthorized access to the metrics route but overshoots the goal by locking out everyone - including administrators.", + "Access will now be restricted only to users with administrator permissions, which seems reasonable protection, assuming that it is not possible for a regular user to escalate admin priviliges. If that were a risk, the metrics should better be stored behind the scenes not be made accessible via the shop application at all.": "Access will now be restricted only to users with administrator permissions, which seems reasonable protection, assuming that it is not possible for a regular user to escalate admin priviliges. If that were a risk, the metrics should better be stored behind the scenes not be made accessible via the shop application at all.", + "Do you remember the security question that Bender used for his account?": "Do you remember the security question that Bender used for his account?", + "This question is the source of the security risk in this challenge.": "This question is the source of the security risk in this challenge.", + "While not necessarily as trivial to research via a user's LinkedIn profile, the question is still easy to research or brute force when answered truthfully.": "While not necessarily as trivial to research via a user's LinkedIn profile, the question is still easy to research or brute force when answered truthfully.", + "Exchanging \"company\" with \"organization\" is only a vocabulary change and has no effect on security.": "Exchanging \"company\" with \"organization\" is only a vocabulary change and has no effect on security.", + "When answered truthfully, all security questions are susceptible to online research (on Facebook, LinkedIn etc.) and often even brute force. If at all, they should not be used as the only factor for a security-relevant function.": "When answered truthfully, all security questions are susceptible to online research (on Facebook, LinkedIn etc.) and often even brute force. If at all, they should not be used as the only factor for a security-relevant function.", + "Can you identify the lines which have something to do with crypto currency addresses?": "Can you identify the lines which have something to do with crypto currency addresses?", + "Did you notice there is a constant containing allowed redirect web addresses?": "Did you notice there is a constant containing allowed redirect web addresses?", + "Make sure to select all three lines responsible for crypto currency addresses which are not promoted any longer.": "Make sure to select all three lines responsible for crypto currency addresses which are not promoted any longer.", + "This fix removes one deprecated crypto currency address from the allow list but forgets to deal with two other ones.": "This fix removes one deprecated crypto currency address from the allow list but forgets to deal with two other ones.", + "When cleaning up any allow list of deprecated entries, it is crucial to be thorough and re-check the list regularly. Otherwise allow lists tend to become weaker over time.": "When cleaning up any allow list of deprecated entries, it is crucial to be thorough and re-check the list regularly. Otherwise allow lists tend to become weaker over time.", + "This fix uses the binding mechanism of Sequelize to create the equivalent of a Prepared Statement, which is great. Unfortunately this fix also introduces a critical functional bug into the authentication process.": "This fix uses the binding mechanism of Sequelize to create the equivalent of a Prepared Statement, which is great. Unfortunately this fix also introduces a critical functional bug into the authentication process.", + "This fix unfortunately goes only half the way to using the binding mechanism of Sequelize. Such a Prepared Statement still concatenated from user input, is still wide open for SQL Injection attacks.": "This fix unfortunately goes only half the way to using the binding mechanism of Sequelize. Such a Prepared Statement still concatenated from user input, is still wide open for SQL Injection attacks.", + "This fix unfortunately goes only half the way to using the replacement mechanism of Sequelize. Such a Prepared Statement still concatenated from user input, is still wide open for SQL Injection attacks.": "This fix unfortunately goes only half the way to using the replacement mechanism of Sequelize. Such a Prepared Statement still concatenated from user input, is still wide open for SQL Injection attacks.", + "Turning off the \"plain\" flag will let Sequelize return all matching rows instead of just the first one. This neither makes sense from a functional point of view in a login function, not could it prevent SQL Injection attacks.": "Turning off the \"plain\" flag will let Sequelize return all matching rows instead of just the first one. This neither makes sense from a functional point of view in a login function, not could it prevent SQL Injection attacks.", + "Using the built-in binding (or replacement) mechanism of Sequelize is equivalent to creating a Prepared Statement. This prevents tampering with the query syntax through malicious user input as it is \"set in stone\" before the criteria parameter is inserted.": "Using the built-in binding (or replacement) mechanism of Sequelize is equivalent to creating a Prepared Statement. This prevents tampering with the query syntax through malicious user input as it is \"set in stone\" before the criteria parameter is inserted.", + "Using bypassSecurityTrustSoundCloud() instead of bypassSecurityTrustHtml() supposedly bypasses sanitization to allow only content from that service provider. Not surprisingly, there is no such vendor-specific function bypassSecurityTrustSoundCloud() offered by the Angular DomSanitizer.": "Using bypassSecurityTrustSoundCloud() instead of bypassSecurityTrustHtml() supposedly bypasses sanitization to allow only content from that service provider. Not surprisingly, there is no such vendor-specific function bypassSecurityTrustSoundCloud() offered by the Angular DomSanitizer.", + "Using bypassSecurityTrustIframe() instead of bypassSecurityTrustHtml() supposedly bypasses sanitization to allow only