One of the core usage scenarios for OWASP Juice Shop is in employee trainings in order to facilitating security awareness. With its not entirely serious user roster and product inventory the application might not be suited for all audiences alike.

In some particularly traditional domains or conservative enterprises it would be beneficial to have the demo application look and behave more like an internal application.

OWASP Juice Shop can be customized in its product inventory and look & feel to accommodate this requirement. It also allows to add an arbitrary number of fake users to make demonstrations - particularly those of UNION-SQL injection attacks - even more impressive. Furthermore the Challenge solved!-notifications can be turned off in order to keep the impression of a "real" application undisturbed.

How to customize the application

The customization is powered by a YAML configuration file placed in /config. To run a customized OWASP Juice Shop you need to:

  1. Place your own .yml configuration file into /config
  2. Set the environment variable NODE_ENV to the filename of your config without the .yml extension
    • On Windows: set NODE_ENV=nameOfYourConfig
    • On Linux: export NODE_ENV=nameOfYourConfig
  3. Run npm start

You can also run a config directly in one command (on Linux) via NODE_ENV=nameOfYourConfig npm start. By default the config/default.yml config is used which generates the original OWASP Juice Shop look & feel and inventory. Please note that it is not necessary to run npm install after switching customization configurations.

Overriding default.yml in Docker container

In order to override the default configuration inside your Docker container with one of the provided configs, you can pass in the NODE_ENV environment variable with the -e parameter:

docker run -d -e "NODE_ENV=bodgeit" -p 3000:3000

In order to inject your own configuration, you can use -v to mount the default.yml path inside the container to any config file on your outside file system:

docker run -d -e "NODE_ENV=myConfig" -v /tmp/myConfig.yml:/juice-shop/config/myConfig.yml -p 3000:3000 --name juice-shop bkimminich/juice-shop

YAML configuration file

The YAML format for customizations is very straightforward. Below you find its syntax along with an excerpt of the default settings.

  • server
    • port to launch the server on. Defaults to 3000
  • application
    • domain used for all user email addresses. Defaults to 'juice-sh.op'
    • name as shown in title and menu bar Defaults to 'OWASP Juice Shop'
    • logo filename in /app/public/images/ or a URL of an image which will first be download to that folder and then used as a logo. Defaults to JuiceShop_Logo.png
    • favicon filename in /app/public/ or a URL of an image in .ico format which will first be download to that folder and then used as a favicon. Defaults to favicon_v2.ico
    • numberOfRandomFakeUsers represents the number of random user accounts to be created on top of the pre-defined ones (which are required for several challenges). Defaults to 0, meaning no additional users are created.
    • showChallengeSolvedNotifications shows or hides all instant "challenge solved"-notifications. Recommended to set to false for awareness demos. Defaults to true.
    • showChallengeHints shows or hides hints for each challenge on hovering over/clicking its "unsolved" badge on the score board. Defaults to true.
    • showVersionNumber shows or hides the software version from the title. Defaults to true.
    • theme the name of the color theme used to render the UI. Options are bluegrey-lightgreen, blue-lightblue, deeppurple-amber, indigo-pink, pink-bluegrey, purple-green and deeporange-indigo. Defaults to bluegrey-lightgreen
    • gitHubRibbon shows or hides the "GitHub" button in the top-right corner of the navigation bar. Defaults to true.
    • twitterUrl used as the Twitter link promising coupon codes on the About Us and Your Basket screen. Defaults to ''
    • facebookUrl used as the Facebook link promising coupon codes on the About Us and Your Basket screen. Defaults to ''
    • slackUrl used as the Slack link on the About Us screen. Defaults to ''
    • pressKitUrl used as the link to logos and media files on the About Us screen. Defaults to ''
    • planetOverlayMap filename in /app/private or URL of an image to download to that folder and then use as an overlay texture for the 3D planet "easter egg". Defaults to orangemap2k.jpg
    • planetName of the 3D planet "easter egg" as shown in the page title. Defaults to Orangeuze
    • recyclePage custom elements on the Request Recycling Box page
      • topProductImage filename in /app/public/images/products to use as the image on the top of the info column on the page. Defaults to fruit_press.jpg
      • bottomProductImage filename in /app/public/images/products to use as the image on the bottom of the info column on the page. Defaults to apple_pressings.jpg
    • altcoinName defines the name of the (fake) crypto currency that is offered on the Token Sale screen. Defaults to Juicycoin
    • cookieConsent defines the cookie consent dialog shown in the bottom right corner
      • backgroundColor of the cookie banner itself. Defaults to '#546e7a'
      • textColor of the message shown in the cookie banner. Defaults to '#ffffff'
      • buttonColor defines the color of the button to dismiss the banner. Defaults to '#558b2f'
      • buttonTextColor of the dismissText on the button. Defaults to '#ffffff'
      • message explains the cookie usage in the application. Defaults to 'This website uses fruit cookies to ensure you get the juiciest tracking experience.'
      • dismissText the text shown on the button to dismiss the banner. Defaults to 'Me want it!'
      • linkText is shown after the message to refer to further information. Defaults to 'But me wait!'
      • linkUrl provides further information about cookie usage. Defaults to ''
    • privacyContactEmail the email address shown as contact in the Privacy Policy. Defaults to
    • securityTxt defines the attributes for the security.txt file based on the Internet draft
      • contact an email address, phone number or URL to report security vulnerabilities to. Can be fake obviously. Defaults to
      • encryption URL to a public encryption key for secure communication. Can be fake obviously. Defaults to
      • acknowledgements URL a "hall of fame" page. Can be fake obviously. Defaults to /#/score-board
    • promotion defines the attributes required for the /promotion screen where a marketing video with subtitles is rendered that hosts the XSS Tier 6 challenge
      • video name of a file with video/mp4 content type in /app/public/videos or URL of an image to download to that folder and then use as the promotion video. Defaults to JuiceShopJingle.mp4
      • subtitles name of a Web Video Text Tracks Format file in /app/public/videos or URL of an image to download to that folder and then use as the promotion video. Defaults to JuiceShopJingle.vtt
  • challenges
    • safetyOverride enables all challenges regardless of any potential harm or danger they might pose for your computer (i.e. XXE or RCE vulnerabilities which could not entirely be sandboxed). Defaults to false
    • overwriteUrlForProductTamperingChallenge the URL that should replace the original URL defined in urlForProductTamperingChallenge for the Product Tampering challenge. Defaults to
  • products list which, when specified, replaces the entire list of default products
    • name of the product (mandatory)
    • description of the product (optional). Defaults to a static placeholder text
    • price of the product (optional). Defaults to a random price
    • image (optional) filename in /app/public/images/products or URL of an image to download to that folder and then use as a product image. Defaults to undefined.png
    • deletedDate of the product in YYYY-MM-DD format (optional). Defaults to null.
    • urlForProductTamperingChallenge sets the original link of the product which is the target for the Product Tampering challenge. Overrides deletedDate with null (must be defined on exactly one product)
    • useForChristmasSpecialChallenge marks a product as the target for the "christmas special" challenge. Overrides deletedDate with 2014-12-27 (must be true on exactly one product)
    • fileForRetrieveBlueprintChallenge (must be true on exactly one product) filename in /app/public/images/products or URL of a file download to that folder and then use as the target for the Retrieve Blueprint challenge. If a filename is specified but the file does not exist in /app/public/images/products the challenge is still solvable by just requesting it from the server. Defaults to JuiceShop.stl. :information_source: To make this challenge realistically solvable, include some kind of hint to the blueprint file's name/type in the product image (e.g. its Exif metadata) or in the product description
    • keywordsForPastebinDataLeakChallenge (must be defined on exactly one product) list of keywords which are all mandatory to mention in a feedback or complaint to solve the DLP Tier 1 challenge. Overrides deletedDate with 2019-02-1. :information_source: To make this challenge realistically solvable, provide the keywords on e.g. PasteBin in an obscured way that works well with the "dangerous ingredients of an unsafe product"" narrative
    • reviews a sub-list which adds reviews to a product (optional)
      • text of the review (mandatory)
      • author of the review from the following list of pre-defined users in the database: admin, jim, bender, ciso, support, morty, amy or mc.safesearch (mandatory)
  • ctf
    • showFlagsInNotifications shows or hides the CTF flag codes in the "challenge solved"-notifications. Is ignored when application.showChallengeSolvedNotifications is set to false. Defaults to false
    • showCountryDetailsInNotifications determines if the country mapped to the solved challenge is displayed in the notification. Can be none, name, flag or both. Only useful for CTFs using FBCTF. Defaults to none
    • countryMapping list which maps challenges to countries on the challenge map of FBCTF. Only needed for CTFs using FBCTF. Defaults to empty ~
      • <challengeName>
        • name the name of the country
        • code the two-letter ISO code of the country

Configuration example

  port: 3000
  domain: juice-sh.op
  name: 'OWASP Juice Shop'
  logo: JuiceShop_Logo.png
  favicon: favicon_v2.ico
  numberOfRandomFakeUsers: 0
  showChallengeSolvedNotifications: true
  showChallengeHints: true
  showVersionNumber: true
  theme: bluegrey-lightgreen
  gitHubRibbon: true
  twitterUrl: ''
  facebookUrl: ''
  slackUrl: ''
  planetOverlayMap: orangemap2k.jpg
  planetName: Orangeuze
    topProductImage: fruit_press.jpg
    bottomProductImage: apple_pressings.jpg
  altcoinName: Juicycoin
    backgroundColor: '#eb6c44'
    textColor: '#ffffff'
    buttonColor: '#f5d948'
    buttonTextColor: '#000000'
    message: 'This website uses fruit cookies to ensure you get the juiciest tracking experience.'
    dismissText: 'Me want it!'
    linkText: 'But me wait!'
    linkUrl: ''
    contact: ''
    encryption: ''
    acknowledgements: '/#/score-board'
    video: JuiceShopJingle.mp4
    subtitles: jingleSubtitles.vtt
  safetyOverride: false
  overwriteUrlForProductTamperingChallenge: ''
    name: 'Apple Juice (1000ml)'
    price: 1.99
    description: 'The all-time classic.'
    image: apple_juice.jpg
      - { text: 'One of my favorites!', author: admin }
# ~~~~~ ... ~~~~~~
    name: 'OWASP SSL Advanced Forensic Tool (O-Saft)'
    description: '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.'
    price: 0.01
    image: orange_juice.jpg
    urlForProductTamperingChallenge: ''
    name: 'Christmas Super-Surprise-Box (2014 Edition)'
    description: 'Contains a random selection of 10 bottles (each 500ml) of our tastiest juices and an extra fan shirt for an unbeatable price!'
    price: 29.99
    image: undefined.jpg
    useForChristmasSpecialChallenge: true
    name: 'OWASP Juice Shop Sticker (2015/2016 design)'
    description: 'Die-cut sticker with the official 2015/2016 logo. By now this is a rare collectors item. <em>Out of stock!</em>'
    price: 999.99
    image: sticker.png
    deletedDate: '2017-04-28'
# ~~~~~ ... ~~~~~~
    name: 'OWASP Juice Shop Logo (3D-printed)'
    description: 'This rare item was designed and handcrafted in Sweden. This is why it is so incredibly expensive despite its complete lack of purpose.'
    price: 99.99
    image: 3d_keychain.jpg
    fileForRetrieveBlueprintChallenge: JuiceShop.stl
# ~~~~~ ... ~~~~~~
  showFlagsInNotifications: false
  showCountryDetailsInNotifications: none
  countryMapping: ~

Overriding default settings

When creating your own YAML configuration file, you can rely on the existing default values and only overwrite what you want to change. The provided config/ctf.yml file for capture-the-flag events for example is as short as this:

  logo: JuiceShopCTF_Logo.png
  favicon: favicon_ctf.ico
  showChallengeHints: false
  showVersionNumber: false
  gitHubRibbon: false
  showFlagsInNotifications: true

Testing customizations

To verify if your custom configuration will not break any of the challenges, you should run the end-to-end tests via npm run protractor. If they pass, all challenges will be working fine!

Provided customizations

The following three customizations are provided out of the box by OWASP Juice Shop:

  • 7 Minute Security: Full conversion for the first podcast that picked up the Juice Shop way before it was famous! :sunglasses:
  • Mozilla-CTF: Another full conversion theme harvested and refined from the Mozilla Austin CTF-event! :earth_americas:
  • The BodgeIt Store: An homage to our server-side rendered ancestor. May it rest in JSPs! :skull:
  • Sick-Shop: A store that offers a variety of illnesses and the original PoC theme for the customization feature. Achoo! Bless you! :mask:
  • CTF-mode: Keeps the Juice Shop in its default layout but disabled hints while enabling CTF flag codes in the "challenge solved"-notifications. Refer to Hosting a CTF event to learn more about running a CTF-event with OWASP Juice Shop. :triangular_flag_on_post:
  • Quiet mode: Keeps the Juice Shop in its default layout but hides all "challenge solved"-notifications, GitHub ribbon and challenge hints. :mute:
  • OWASP Juice Box: If you find jo͞osbäks much easier to pronounce than jo͞osSHäp, this customization is for you. :us:

Mozilla-CTF theme

BodgeIt Store theme

Additional Browser tweaks

Consider you are doing a live demo with a highly customized corporate theme. Your narrative is, that this really is an upcoming eCommerce application of that company. Walking the "happy path" might now lure you into two situations which could spoil the immersion for the audience.

Coupon codes on social media

If you configured the twitterUrl/facebookUrl as the company's own account/page, you will most likely not find any coupon codes posted there. You will probably fail to convince the social media team to tweet or retweet some coupon code for an application that does not even exist!

Coupon Immersion Spoiler

OAuth Login

Another immersion spoiler occurs when demonstrating the Log in with Google functionality, which will show you the application name registered on Google Cloud Platform: OWASP Juice Shop! There is no way to convince Google to show anything else for obvious trust and integrity reasons.

OAuth Immersion Spoiler

On-the-fly text replacement

You can solve both of the above problems in your own Browser by replacing text on the fly when the Twitter, Facebook or Google-Login page is loaded. For Chrome Word Replacer II is a plugin that does this work for you with very little setup effort. For Firefox FoxReplace does a similar job. After installing either plugin you have to create two text replacements:

  1. Create a replacement for OWASP Juice Shop (as it appears on Google-Login) with your own application name. Best use from your configuration.
  2. Create another replacement for a complete or partial Tweet or Facebook post with some marketing text and an actual coupon code. You can get valid coupon codes from the OWASP Juice Shop Twitter feed:

    Word Replacer II

  3. Enable the plugin and verify your replacements work:

Coupon Immersion Replacement

OAuth Immersion Replacement

results matching ""

    No results matching ""