diff --git a/.codeclimate.yml b/.codeclimate.yml index be79bb94..1ab77259 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -1,28 +1,28 @@ -version: "2" -plugins: - fixme: - enabled: true - duplication: - enabled: true -checks: - file-lines: - config: - threshold: 300 - method-lines: - config: - threshold: 30 - method-complexity: - config: - threshold: 7 - similar-code: - enabled: false - identical-code: - enabled: false -exclude_patterns: - - 'Gruntfile.js' - - '**/*conf.js' - - 'data/datacreator.ts' - - 'frontend/src/hacking-instructor/**/*.ts' - - 'frontend/src/assets/private/*.js' - - 'lib/logger.ts' - - 'lib/config.types.ts' +version: "2" +plugins: + fixme: + enabled: true + duplication: + enabled: true +checks: + file-lines: + config: + threshold: 300 + method-lines: + config: + threshold: 30 + method-complexity: + config: + threshold: 7 + similar-code: + enabled: false + identical-code: + enabled: false +exclude_patterns: + - 'Gruntfile.js' + - '**/*conf.js' + - 'data/datacreator.ts' + - 'frontend/src/hacking-instructor/**/*.ts' + - 'frontend/src/assets/private/*.js' + - 'lib/logger.ts' + - 'lib/config.types.ts' diff --git a/.dependabot/config.yml b/.dependabot/config.yml index ed8eba07..88f7d64e 100644 --- a/.dependabot/config.yml +++ b/.dependabot/config.yml @@ -1,31 +1,31 @@ -version: 1 -update_configs: - - package_manager: "javascript" - directory: "/" - update_schedule: "live" - target_branch: "develop" - default_reviewers: - - "bkimminich" - default_labels: - - "dependencies" - ignored_updates: - - match: - dependency_name: "express-jwt" - version_requirement: "0.1.3" - - match: - dependency_name: "sanitize-html" - version_requirement: "1.4.2" - - match: - dependency_name: "unzipper" - version_requirement: "0.9.15" - - match: - dependency_name: "jsonwebtoken" - version_requirement: "0.4.0" - - package_manager: "javascript" - directory: "/frontend" - update_schedule: "live" - target_branch: "develop" - default_reviewers: - - "bkimminich" - default_labels: - - "dependencies" +version: 1 +update_configs: + - package_manager: "javascript" + directory: "/" + update_schedule: "live" + target_branch: "develop" + default_reviewers: + - "bkimminich" + default_labels: + - "dependencies" + ignored_updates: + - match: + dependency_name: "express-jwt" + version_requirement: "0.1.3" + - match: + dependency_name: "sanitize-html" + version_requirement: "1.4.2" + - match: + dependency_name: "unzipper" + version_requirement: "0.9.15" + - match: + dependency_name: "jsonwebtoken" + version_requirement: "0.4.0" + - package_manager: "javascript" + directory: "/frontend" + update_schedule: "live" + target_branch: "develop" + default_reviewers: + - "bkimminich" + default_labels: + - "dependencies" diff --git a/.devcontainer.json b/.devcontainer.json index a81e1e9d..11d19953 100644 --- a/.devcontainer.json +++ b/.devcontainer.json @@ -1,14 +1,14 @@ -{ - "extensions": [ - "eg2.vscode-npm-script", - "angular.ng-template", - "dbaeumer.vscode-eslint", - "stylelint.vscode-stylelint" - ], - "settings": { - "eslint.workingDirectories": [ - { "mode": "auto" } - ] - }, - "postCreateCommand": "export NG_CLI_ANALYTICS=ci && export NG_FORCE_TTY=false && npm i -g @angular/cli && npm install && unset NG_FORCE_TTY" +{ + "extensions": [ + "eg2.vscode-npm-script", + "angular.ng-template", + "dbaeumer.vscode-eslint", + "stylelint.vscode-stylelint" + ], + "settings": { + "eslint.workingDirectories": [ + { "mode": "auto" } + ] + }, + "postCreateCommand": "export NG_CLI_ANALYTICS=ci && export NG_FORCE_TTY=false && npm i -g @angular/cli && npm install && unset NG_FORCE_TTY" } \ No newline at end of file diff --git a/.dockerignore b/.dockerignore index 4fcadbb6..09b8a08d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,17 +1,17 @@ -.git/ -monitoring/ -node_modules/ -screenshots/ -test/ -build/reports/ -dist/ -vagrant/ -logs/ -Dockerfile -.npmrc -/bom.json -/bom.xml - -# Pattern is *not covered* by node_modules/ above no matter what IntelliJ says! -frontend/node_modules/ -frontend/dist/ +.git/ +monitoring/ +node_modules/ +screenshots/ +test/ +build/reports/ +dist/ +vagrant/ +logs/ +Dockerfile +.npmrc +/bom.json +/bom.xml + +# Pattern is *not covered* by node_modules/ above no matter what IntelliJ says! +frontend/node_modules/ +frontend/dist/ diff --git a/.eslintrc.js b/.eslintrc.js index a52d6e7a..e3aed21c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,43 +1,43 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -module.exports = { - extends: 'standard-with-typescript', - env: { - browser: true, - node: true, - jasmine: true, - mocha: true, - jest: true - }, - globals: { - Atomics: 'readonly', - SharedArrayBuffer: 'readonly' - }, - parserOptions: { - ecmaVersion: 2018, - project: './tsconfig.json' - }, - ignorePatterns: [ - '.eslintrc.js', - 'app/private/**', - 'vagrant/**', - 'frontend/**', - 'dist/**' - ], - overrides: [ - { - files: ['**/*.ts'], - parser: '@typescript-eslint/parser', - rules: { - 'no-void': 'off', // conflicting with recommendation from @typescript-eslint/no-floating-promises - // FIXME warnings below this line need to be checked and fixed. - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/strict-boolean-expressions': 'off', - '@typescript-eslint/no-var-requires': 'off' - } - } - ] -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +module.exports = { + extends: 'standard-with-typescript', + env: { + browser: true, + node: true, + jasmine: true, + mocha: true, + jest: true + }, + globals: { + Atomics: 'readonly', + SharedArrayBuffer: 'readonly' + }, + parserOptions: { + ecmaVersion: 2018, + project: './tsconfig.json' + }, + ignorePatterns: [ + '.eslintrc.js', + 'app/private/**', + 'vagrant/**', + 'frontend/**', + 'dist/**' + ], + overrides: [ + { + files: ['**/*.ts'], + parser: '@typescript-eslint/parser', + rules: { + 'no-void': 'off', // conflicting with recommendation from @typescript-eslint/no-floating-promises + // FIXME warnings below this line need to be checked and fixed. + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/strict-boolean-expressions': 'off', + '@typescript-eslint/no-var-requires': 'off' + } + } + ] +} diff --git a/.gitignore b/.gitignore index be7ab3a2..e58017da 100644 --- a/.gitignore +++ b/.gitignore @@ -1,65 +1,69 @@ -# App -node_modules/ -juiceshop.sqlite -order_*.pdf -app/ -!frontend/src/app -uploads/complaints/*.* -!uploads/complaints/.gitkeep -ftp/legal.md -i18n/*.json -i18n/*.invalid -!frontend/src/assets/i18n/*.json -!data/static/i18n/*.json -data/chatbot/*.* -!data/chatbot/.gitkeep -/data/juiceshop.sqlite-journal - -# Build -.nyc_output/ -.sass-cache/ -build/ -cache/ -dist/ -logs/ -vagrant/.vagrant/ -*.orig -*.out -*.log -JSON -JSON.map -frontend/src/**/*.js -/bom.json -/bom.xml - -# IDEs -.idea/ -.vscode/ -out/ -*.eml -*.iml -*.iws -*.swp - -# Branch ghpages -assets/ -!frontend/src/assets/ - -# Custom configuration files -config/*.yml -!config/addo.yml -!config/bodgeit.yml -!config/ctf.yml -!config/fbctf.yml -!config/default.yml -!config/juicebox.yml -!config/quiet.yml -!config/test.yml -!config/7ms.yml -!config/mozilla.yml -!config/unsafe.yml -!config/tutorial.yml -!config/oss.yml - -# System Files -.DS_Store \ No newline at end of file +# App +node_modules/ +juiceshop.sqlite +order_*.pdf +app/ +!frontend/src/app +uploads/complaints/*.* +!uploads/complaints/.gitkeep +ftp/legal.md +i18n/*.json +i18n/*.invalid +!frontend/src/assets/i18n/*.json +!data/static/i18n/*.json +data/chatbot/*.* +!data/chatbot/.gitkeep +/data/juiceshop.sqlite-journal + +# Build +.nyc_output/ +.sass-cache/ +build/ +cache/ +dist/ +logs/ +vagrant/.vagrant/ +*.orig +*.out +*.log +JSON +JSON.map +frontend/src/**/*.js +/bom.json +/bom.xml + +# IDEs +.idea/ +.vscode/ +out/ +*.eml +*.iml +*.iws +*.swp + +# Branch ghpages +assets/ +!frontend/src/assets/ + +# Custom configuration files +config/*.yml +!config/addo.yml +!config/bodgeit.yml +!config/ctf.yml +!config/fbctf.yml +!config/default.yml +!config/juicebox.yml +!config/quiet.yml +!config/test.yml +!config/7ms.yml +!config/mozilla.yml +!config/unsafe.yml +!config/tutorial.yml +!config/oss.yml + +# System Files +.DS_Store + +.env +*.output.yml +output.yml \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7b5f3c01..bf984ac6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ -include: - - template: Auto-DevOps.gitlab-ci.yml - -variables: - SAST_EXCLUDED_PATHS: "frontend/src/assets/private/**" - TEST_DISABLED: "true" - DAST_DISABLED: "true" +include: + - template: Auto-DevOps.gitlab-ci.yml + +variables: + SAST_EXCLUDED_PATHS: "frontend/src/assets/private/**" + TEST_DISABLED: "true" + DAST_DISABLED: "true" diff --git a/.gitpod.yml b/.gitpod.yml index 45443b40..1e1b59db 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -1,9 +1,9 @@ -tasks: - - init: npm install - command: npm start - -ports: - - name: OWASP Juice Shop - description: The Juice Shop web server - port: 3000 - onOpen: open-preview +tasks: + - init: npm install + command: npm start + +ports: + - name: OWASP Juice Shop + description: The Juice Shop web server + port: 3000 + onOpen: open-preview diff --git a/.mailmap b/.mailmap index a76aace3..1fc353da 100644 --- a/.mailmap +++ b/.mailmap @@ -1,30 +1,30 @@ -Aashish683 Aashish Singh <30633088+Aashish683@users.noreply.github.com> -Alejandro Saenz Alejandro Saenz -Björn Kimminich Bjoern Kimminich -Björn Kimminich Bjoern Kimminich -Björn Kimminich Björn Kimminich -Björn Kimminich Björn Kimminich -Björn Kimminich bjoern.kimminich -Björn Kimminich Björn Kimminich -CaptainFreak CaptainFreak -Jannik Hollenbach J12934 <13718901+J12934@users.noreply.github.com> -Jannik Hollenbach Jannik Hollenbach <13718901+J12934@users.noreply.github.com> -Jannik Hollenbach Jannik Hollenbach -Jannik Hollenbach Jannik Hollenbach -Jannik Hollenbach Jannik Hollenbach -JamesCullum <5477111+JamesCullum@users.noreply.github.com> JamesCullum -MarcRler Marc Rüttler -MarcRler MarcRler -Nat McHugh Nathaniel McHugh -Simon Basset Simon Basset -Supratik Das Supratik Das <30755453+supra08@users.noreply.github.com> -Timo Pagel Timo Pagel -Timo Pagel Timo Pagel -Timo Pagel tpagel -Timo Pagel wurstbrot -Viktor Lindström ViktorLindstrm -aaryan10 Aaryan Budhiraja <31697449+aaryan01@users.noreply.github.com> -agrawalarpit14 Arpit Agrawal <35000671+agrawalarpit14@users.noreply.github.com> -greenkeeper[bot] greenkeeper[bot] <23040076+greenkeeper[bot]@users.noreply.github.com> -omerlh Omer Levi Hevroni -Scar26 Mohit Sharma <41830515+Scar26@users.noreply.github.com> +Aashish683 Aashish Singh <30633088+Aashish683@users.noreply.github.com> +Alejandro Saenz Alejandro Saenz +Björn Kimminich Bjoern Kimminich +Björn Kimminich Bjoern Kimminich +Björn Kimminich Björn Kimminich +Björn Kimminich Björn Kimminich +Björn Kimminich bjoern.kimminich +Björn Kimminich Björn Kimminich +CaptainFreak CaptainFreak +Jannik Hollenbach J12934 <13718901+J12934@users.noreply.github.com> +Jannik Hollenbach Jannik Hollenbach <13718901+J12934@users.noreply.github.com> +Jannik Hollenbach Jannik Hollenbach +Jannik Hollenbach Jannik Hollenbach +Jannik Hollenbach Jannik Hollenbach +JamesCullum <5477111+JamesCullum@users.noreply.github.com> JamesCullum +MarcRler Marc Rüttler +MarcRler MarcRler +Nat McHugh Nathaniel McHugh +Simon Basset Simon Basset +Supratik Das Supratik Das <30755453+supra08@users.noreply.github.com> +Timo Pagel Timo Pagel +Timo Pagel Timo Pagel +Timo Pagel tpagel +Timo Pagel wurstbrot +Viktor Lindström ViktorLindstrm +aaryan10 Aaryan Budhiraja <31697449+aaryan01@users.noreply.github.com> +agrawalarpit14 Arpit Agrawal <35000671+agrawalarpit14@users.noreply.github.com> +greenkeeper[bot] greenkeeper[bot] <23040076+greenkeeper[bot]@users.noreply.github.com> +omerlh Omer Levi Hevroni +Scar26 Mohit Sharma <41830515+Scar26@users.noreply.github.com> diff --git a/.well-known/csaf/2017/juice-shop-sa-20200513-express-jwt.json b/.well-known/csaf/2017/juice-shop-sa-20200513-express-jwt.json index 444dea10..662ba90b 100644 --- a/.well-known/csaf/2017/juice-shop-sa-20200513-express-jwt.json +++ b/.well-known/csaf/2017/juice-shop-sa-20200513-express-jwt.json @@ -1,121 +1,121 @@ -{ - "document": { - "acknowledgments": [ - { - "organization": "OWASP Juice Shop", - "summary": "Probably the most modern and sophisticated insecure web application" - } - ], - "aggregate_severity": { - "text": "Critical" - }, - "category": "csaf_security_advisory", - "csaf_version": "2.0", - "lang": "en", - "notes": [ - { - "category": "legal_disclaimer", - "text": "The Juice Shop contains vulnerabilities. Only use it in an isolated. ONLY run the Juice Shop in a training environment.", - "title": "Isolated Env." - } - ], - "publisher": { - "category": "vendor", - "contact_details": "timo.pagel@owasp.org", - "issuing_authority": "OWASP Juice Shop", - "name": "OWASP Juice Shop Core Team", - "namespace": "https://github.com/juice-shop/juice-shop" - }, - "title": "juice-shop-sa-20200513-express-jwt", - "tracking": { - "current_release_date": "2024-03-03T11:00:00.000Z", - "generator": { - "date": "2024-03-03T19:30:53.428Z", - "engine": { - "name": "Secvisogram", - "version": "2.5.0" - } - }, - "id": "juice-shop-sa-20200513-express-jwt", - "initial_release_date": "2024-03-03T11:00:00.000Z", - "revision_history": [ - { - "date": "2024-03-03T11:00:00.000Z", - "number": "1.0.0", - "summary": "Initial public release." - } - ], - "status": "final", - "version": "1.0.0" - } - }, - "product_tree": { - "branches": [ - { - "category": "product_version_range", - "name": ">=v6.0.0", - "product": { - "name": "OWASP Juice Shop", - "product_id": "juice-shop/juice-shop", - "product_identification_helper": { - "purl": "pkg:docker/bkimminich/juice-shop" - } - } - } - ] - }, - "vulnerabilities": [ - { - "cve": "CVE-2020-15084", - "notes": [ - { - "category": "details", - "text": "The Juice Shop is currently vulnerable to JWT null algorithm attacks . We will soon release a patch", - "title": "Vulnerable to Null JWT Algorithm" - } - ], - "product_status": { - "known_affected": [ - "juice-shop/juice-shop" - ] - }, - "remediations": [ - { - "category": "workaround", - "date": "2020-07-01T10:00:00.000Z", - "details": "Check for the expected JWT algorithm type in a WAF/Proxy/Loadbalancer in front of the Juice Shop.", - "product_ids": [ - "juice-shop/juice-shop" - ], - "url": "https://github.com/advisories/GHSA-6g6m-m6h5-w9gf" - } - ], - "scores": [ - { - "cvss_v3": { - "attackComplexity": "LOW", - "attackVector": "NETWORK", - "availabilityImpact": "NONE", - "baseScore": 9.1, - "baseSeverity": "CRITICAL", - "confidentialityImpact": "HIGH", - "environmentalScore": 9.1, - "environmentalSeverity": "CRITICAL", - "integrityImpact": "HIGH", - "privilegesRequired": "NONE", - "scope": "UNCHANGED", - "temporalScore": 9.1, - "temporalSeverity": "CRITICAL", - "userInteraction": "NONE", - "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", - "version": "3.1" - }, - "products": [ - "juice-shop/juice-shop" - ] - } - ], - "title": "CVE-2020-15084" - } - ] -} +{ + "document": { + "acknowledgments": [ + { + "organization": "OWASP Juice Shop", + "summary": "Probably the most modern and sophisticated insecure web application" + } + ], + "aggregate_severity": { + "text": "Critical" + }, + "category": "csaf_security_advisory", + "csaf_version": "2.0", + "lang": "en", + "notes": [ + { + "category": "legal_disclaimer", + "text": "The Juice Shop contains vulnerabilities. Only use it in an isolated. ONLY run the Juice Shop in a training environment.", + "title": "Isolated Env." + } + ], + "publisher": { + "category": "vendor", + "contact_details": "timo.pagel@owasp.org", + "issuing_authority": "OWASP Juice Shop", + "name": "OWASP Juice Shop Core Team", + "namespace": "https://github.com/juice-shop/juice-shop" + }, + "title": "juice-shop-sa-20200513-express-jwt", + "tracking": { + "current_release_date": "2024-03-03T11:00:00.000Z", + "generator": { + "date": "2024-03-03T19:30:53.428Z", + "engine": { + "name": "Secvisogram", + "version": "2.5.0" + } + }, + "id": "juice-shop-sa-20200513-express-jwt", + "initial_release_date": "2024-03-03T11:00:00.000Z", + "revision_history": [ + { + "date": "2024-03-03T11:00:00.000Z", + "number": "1.0.0", + "summary": "Initial public release." + } + ], + "status": "final", + "version": "1.0.0" + } + }, + "product_tree": { + "branches": [ + { + "category": "product_version_range", + "name": ">=v6.0.0", + "product": { + "name": "OWASP Juice Shop", + "product_id": "juice-shop/juice-shop", + "product_identification_helper": { + "purl": "pkg:docker/bkimminich/juice-shop" + } + } + } + ] + }, + "vulnerabilities": [ + { + "cve": "CVE-2020-15084", + "notes": [ + { + "category": "details", + "text": "The Juice Shop is currently vulnerable to JWT null algorithm attacks . We will soon release a patch", + "title": "Vulnerable to Null JWT Algorithm" + } + ], + "product_status": { + "known_affected": [ + "juice-shop/juice-shop" + ] + }, + "remediations": [ + { + "category": "workaround", + "date": "2020-07-01T10:00:00.000Z", + "details": "Check for the expected JWT algorithm type in a WAF/Proxy/Loadbalancer in front of the Juice Shop.", + "product_ids": [ + "juice-shop/juice-shop" + ], + "url": "https://github.com/advisories/GHSA-6g6m-m6h5-w9gf" + } + ], + "scores": [ + { + "cvss_v3": { + "attackComplexity": "LOW", + "attackVector": "NETWORK", + "availabilityImpact": "NONE", + "baseScore": 9.1, + "baseSeverity": "CRITICAL", + "confidentialityImpact": "HIGH", + "environmentalScore": 9.1, + "environmentalSeverity": "CRITICAL", + "integrityImpact": "HIGH", + "privilegesRequired": "NONE", + "scope": "UNCHANGED", + "temporalScore": 9.1, + "temporalSeverity": "CRITICAL", + "userInteraction": "NONE", + "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", + "version": "3.1" + }, + "products": [ + "juice-shop/juice-shop" + ] + } + ], + "title": "CVE-2020-15084" + } + ] +} diff --git a/.well-known/csaf/2017/juice-shop-sa-20200513-express-jwt.json.asc b/.well-known/csaf/2017/juice-shop-sa-20200513-express-jwt.json.asc index 610c71b9..cb2aafe7 100644 --- a/.well-known/csaf/2017/juice-shop-sa-20200513-express-jwt.json.asc +++ b/.well-known/csaf/2017/juice-shop-sa-20200513-express-jwt.json.asc @@ -1,7 +1,7 @@ ------BEGIN PGP SIGNATURE----- - -iHUEABYKAB0WIQQjcrKxKup64wAbs/vQj7FuICnYcAUCZid3ggAKCRDQj7FuICnY -cItlAP4tS43N//qIKXUZTLOMnd8cRMv25KfRF5WZ3OazSZxyLAEAkQluY3UwxO0m -Ybd/wfOOJ9DE7qjjZyFcf6le4Bl1pAI= -=n7jT ------END PGP SIGNATURE----- +-----BEGIN PGP SIGNATURE----- + +iHUEABYKAB0WIQQjcrKxKup64wAbs/vQj7FuICnYcAUCZid3ggAKCRDQj7FuICnY +cItlAP4tS43N//qIKXUZTLOMnd8cRMv25KfRF5WZ3OazSZxyLAEAkQluY3UwxO0m +Ybd/wfOOJ9DE7qjjZyFcf6le4Bl1pAI= +=n7jT +-----END PGP SIGNATURE----- diff --git a/.well-known/csaf/2017/juice-shop-sa-20200513-express-jwt.json.sha512 b/.well-known/csaf/2017/juice-shop-sa-20200513-express-jwt.json.sha512 index ca05f552..7d1cf6c0 100644 --- a/.well-known/csaf/2017/juice-shop-sa-20200513-express-jwt.json.sha512 +++ b/.well-known/csaf/2017/juice-shop-sa-20200513-express-jwt.json.sha512 @@ -1 +1 @@ -7e7ce7c65db3bf0625fcea4573d25cff41f2f7e3474f2c74334b14fc65bb4fd26af802ad17a3a03bf0eee6827a00fb8f7905f338c31b5e6ea9cb31620242e843 juice-shop-sa-20200513-express-jwt.json +7e7ce7c65db3bf0625fcea4573d25cff41f2f7e3474f2c74334b14fc65bb4fd26af802ad17a3a03bf0eee6827a00fb8f7905f338c31b5e6ea9cb31620242e843 juice-shop-sa-20200513-express-jwt.json diff --git a/.well-known/csaf/2021/juice-shop-sa-20211014-proto.json b/.well-known/csaf/2021/juice-shop-sa-20211014-proto.json index 1a943a6f..875cf2b7 100644 --- a/.well-known/csaf/2021/juice-shop-sa-20211014-proto.json +++ b/.well-known/csaf/2021/juice-shop-sa-20211014-proto.json @@ -1,85 +1,85 @@ -{ - "document": { - "acknowledgments": [ - { - "organization": "OWASP Juice Shop", - "summary": "Probably the most modern and sophisticated insecure web application" - } - ], - "aggregate_severity": { - "text": "High" - }, - "category": "csaf_security_advisory", - "csaf_version": "2.0", - "lang": "en", - "notes": [ - { - "category": "legal_disclaimer", - "text": "The Juice Shop contains vulnerabilities. Only use it in an isolated. ONLY run the Juice Shop in a training environment.", - "title": "Isolated Env." - } - ], - "publisher": { - "category": "vendor", - "contact_details": "timo.pagel@owasp.org", - "issuing_authority": "OWASP Juice Shop", - "name": "OWASP Juice Shop Core Team", - "namespace": "https://github.com/juice-shop/juice-shop" - }, - "title": "juice-shop-sa-20211014-proto", - "tracking": { - "current_release_date": "2021-10-14T10:00:00.000Z", - "generator": { - "date": "2024-03-09T14:24:03.158Z", - "engine": { - "name": "Secvisogram", - "version": "2.5.0" - } - }, - "id": "juice-shop-sa-20211014-proto", - "initial_release_date": "2024-03-03T11:00:00.000Z", - "revision_history": [ - { - "date": "2024-03-03T11:00:00.000Z", - "number": "1.0.0", - "summary": "Initial public release." - } - ], - "status": "final", - "version": "1.0.0" - } - }, - "product_tree": { - "branches": [ - { - "category": "product_version_range", - "name": ">=v12.10.2", - "product": { - "name": "OWASP Juice Shop", - "product_id": "juice-shop/juice-shop", - "product_identification_helper": { - "purl": "pkg:docker/bkimminich/juice-shop" - } - } - } - ] - }, - "vulnerabilities": [ - { - "cve": "CVE-2020-36604", - "notes": [ - { - "category": "details", - "text": "A proof of an exploit does not exists, but it might be possible to exploit the Juice Shop through the vulnerability.", - "title": "Notes" - } - ], - "product_status": { - "known_affected": [ - "juice-shop/juice-shop" - ] - }, - "title": "The Juice Shop uses the library hoek which might be subject to prototype pollution via the clone function." - } - ] -} +{ + "document": { + "acknowledgments": [ + { + "organization": "OWASP Juice Shop", + "summary": "Probably the most modern and sophisticated insecure web application" + } + ], + "aggregate_severity": { + "text": "High" + }, + "category": "csaf_security_advisory", + "csaf_version": "2.0", + "lang": "en", + "notes": [ + { + "category": "legal_disclaimer", + "text": "The Juice Shop contains vulnerabilities. Only use it in an isolated. ONLY run the Juice Shop in a training environment.", + "title": "Isolated Env." + } + ], + "publisher": { + "category": "vendor", + "contact_details": "timo.pagel@owasp.org", + "issuing_authority": "OWASP Juice Shop", + "name": "OWASP Juice Shop Core Team", + "namespace": "https://github.com/juice-shop/juice-shop" + }, + "title": "juice-shop-sa-20211014-proto", + "tracking": { + "current_release_date": "2021-10-14T10:00:00.000Z", + "generator": { + "date": "2024-03-09T14:24:03.158Z", + "engine": { + "name": "Secvisogram", + "version": "2.5.0" + } + }, + "id": "juice-shop-sa-20211014-proto", + "initial_release_date": "2024-03-03T11:00:00.000Z", + "revision_history": [ + { + "date": "2024-03-03T11:00:00.000Z", + "number": "1.0.0", + "summary": "Initial public release." + } + ], + "status": "final", + "version": "1.0.0" + } + }, + "product_tree": { + "branches": [ + { + "category": "product_version_range", + "name": ">=v12.10.2", + "product": { + "name": "OWASP Juice Shop", + "product_id": "juice-shop/juice-shop", + "product_identification_helper": { + "purl": "pkg:docker/bkimminich/juice-shop" + } + } + } + ] + }, + "vulnerabilities": [ + { + "cve": "CVE-2020-36604", + "notes": [ + { + "category": "details", + "text": "A proof of an exploit does not exists, but it might be possible to exploit the Juice Shop through the vulnerability.", + "title": "Notes" + } + ], + "product_status": { + "known_affected": [ + "juice-shop/juice-shop" + ] + }, + "title": "The Juice Shop uses the library hoek which might be subject to prototype pollution via the clone function." + } + ] +} diff --git a/.well-known/csaf/2021/juice-shop-sa-20211014-proto.json.asc b/.well-known/csaf/2021/juice-shop-sa-20211014-proto.json.asc index 851e714e..79d9150f 100644 --- a/.well-known/csaf/2021/juice-shop-sa-20211014-proto.json.asc +++ b/.well-known/csaf/2021/juice-shop-sa-20211014-proto.json.asc @@ -1,7 +1,7 @@ ------BEGIN PGP SIGNATURE----- - -iHUEABYKAB0WIQQjcrKxKup64wAbs/vQj7FuICnYcAUCZid3yAAKCRDQj7FuICnY -cJo1AP0ZdiEeoFAUcCm6j6lrGIbrPjElYFcgeX1yRbx1plzaCwEA4BH2nvY/VuLH -cZI6JuYTsPoeAkzwDsWWTCJGM7u12QU= -=UeTn ------END PGP SIGNATURE----- +-----BEGIN PGP SIGNATURE----- + +iHUEABYKAB0WIQQjcrKxKup64wAbs/vQj7FuICnYcAUCZid3yAAKCRDQj7FuICnY +cJo1AP0ZdiEeoFAUcCm6j6lrGIbrPjElYFcgeX1yRbx1plzaCwEA4BH2nvY/VuLH +cZI6JuYTsPoeAkzwDsWWTCJGM7u12QU= +=UeTn +-----END PGP SIGNATURE----- diff --git a/.well-known/csaf/2021/juice-shop-sa-20211014-proto.json.sha512 b/.well-known/csaf/2021/juice-shop-sa-20211014-proto.json.sha512 index a51b30b5..d5769bd1 100644 --- a/.well-known/csaf/2021/juice-shop-sa-20211014-proto.json.sha512 +++ b/.well-known/csaf/2021/juice-shop-sa-20211014-proto.json.sha512 @@ -1 +1 @@ -c4eedb2d5ac0b0c11666d87247e1011de4fa5db7e741a4c090374a039e1ce31210d08e63b27d5fabb307705ebbfa1bbbcfe56e5ba0c3528deb00af273f670778 juice-shop-sa-20211014-proto.json +c4eedb2d5ac0b0c11666d87247e1011de4fa5db7e741a4c090374a039e1ce31210d08e63b27d5fabb307705ebbfa1bbbcfe56e5ba0c3528deb00af273f670778 juice-shop-sa-20211014-proto.json diff --git a/.well-known/csaf/2024/juice-shop-sa-disclaimer.json b/.well-known/csaf/2024/juice-shop-sa-disclaimer.json index 4361fd2f..b2069d65 100644 --- a/.well-known/csaf/2024/juice-shop-sa-disclaimer.json +++ b/.well-known/csaf/2024/juice-shop-sa-disclaimer.json @@ -1,141 +1,141 @@ -{ - "document": { - "acknowledgments": [ - { - "organization": "OWASP", - "summary": "Probably the most modern and sophisticated insecure web application" - } - ], - "aggregate_severity": { - "text": "Critical" - }, - "category": "csaf_security_advisory", - "csaf_version": "2.1", - "distribution": { - "tlp": { - "label": "WHITE" - } - }, - "lang": "en", - "notes": [ - { - "category": "legal_disclaimer", - "text": "The Juice Shop contains vulnerabilities. ONLY run the Juice Shop in an isolated training environment.", - "title": "Isolated Env." - } - ], - "publisher": { - "category": "vendor", - "contact_details": "jannik.hollenbach@owasp.org;timo.pagel@owasp.org", - "issuing_authority": "OWASP Juice Shop", - "name": "OWASP Juice Shop Core Team", - "namespace": "https://github.com/juice-shop/juice-shop" - }, - "title": "juice-shop-sa-disclaimer", - "tracking": { - "current_release_date": "2024-03-03T11:00:00.000Z", - "generator": { - "date": "2024-04-23T08:32:41.092Z", - "engine": { - "name": "Secvisogram", - "version": "2.5.2" - } - }, - "id": "juice-shop-sa-disclaimer", - "initial_release_date": "2024-03-03T11:00:00.000Z", - "revision_history": [ - { - "date": "2024-03-03T11:00:00.000Z", - "number": "1.0.0", - "summary": "Initial public release." - } - ], - "status": "final", - "version": "1.0.0" - } - }, - "product_tree": { - "branches": [ - { - "category": "product_version_range", - "name": "vers:all/>=0.0.1", - "product": { - "name": "OWASP Juice Shop", - "product_id": "juice-shop/juice-shop", - "product_identification_helper": { - "purl": "pkg:docker/bkimminich/juice-shop" - } - } - }, - { - "category": "product_version_range", - "name": "vers:all/>=17.0.0", - "product": { - "name": "OWASP Juice Shop", - "product_id": "juice-shop/juice-shop-17-or-later" - } - } - ] - }, - "vulnerabilities": [ - { - "notes": [ - { - "category": "details", - "text": "The Juice Shop has intentional vulnerabilities which might be abused to attack your system", - "title": "Intentional Vulnerable Juice Shop" - } - ], - "product_status": { - "known_affected": [ - "juice-shop/juice-shop" - ] - }, - "remediations": [ - { - "category": "no_fix_planned", - "date": "2024-03-03T11:00:00.000Z", - "details": "ONLY run the Juice Shop in an isolated training environment.", - "product_ids": [ - "juice-shop/juice-shop" - ] - }, - { - "category": "mitigation", - "date": "2024-03-10T08:46:00.000Z", - "details": "Explicitly enable safetyMode to disable unsecure challenges.\n\n```yaml\nchallenges:\n safetyMode: enabled\n```\n", - "product_ids": [ - "juice-shop/juice-shop-17-or-later" - ], - "url": "https://github.com/juice-shop/juice-shop/issues/2174" - } - ], - "scores": [ - { - "cvss_v3": { - "attackComplexity": "LOW", - "attackVector": "NETWORK", - "availabilityImpact": "NONE", - "baseScore": 9.1, - "baseSeverity": "CRITICAL", - "confidentialityImpact": "HIGH", - "environmentalScore": 9.1, - "environmentalSeverity": "CRITICAL", - "integrityImpact": "HIGH", - "privilegesRequired": "NONE", - "scope": "UNCHANGED", - "temporalScore": 9.1, - "temporalSeverity": "CRITICAL", - "userInteraction": "NONE", - "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", - "version": "3.1" - }, - "products": [ - "juice-shop/juice-shop" - ] - } - ], - "title": "Intentional Vulnerabilities" - } - ] -} +{ + "document": { + "acknowledgments": [ + { + "organization": "OWASP", + "summary": "Probably the most modern and sophisticated insecure web application" + } + ], + "aggregate_severity": { + "text": "Critical" + }, + "category": "csaf_security_advisory", + "csaf_version": "2.1", + "distribution": { + "tlp": { + "label": "WHITE" + } + }, + "lang": "en", + "notes": [ + { + "category": "legal_disclaimer", + "text": "The Juice Shop contains vulnerabilities. ONLY run the Juice Shop in an isolated training environment.", + "title": "Isolated Env." + } + ], + "publisher": { + "category": "vendor", + "contact_details": "jannik.hollenbach@owasp.org;timo.pagel@owasp.org", + "issuing_authority": "OWASP Juice Shop", + "name": "OWASP Juice Shop Core Team", + "namespace": "https://github.com/juice-shop/juice-shop" + }, + "title": "juice-shop-sa-disclaimer", + "tracking": { + "current_release_date": "2024-03-03T11:00:00.000Z", + "generator": { + "date": "2024-04-23T08:32:41.092Z", + "engine": { + "name": "Secvisogram", + "version": "2.5.2" + } + }, + "id": "juice-shop-sa-disclaimer", + "initial_release_date": "2024-03-03T11:00:00.000Z", + "revision_history": [ + { + "date": "2024-03-03T11:00:00.000Z", + "number": "1.0.0", + "summary": "Initial public release." + } + ], + "status": "final", + "version": "1.0.0" + } + }, + "product_tree": { + "branches": [ + { + "category": "product_version_range", + "name": "vers:all/>=0.0.1", + "product": { + "name": "OWASP Juice Shop", + "product_id": "juice-shop/juice-shop", + "product_identification_helper": { + "purl": "pkg:docker/bkimminich/juice-shop" + } + } + }, + { + "category": "product_version_range", + "name": "vers:all/>=17.0.0", + "product": { + "name": "OWASP Juice Shop", + "product_id": "juice-shop/juice-shop-17-or-later" + } + } + ] + }, + "vulnerabilities": [ + { + "notes": [ + { + "category": "details", + "text": "The Juice Shop has intentional vulnerabilities which might be abused to attack your system", + "title": "Intentional Vulnerable Juice Shop" + } + ], + "product_status": { + "known_affected": [ + "juice-shop/juice-shop" + ] + }, + "remediations": [ + { + "category": "no_fix_planned", + "date": "2024-03-03T11:00:00.000Z", + "details": "ONLY run the Juice Shop in an isolated training environment.", + "product_ids": [ + "juice-shop/juice-shop" + ] + }, + { + "category": "mitigation", + "date": "2024-03-10T08:46:00.000Z", + "details": "Explicitly enable safetyMode to disable unsecure challenges.\n\n```yaml\nchallenges:\n safetyMode: enabled\n```\n", + "product_ids": [ + "juice-shop/juice-shop-17-or-later" + ], + "url": "https://github.com/juice-shop/juice-shop/issues/2174" + } + ], + "scores": [ + { + "cvss_v3": { + "attackComplexity": "LOW", + "attackVector": "NETWORK", + "availabilityImpact": "NONE", + "baseScore": 9.1, + "baseSeverity": "CRITICAL", + "confidentialityImpact": "HIGH", + "environmentalScore": 9.1, + "environmentalSeverity": "CRITICAL", + "integrityImpact": "HIGH", + "privilegesRequired": "NONE", + "scope": "UNCHANGED", + "temporalScore": 9.1, + "temporalSeverity": "CRITICAL", + "userInteraction": "NONE", + "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", + "version": "3.1" + }, + "products": [ + "juice-shop/juice-shop" + ] + } + ], + "title": "Intentional Vulnerabilities" + } + ] +} diff --git a/.well-known/csaf/2024/juice-shop-sa-disclaimer.json.asc b/.well-known/csaf/2024/juice-shop-sa-disclaimer.json.asc index d4e410aa..5af8f0a8 100644 --- a/.well-known/csaf/2024/juice-shop-sa-disclaimer.json.asc +++ b/.well-known/csaf/2024/juice-shop-sa-disclaimer.json.asc @@ -1,7 +1,7 @@ ------BEGIN PGP SIGNATURE----- - -iHUEABYKAB0WIQQjcrKxKup64wAbs/vQj7FuICnYcAUCZid2pgAKCRDQj7FuICnY -cHgLAP0X9oSVm//b3ARXO1QfG/NCk0QKh8bHarNMWYnuWkQaMgD/Y1RQ+v+4Nn4M -7iY/HLFd2wOIcT8+FC/Ov/xXBtmbjwk= -=+ZJb ------END PGP SIGNATURE----- +-----BEGIN PGP SIGNATURE----- + +iHUEABYKAB0WIQQjcrKxKup64wAbs/vQj7FuICnYcAUCZid2pgAKCRDQj7FuICnY +cHgLAP0X9oSVm//b3ARXO1QfG/NCk0QKh8bHarNMWYnuWkQaMgD/Y1RQ+v+4Nn4M +7iY/HLFd2wOIcT8+FC/Ov/xXBtmbjwk= +=+ZJb +-----END PGP SIGNATURE----- diff --git a/.well-known/csaf/2024/juice-shop-sa-disclaimer.json.sha512 b/.well-known/csaf/2024/juice-shop-sa-disclaimer.json.sha512 index 0b921a9b..1432b1b8 100644 --- a/.well-known/csaf/2024/juice-shop-sa-disclaimer.json.sha512 +++ b/.well-known/csaf/2024/juice-shop-sa-disclaimer.json.sha512 @@ -1 +1 @@ -afb6f3699f5c32b5255691df64274e2cb24b893a9499853a4896308f72948b1dfebb00f9bca3a5907db580d5e70ec54af7224c4e07050a6c7987c4540d73d1ad juice-shop-sa-disclaimer.json +afb6f3699f5c32b5255691df64274e2cb24b893a9499853a4896308f72948b1dfebb00f9bca3a5907db580d5e70ec54af7224c4e07050a6c7987c4540d73d1ad juice-shop-sa-disclaimer.json diff --git a/.well-known/csaf/changes.csv b/.well-known/csaf/changes.csv index 570df733..83ac871f 100644 --- a/.well-known/csaf/changes.csv +++ b/.well-known/csaf/changes.csv @@ -1,3 +1,3 @@ -2017/juice-shop-sa-20200513-express-jwt.json,2024-03-03T11:00:00.000Z -2021/juice-shop-sa-20211014-proto.json,2024-03-25T19:36:00.000Z -2024/juice-shop-sa-general.json,2024-03-03T11:00:00.000Z +2017/juice-shop-sa-20200513-express-jwt.json,2024-03-03T11:00:00.000Z +2021/juice-shop-sa-20211014-proto.json,2024-03-25T19:36:00.000Z +2024/juice-shop-sa-general.json,2024-03-03T11:00:00.000Z diff --git a/.well-known/csaf/index.txt b/.well-known/csaf/index.txt index 2b77b3e3..7d3a3e79 100644 --- a/.well-known/csaf/index.txt +++ b/.well-known/csaf/index.txt @@ -1,3 +1,3 @@ -2017/juice-shop-sa-20200513-express-jwt.json -2021/juice-shop-sa-20211014-proto.json -2024/juice-shop-sa-general.json +2017/juice-shop-sa-20200513-express-jwt.json +2021/juice-shop-sa-20211014-proto.json +2024/juice-shop-sa-general.json diff --git a/.well-known/csaf/provider-metadata.json b/.well-known/csaf/provider-metadata.json index a44501be..6dca1069 100644 --- a/.well-known/csaf/provider-metadata.json +++ b/.well-known/csaf/provider-metadata.json @@ -1,33 +1,33 @@ -{ - "canonical_url": "http://localhost:3000/.well-known/csaf/provider-metadata.json", - "distributions": [ - { - "directory_url": "http://localhost:3000/.well-known/csaf/" - } - ], - "last_updated": "2024-03-05T20:20:56.169Z", - "list_on_CSAF_aggregators": false, - "metadata_version": "2.0", - "mirror_on_CSAF_aggregators": false, - "public_openpgp_keys": [ - { - "fingerprint": "19c01cb7157e4645e9e2c863062a85a8cbfbdcda", - "url": "https://keybase.io/bkimminich/pgp_keys.asc?fingerprint=19c01cb7157e4645e9e2c863062a85a8cbfbdcda" - }, - { - "fingerprint": "2372B2B12AEA7AE3001BB3FBD08FB16E2029D870", - "url": "https://keybase.io/wurstbrot/pgp_keys.asc" - }, - { - "fingerprint": "91b7a09d34db0a5e662ea7546f4a7656807d4ff9", - "url": "https://github.com/J12934.gpg" - } - ], - "publisher": { - "category": "vendor", - "name": "OWASP Juice Shop", - "namespace": "/juice-shop/juice-shop", - "contact_details": "timo.pagel@owasp.org" - }, - "role": "csaf_trusted_provider" -} +{ + "canonical_url": "http://localhost:3000/.well-known/csaf/provider-metadata.json", + "distributions": [ + { + "directory_url": "http://localhost:3000/.well-known/csaf/" + } + ], + "last_updated": "2024-03-05T20:20:56.169Z", + "list_on_CSAF_aggregators": false, + "metadata_version": "2.0", + "mirror_on_CSAF_aggregators": false, + "public_openpgp_keys": [ + { + "fingerprint": "19c01cb7157e4645e9e2c863062a85a8cbfbdcda", + "url": "https://keybase.io/bkimminich/pgp_keys.asc?fingerprint=19c01cb7157e4645e9e2c863062a85a8cbfbdcda" + }, + { + "fingerprint": "2372B2B12AEA7AE3001BB3FBD08FB16E2029D870", + "url": "https://keybase.io/wurstbrot/pgp_keys.asc" + }, + { + "fingerprint": "91b7a09d34db0a5e662ea7546f4a7656807d4ff9", + "url": "https://github.com/J12934.gpg" + } + ], + "publisher": { + "category": "vendor", + "name": "OWASP Juice Shop", + "namespace": "/juice-shop/juice-shop", + "contact_details": "timo.pagel@owasp.org" + }, + "role": "csaf_trusted_provider" +} diff --git a/.well-known/security.txt b/.well-known/security.txt index cd0fe065..5f15087c 100644 --- a/.well-known/security.txt +++ b/.well-known/security.txt @@ -1 +1 @@ -this is a placeholder and the security.txt will be delivered via a route +this is a placeholder and the security.txt will be delivered via a route diff --git a/.zap/rules.tsv b/.zap/rules.tsv index 007cfe35..cd1d953f 100644 --- a/.zap/rules.tsv +++ b/.zap/rules.tsv @@ -1,19 +1,19 @@ -10109 IGNORE (Modern Web Application) -10035 IGNORE (Strict-Transport-Security Header Not Set) -10098 IGNORE (Cross-Domain Misconfiguration) -10017 IGNORE (Cross-Domain JavaScript Source File Inclusion) -10096 IGNORE (Timestamp Disclosure - Unix) -10015 IGNORE (Incomplete or No Cache-control and Pragma HTTP Header Set) -10038 IGNORE (Content Security Policy (CSP) Header Not Set) -10099 IGNORE (Source Code Disclosure - Java) -10027 IGNORE (Information Disclosure - Suspicious Comments) -10094 IGNORE (Base64 Disclosure) -10063 IGNORE (Feature Policy Header Not Set) -10049 IGNORE (Storable but Non-Cacheable Content) -10049 IGNORE (Non-Storable Content) -10110 IGNORE (Dangerous JS Functions) -90004 IGNORE (Insufficient Site Isolation Against Spectre Vulnerability) -90005 IGNORE (Sec-Fetch-Dest Header is Missing) -90005 IGNORE (Sec-Fetch-Mode Header is Missing) -90005 IGNORE (Sec-Fetch-Site Header is Missing) -90005 IGNORE (Sec-Fetch-User Header is Missing) +10109 IGNORE (Modern Web Application) +10035 IGNORE (Strict-Transport-Security Header Not Set) +10098 IGNORE (Cross-Domain Misconfiguration) +10017 IGNORE (Cross-Domain JavaScript Source File Inclusion) +10096 IGNORE (Timestamp Disclosure - Unix) +10015 IGNORE (Incomplete or No Cache-control and Pragma HTTP Header Set) +10038 IGNORE (Content Security Policy (CSP) Header Not Set) +10099 IGNORE (Source Code Disclosure - Java) +10027 IGNORE (Information Disclosure - Suspicious Comments) +10094 IGNORE (Base64 Disclosure) +10063 IGNORE (Feature Policy Header Not Set) +10049 IGNORE (Storable but Non-Cacheable Content) +10049 IGNORE (Non-Storable Content) +10110 IGNORE (Dangerous JS Functions) +90004 IGNORE (Insufficient Site Isolation Against Spectre Vulnerability) +90005 IGNORE (Sec-Fetch-Dest Header is Missing) +90005 IGNORE (Sec-Fetch-Mode Header is Missing) +90005 IGNORE (Sec-Fetch-Site Header is Missing) +90005 IGNORE (Sec-Fetch-User Header is Missing) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 1f883035..8f526fa1 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,112 +1,112 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for -everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity -and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, -color, religion, or sexual identity and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our community include: - -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience -* Focusing on what is best not just for us as individuals, but for the overall community - -Examples of unacceptable behavior include: - -* The use of sexualized language or imagery, and sexual attention or advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take -appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, -issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for -moderation decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing -the community in public spaces. Examples of representing our community include using an official e-mail address, posting -via an official social media account, or acting as an appointed representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible -for enforcement at -[bjoern.kimminich@owasp.org](mailto:bjoern.kimminich@owasp.org). All complaints will be reviewed and investigated -promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem -in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the -community. - -**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation -and an explanation of why the behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series of actions. - -**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including -unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding -interactions in community spaces as well as external channels like social media. Violating these terms may lead to a -temporary or permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified -period of time. No public or private interaction with the people involved, including unsolicited interaction with those -enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate -behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within the community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at -[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. - -Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. - -For answers to common questions about this code of conduct, see the FAQ -at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at -[https://www.contributor-covenant.org/translations][translations]. - -[homepage]: https://www.contributor-covenant.org - -[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html - -[Mozilla CoC]: https://github.com/mozilla/diversity - -[FAQ]: https://www.contributor-covenant.org/faq - -[translations]: https://www.contributor-covenant.org/translations - +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for +everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity +and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, +color, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take +appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, +issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for +moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing +the community in public spaces. Examples of representing our community include using an official e-mail address, posting +via an official social media account, or acting as an appointed representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible +for enforcement at +[bjoern.kimminich@owasp.org](mailto:bjoern.kimminich@owasp.org). All complaints will be reviewed and investigated +promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem +in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the +community. + +**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation +and an explanation of why the behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of actions. + +**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including +unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding +interactions in community spaces as well as external channels like social media. Violating these terms may lead to a +temporary or permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified +period of time. No public or private interaction with the people involved, including unsolicited interaction with those +enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate +behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at +[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ +at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org + +[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html + +[Mozilla CoC]: https://github.com/mozilla/diversity + +[FAQ]: https://www.contributor-covenant.org/faq + +[translations]: https://www.contributor-covenant.org/translations + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index db9eca6b..e91bdf0e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,31 +1,31 @@ -# Contributing [![GitHub contributors](https://img.shields.io/github/contributors/juice-shop/juice-shop.svg)](https://github.com/juice-shop/juice-shop/graphs/contributors) [![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/) - -![CI/CD Pipeline](https://github.com/juice-shop/juice-shop/workflows/CI/CD%20Pipeline/badge.svg?branch=develop) -[![Test Coverage](https://api.codeclimate.com/v1/badges/6206c8f3972bcc97a033/test_coverage)](https://codeclimate.com/github/juice-shop/juice-shop/test_coverage) -[![Maintainability](https://api.codeclimate.com/v1/badges/6206c8f3972bcc97a033/maintainability)](https://codeclimate.com/github/juice-shop/juice-shop/maintainability) -[![Cypress tests](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/detailed/3hrkhu/develop&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/3hrkhu/runs) -![Gitlab pipeline status](https://img.shields.io/gitlab/pipeline/bkimminich/juice-shop.svg) -[![Crowdin](https://d322cqt584bo4o.cloudfront.net/owasp-juice-shop/localized.svg)](https://crowdin.com/project/owasp-juice-shop) -![GitHub issues by-label "help wanted"](https://img.shields.io/github/issues/juice-shop/juice-shop/help%20wanted.svg?color=darkslateblue) -![GitHub issues by-label "good first issue"](https://img.shields.io/github/issues/juice-shop/juice-shop/good%20first%20issue.svg?color=darkgreen) - -## Code Contributions - -The minimum requirements for code contributions are: - -1. The code _must_ be compliant with the configured ESLint rules based on the [JS Standard Code Style](http://standardjs.com). -2. All new and changed code _should_ have a corresponding unit and/or integration test. -3. New and changed challenges _must_ have a corresponding e2e test. -4. [Status checks](https://docs.github.com/en/github/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks) _must_ pass for the last commit within your PR. -5. All Git commits within a PR _must_ be [signed off](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt--s) to indicate the contributor's agreement with the [Developer Certificate of Origin](https://developercertificate.org/). - -### Contribution Guidelines - -You can find our detailed contribution guidelines over here: - - - -## I18N Contributions - -Learn all about our crowd-sourced [translation project on Crowdin](https://crowdin.com/project/owasp-juice-shop) -here: +# Contributing [![GitHub contributors](https://img.shields.io/github/contributors/juice-shop/juice-shop.svg)](https://github.com/juice-shop/juice-shop/graphs/contributors) [![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/) + +![CI/CD Pipeline](https://github.com/juice-shop/juice-shop/workflows/CI/CD%20Pipeline/badge.svg?branch=develop) +[![Test Coverage](https://api.codeclimate.com/v1/badges/6206c8f3972bcc97a033/test_coverage)](https://codeclimate.com/github/juice-shop/juice-shop/test_coverage) +[![Maintainability](https://api.codeclimate.com/v1/badges/6206c8f3972bcc97a033/maintainability)](https://codeclimate.com/github/juice-shop/juice-shop/maintainability) +[![Cypress tests](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/detailed/3hrkhu/develop&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/3hrkhu/runs) +![Gitlab pipeline status](https://img.shields.io/gitlab/pipeline/bkimminich/juice-shop.svg) +[![Crowdin](https://d322cqt584bo4o.cloudfront.net/owasp-juice-shop/localized.svg)](https://crowdin.com/project/owasp-juice-shop) +![GitHub issues by-label "help wanted"](https://img.shields.io/github/issues/juice-shop/juice-shop/help%20wanted.svg?color=darkslateblue) +![GitHub issues by-label "good first issue"](https://img.shields.io/github/issues/juice-shop/juice-shop/good%20first%20issue.svg?color=darkgreen) + +## Code Contributions + +The minimum requirements for code contributions are: + +1. The code _must_ be compliant with the configured ESLint rules based on the [JS Standard Code Style](http://standardjs.com). +2. All new and changed code _should_ have a corresponding unit and/or integration test. +3. New and changed challenges _must_ have a corresponding e2e test. +4. [Status checks](https://docs.github.com/en/github/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks) _must_ pass for the last commit within your PR. +5. All Git commits within a PR _must_ be [signed off](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt--s) to indicate the contributor's agreement with the [Developer Certificate of Origin](https://developercertificate.org/). + +### Contribution Guidelines + +You can find our detailed contribution guidelines over here: + + + +## I18N Contributions + +Learn all about our crowd-sourced [translation project on Crowdin](https://crowdin.com/project/owasp-juice-shop) +here: diff --git a/Dockerfile b/Dockerfile index f1d3a8e2..dec58638 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,51 +1,51 @@ -FROM node:20-buster as installer -COPY . /juice-shop -WORKDIR /juice-shop -RUN npm i -g typescript ts-node -RUN npm install --omit=dev --unsafe-perm -RUN npm dedupe --omit=dev -RUN rm -rf frontend/node_modules -RUN rm -rf frontend/.angular -RUN rm -rf frontend/src/assets -RUN mkdir logs -RUN chown -R 65532 logs -RUN chgrp -R 0 ftp/ frontend/dist/ logs/ data/ i18n/ -RUN chmod -R g=u ftp/ frontend/dist/ logs/ data/ i18n/ -RUN rm data/chatbot/botDefaultTrainingData.json || true -RUN rm ftp/legal.md || true -RUN rm i18n/*.json || true - -ARG CYCLONEDX_NPM_VERSION=latest -RUN npm install -g @cyclonedx/cyclonedx-npm@$CYCLONEDX_NPM_VERSION -RUN npm run sbom - -# workaround for libxmljs startup error -FROM node:20-buster as libxmljs-builder -WORKDIR /juice-shop -RUN apt-get update && apt-get install -y build-essential python3 -COPY --from=installer /juice-shop/node_modules ./node_modules -RUN rm -rf node_modules/libxmljs/build && \ - cd node_modules/libxmljs && \ - npm run build - -FROM gcr.io/distroless/nodejs20-debian11 -ARG BUILD_DATE -ARG VCS_REF -LABEL maintainer="Bjoern Kimminich " \ - org.opencontainers.image.title="OWASP Juice Shop" \ - org.opencontainers.image.description="Probably the most modern and sophisticated insecure web application" \ - org.opencontainers.image.authors="Bjoern Kimminich " \ - org.opencontainers.image.vendor="Open Worldwide Application Security Project" \ - org.opencontainers.image.documentation="https://help.owasp-juice.shop" \ - org.opencontainers.image.licenses="MIT" \ - org.opencontainers.image.version="17.1.1" \ - 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 \ - org.opencontainers.image.created=$BUILD_DATE -WORKDIR /juice-shop -COPY --from=installer --chown=65532:0 /juice-shop . -COPY --chown=65532:0 --from=libxmljs-builder /juice-shop/node_modules/libxmljs ./node_modules/libxmljs -USER 65532 -EXPOSE 3000 -CMD ["/juice-shop/build/app.js"] +FROM node:20-buster as installer +COPY . /juice-shop +WORKDIR /juice-shop +RUN npm i -g typescript ts-node +RUN npm install --omit=dev --unsafe-perm +RUN npm dedupe --omit=dev +RUN rm -rf frontend/node_modules +RUN rm -rf frontend/.angular +RUN rm -rf frontend/src/assets +RUN mkdir logs +RUN chown -R 65532 logs +RUN chgrp -R 0 ftp/ frontend/dist/ logs/ data/ i18n/ +RUN chmod -R g=u ftp/ frontend/dist/ logs/ data/ i18n/ +RUN rm data/chatbot/botDefaultTrainingData.json || true +RUN rm ftp/legal.md || true +RUN rm i18n/*.json || true + +ARG CYCLONEDX_NPM_VERSION=latest +RUN npm install -g @cyclonedx/cyclonedx-npm@$CYCLONEDX_NPM_VERSION +RUN npm run sbom + +# workaround for libxmljs startup error +FROM node:20-buster as libxmljs-builder +WORKDIR /juice-shop +RUN apt-get update && apt-get install -y build-essential python3 +COPY --from=installer /juice-shop/node_modules ./node_modules +RUN rm -rf node_modules/libxmljs/build && \ + cd node_modules/libxmljs && \ + npm run build + +FROM gcr.io/distroless/nodejs20-debian11 +ARG BUILD_DATE +ARG VCS_REF +LABEL maintainer="Bjoern Kimminich " \ + org.opencontainers.image.title="OWASP Juice Shop" \ + org.opencontainers.image.description="Probably the most modern and sophisticated insecure web application" \ + org.opencontainers.image.authors="Bjoern Kimminich " \ + org.opencontainers.image.vendor="Open Worldwide Application Security Project" \ + org.opencontainers.image.documentation="https://help.owasp-juice.shop" \ + org.opencontainers.image.licenses="MIT" \ + org.opencontainers.image.version="17.1.1" \ + 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 \ + org.opencontainers.image.created=$BUILD_DATE +WORKDIR /juice-shop +COPY --from=installer --chown=65532:0 /juice-shop . +COPY --chown=65532:0 --from=libxmljs-builder /juice-shop/node_modules/libxmljs ./node_modules/libxmljs +USER 65532 +EXPOSE 3000 +CMD ["/juice-shop/build/app.js"] diff --git a/Gruntfile.js b/Gruntfile.js index e54417fa..47350ab9 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,90 +1,90 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -'use strict' - -module.exports = function (grunt) { - const os = grunt.option('os') || process.env.PCKG_OS_NAME || '' - const platform = grunt.option('platform') || process.env.PCKG_CPU_ARCH || '' - const node = grunt.option('node') || process.env.nodejs_version || process.env.PCKG_NODE_VERSION || '' - - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - - replace_json: { - manifest: { - src: 'package.json', - changes: { - 'engines.node': (node || '<%= pkg.engines.node %>'), - os: (os ? [os] : '<%= pkg.os %>'), - cpu: (platform ? [platform] : '<%= pkg.cpu %>') - } - } - }, - - compress: { - pckg: { - options: { - mode: os === 'linux' ? 'tgz' : 'zip', - archive: 'dist/<%= pkg.name %>-<%= pkg.version %>' + (node ? ('_node' + node) : '') + (os ? ('_' + os) : '') + (platform ? ('_' + platform) : '') + (os === 'linux' ? '.tgz' : '.zip') - }, - files: [ - { - src: [ - '.well-known/**', - 'LICENSE', - '*.md', - 'package.json', - 'ctf.key', - 'swagger.yml', - 'server.ts', - 'config.schema.yml', - 'build/**', - '!build/reports/**', - 'bom.json', - 'bom.xml', - 'config/*.yml', - 'data/*.ts', - 'data/static/**', - 'data/chatbot/.gitkeep', - 'encryptionkeys/**', - 'frontend/dist/frontend/**', - 'frontend/dist/bom/**', - 'frontend/src/**/*.ts', - 'ftp/**', - 'i18n/.gitkeep', - 'lib/**', - 'models/*.ts', - 'node_modules/**', - 'routes/*.ts', - 'uploads/complaints/.gitkeep', - 'views/**' - ], - dest: 'juice-shop_<%= pkg.version %>/' - } - ] - } - } - }) - - grunt.registerTask('checksum', 'Create .md5 checksum files', function () { - const fs = require('fs') - const crypto = require('crypto') - fs.readdirSync('dist/').forEach(file => { - const buffer = fs.readFileSync('dist/' + file) - const md5 = crypto.createHash('md5') - md5.update(buffer) - const md5Hash = md5.digest('hex') - const md5FileName = 'dist/' + file + '.md5' - grunt.file.write(md5FileName, md5Hash) - grunt.log.write(`Checksum ${md5Hash} written to file ${md5FileName}.`).verbose.write('...').ok() - grunt.log.writeln() - }) - }) - - grunt.loadNpmTasks('grunt-replace-json') - grunt.loadNpmTasks('grunt-contrib-compress') - grunt.registerTask('package', ['replace_json:manifest', 'compress:pckg', 'checksum']) -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +'use strict' + +module.exports = function (grunt) { + const os = grunt.option('os') || process.env.PCKG_OS_NAME || '' + const platform = grunt.option('platform') || process.env.PCKG_CPU_ARCH || '' + const node = grunt.option('node') || process.env.nodejs_version || process.env.PCKG_NODE_VERSION || '' + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + + replace_json: { + manifest: { + src: 'package.json', + changes: { + 'engines.node': (node || '<%= pkg.engines.node %>'), + os: (os ? [os] : '<%= pkg.os %>'), + cpu: (platform ? [platform] : '<%= pkg.cpu %>') + } + } + }, + + compress: { + pckg: { + options: { + mode: os === 'linux' ? 'tgz' : 'zip', + archive: 'dist/<%= pkg.name %>-<%= pkg.version %>' + (node ? ('_node' + node) : '') + (os ? ('_' + os) : '') + (platform ? ('_' + platform) : '') + (os === 'linux' ? '.tgz' : '.zip') + }, + files: [ + { + src: [ + '.well-known/**', + 'LICENSE', + '*.md', + 'package.json', + 'ctf.key', + 'swagger.yml', + 'server.ts', + 'config.schema.yml', + 'build/**', + '!build/reports/**', + 'bom.json', + 'bom.xml', + 'config/*.yml', + 'data/*.ts', + 'data/static/**', + 'data/chatbot/.gitkeep', + 'encryptionkeys/**', + 'frontend/dist/frontend/**', + 'frontend/dist/bom/**', + 'frontend/src/**/*.ts', + 'ftp/**', + 'i18n/.gitkeep', + 'lib/**', + 'models/*.ts', + 'node_modules/**', + 'routes/*.ts', + 'uploads/complaints/.gitkeep', + 'views/**' + ], + dest: 'juice-shop_<%= pkg.version %>/' + } + ] + } + } + }) + + grunt.registerTask('checksum', 'Create .md5 checksum files', function () { + const fs = require('fs') + const crypto = require('crypto') + fs.readdirSync('dist/').forEach(file => { + const buffer = fs.readFileSync('dist/' + file) + const md5 = crypto.createHash('md5') + md5.update(buffer) + const md5Hash = md5.digest('hex') + const md5FileName = 'dist/' + file + '.md5' + grunt.file.write(md5FileName, md5Hash) + grunt.log.write(`Checksum ${md5Hash} written to file ${md5FileName}.`).verbose.write('...').ok() + grunt.log.writeln() + }) + }) + + grunt.loadNpmTasks('grunt-replace-json') + grunt.loadNpmTasks('grunt-contrib-compress') + grunt.registerTask('package', ['replace_json:manifest', 'compress:pckg', 'checksum']) +} diff --git a/HALL_OF_FAME.md b/HALL_OF_FAME.md index c90a23d7..5db2bf11 100644 --- a/HALL_OF_FAME.md +++ b/HALL_OF_FAME.md @@ -1,88 +1,88 @@ -# Hall of Fame - -## Core Team - -- [Björn Kimminich](https://github.com/bkimminich) aka `bkimminich` - ([Project Leader](https://www.owasp.org/index.php/Projects/Project_Leader_Responsibilities)) - [![Keybase PGP](https://img.shields.io/keybase/pgp/bkimminich)](https://keybase.io/bkimminich) -- [Jannik Hollenbach](https://github.com/J12934) aka `J12934` -- [Timo Pagel](https://github.com/wurstbrot) aka `wurstbrot` -- [Shubham Palriwala](https://github.com/ShubhamPalriwala) aka `ShubhamPalriwala` - -## GitHub Contributors - -As reported by [`git-stats -a -s '2014'`](https://www.npmjs.com/package/git-stats) analysis of `master` as of Wed, 07 Aug -2024 after deduplication with `.mailmap`. - -![Top git contributors](screenshots/git-stats.png) - -## Translators - -As exported from -[CrowdIn Top Members Report](https://crowdin.com/project/owasp-juice-shop/reports/top-members) -(by # of translated words) for all languages as of Wed, 07 Aug -2024 after [conversion into Markdown](https://thisdavej.com/copy-table-in-excel-and-paste-as-a-markdown-table/). - -| Name | Languages | Translated | -|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------| -| Björn Kimminich (bkimminich) | German; Dutch; German, Switzerland; Chinese Simplified; Romanian; Danish; Spanish; French; Chinese Traditional; Polish; Hebrew; Japanese; Turkish; Portuguese, Brazilian; Russian; Estonian; Portuguese; Arabic; Norwegian; Czech; Italian; Hindi; Swedish; Azerbaijani; Finnish; Indonesian; Chinese Traditional, Hong Kong; Thai; Korean; Burmese; Greek; Bulgarian; Georgian; Klingon; Latvian; Hungarian; Catalan; Lithuanian; Sinhala; Irish; Urdu (Pakistan); Armenian; Ukrainian; Bengali | 46776 | -| tongsonghua (yolylight) | Chinese Simplified | 10517 | -| Derek Chan (ChanDerek) | Chinese Traditional | 5411 | -| REMOVED_USER | Romanian | 5009 | -| Yannick (yannickboy15) | Dutch | 3872 | -| NCAA | Danish | 3855 | -| Enrique Rossel (erossel) | Spanish | 3416 | -| Simon Basset (simbas) | French | 2933 | -| MortenHC | Danish | 2597 | -| janesmae | Estonian | 2594 | -| toshiaizawa | Japanese | 2302 | -| mrtlgz | Turkish | 2274 | -| schattenbaum | German, Switzerland; German | 2181 | -| Jean Novak (jeannovak) | Portuguese, Brazilian | 2151 | -| ShahinF27 (Khan27) | Azerbaijani | 2125 | -| Lang Mediator (lang.mediator) | Russian | 1949 | -| Bogdan Mihai Nicolae (bogminic) | Romanian | 1824 | -| htchen99 | Chinese Traditional | 1664 | -| Timo Meriläinen (owasp.timo) | Finnish | 1470 | -| Herisatry Lubaba (herisatry) | French | 1465 | -| Dana-Maria Munteanu (danamunteanu) | Romanian | 1366 | -| Dmitry (shipko) | Russian | 1243 | -| Petr Gallus (PetrGallus) | Czech | 1222 | -| owangen | Norwegian; Danish; Klingon | 1139 | -| sjroh | Korean | 1063 | - -**Additional translations by:** - -Giovanni (cruzgio), Alexander Nissen (Nissen96), fabrizio1979, OrNol (TRNSRL), Jorge Estigarribia (jorgestiga), Pablo Barrera (pablo.barrera), Coink (CoinkWang), Phakphum Visetnut (phakphum_visetnut), Kamil Vavra (vavkamil), Abdo Farwan (abdofarwan), AviD (avidouglen), Marco Cavenati (Marcondiro), Stella Dineva (stella.dineva), Stavros M. (msstavros), Fredrik Bore (Boren), GiorgiSharia, Songrit Kitisriworapan (songritk), Oussama Bouthouri (Boussama), sergio.kubota, Ender Çulha (ecu), Claudio Snidero (cla7997), Marc Rüttler (MarcRler), Davis Freimanis (davisfreimanis), r0n1am, fieldhill13, thinbashane, Tomas Rosenqvist (Muamaidbengt), stejkenzie, rToxic, adeyosemanputra, Kylian Runembert (FunnHydra), Andrew Pio (siranen), Filipe Azevedo (filipaze98), Henry Hu (ninedter), zvargun, timexlord, Maria Tiurina (tiurina.maria), ztzxt, Bernhard Hirschmann (bhirschmann20), Daniel Paniagua (danielgpm), REMOVED_USER, Xotak (loulou310), asifnm, Estevam Arantes (Es7evam), REMOVED_USER, anderson silva (anderson.silva), FoteiniAthina, orjen, vientspam, Allan Kimmer Jensen (Saturate), Idomin Ninja (Idomin), BostonLow, Abdullah alshowaiey (Abdullah201), にのせき (ninoseki), Egert Aia (aiaegert), Nico Ådahl (nigotiator), Lars Grini (lars.grini), Jan Wolff (jan.wolff.owasp), Emil (EmilMarian), Pär Svedberg (grebdevs), rakzcs, Ido Har-Tuv (IdoHartuv), Karl (spruur), Adriano Pereira Junior (adrianoapj), Albert Camps (campsupc), Zenmaster212, jasinski_tomasz, Daan Sprenkels (dsprenkels), atteism, Aleksandra Niemyska (niemyskaa), Diego Andreé Porras Rivas (andree.rivas), mateomartinez, Rasmus Bidstrup (rasmusbidstrup), Koji O (marlboro20light), Bruno Rodrigues (bmvr), MoriRo13, Riotaro OKADA (riotaro), talisainen, jcmarcflores, Ahmet Duzenci (duzenci), OliverkeHU, GhosteFace, Kitisak Jirawannakool (jkitisak), Bart Decker (Decker), Daniel Christensen (Tejendi), Manu B (Rosina), Mohammad Febri Ramadlan (mohammadfebrir), coavacoffee, bill (Hawxdu), victor goncalves (noxes), Klas Fahlberg (FahlbergKlas), CarlCampbell, Natalia (notNao), Lenka Dubois (lenkadubois), Syahrol, rachidbm, Mattias Persson (mattiasbpersson), André Santos Duarte Fonseca (Andre_Duarte), sp8c3, cello-anders, Oussama Bouthouri (oussama.bouthouri), HelaBasa Group (HelaBasa), bmoritz, GK (lollipas), landinl, mrudul, Tetsutaro UEHARA (tetsutalow), Héctor Lecuanda (hlecuanda), Michiya Tominaga (nuwaa), Alain Herreman (PapillonPerdu), Anton Krivonosov (anton.krivonosov), Ilkka Savela (ile2021), gray litrot (graylitrot), Martin Hartl (hartlmartin), Mircea Ulmeanu (boltzmann.gt), Bryan Rioux (nayrbrioux), Roy Quiceno (rquiceno), Carlos Allendes (OwaspChile), redr0n19, saetgar, Shivam Soni (i-shivamsoni), ManuelFranz, Fernando (Sh4dow-BR), Anthony3000, Yang Lucas (Lucas.y), REMOVED_USER, hugoalh, nilfigo, Richardson Lima (contatorichardsonlima), soledad aro (cristinagarciaaro), Katharina Wittkowsky (kwittkowsky), Frederik Bøgeskov Johnsen (cpfbj), NaveenKumar (QAInsights), kahfiehudson, Ezequiel Andino (acidobinario), Origami, motofy, dav1ds, Stefan Daugaard Poulsen (cyberzed) - -## Special Thanks - -* Inspired by the "classic" - [BodgeIt Store](https://github.com/psiinon/bodgeit) by - [@psiinon](https://github.com/psiinon) -* Revised OWASP Juice Shop and Juice Shop CTF logo artworks by Emily Gundry (courtesy - of [@SecureState](https://github.com/SecureState)) -* Wallpaper artworks by Mike Branscum (courtesy of - [@daylightstudio](https://github.com/daylightstudio)) -* Official - [OWASP Juice Shop Jingle](https://soundcloud.com/braimee/owasp-juice-shop-jingle) - written and performed by [Brian Johnson](https://github.com/braimee) -* Juicy Chat Bot artworks by Kharisma Mulyana (courtesy of - [Timo Pagel](https://github.com/wurstbrot/)) -* Admin profile picture artworks by Kharisma Mulyana (courtesy of - [Timo Pagel](https://github.com/wurstbrot/)) -* OWASP Juice Shop LEGO™ Tower design & prototyping by [Bram Patelski](https://github.com/brampat/) - -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) -* [Score Board redesign](https://www.figma.com/file/DwC5ErhRz6gb3eTZEYYriS/Juiceshop-Scoreboard?type=design&node-id=0-1&mode=design) by Vibhuti Arora - -## Stargazers (over time) - -[![Stargazers over time](https://starchart.cc/juice-shop/juice-shop.svg)](https://starchart.cc/juice-shop/juice-shop) +# Hall of Fame + +## Core Team + +- [Björn Kimminich](https://github.com/bkimminich) aka `bkimminich` + ([Project Leader](https://www.owasp.org/index.php/Projects/Project_Leader_Responsibilities)) + [![Keybase PGP](https://img.shields.io/keybase/pgp/bkimminich)](https://keybase.io/bkimminich) +- [Jannik Hollenbach](https://github.com/J12934) aka `J12934` +- [Timo Pagel](https://github.com/wurstbrot) aka `wurstbrot` +- [Shubham Palriwala](https://github.com/ShubhamPalriwala) aka `ShubhamPalriwala` + +## GitHub Contributors + +As reported by [`git-stats -a -s '2014'`](https://www.npmjs.com/package/git-stats) analysis of `master` as of Wed, 07 Aug +2024 after deduplication with `.mailmap`. + +![Top git contributors](screenshots/git-stats.png) + +## Translators + +As exported from +[CrowdIn Top Members Report](https://crowdin.com/project/owasp-juice-shop/reports/top-members) +(by # of translated words) for all languages as of Wed, 07 Aug +2024 after [conversion into Markdown](https://thisdavej.com/copy-table-in-excel-and-paste-as-a-markdown-table/). + +| Name | Languages | Translated | +|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------| +| Björn Kimminich (bkimminich) | German; Dutch; German, Switzerland; Chinese Simplified; Romanian; Danish; Spanish; French; Chinese Traditional; Polish; Hebrew; Japanese; Turkish; Portuguese, Brazilian; Russian; Estonian; Portuguese; Arabic; Norwegian; Czech; Italian; Hindi; Swedish; Azerbaijani; Finnish; Indonesian; Chinese Traditional, Hong Kong; Thai; Korean; Burmese; Greek; Bulgarian; Georgian; Klingon; Latvian; Hungarian; Catalan; Lithuanian; Sinhala; Irish; Urdu (Pakistan); Armenian; Ukrainian; Bengali | 46776 | +| tongsonghua (yolylight) | Chinese Simplified | 10517 | +| Derek Chan (ChanDerek) | Chinese Traditional | 5411 | +| REMOVED_USER | Romanian | 5009 | +| Yannick (yannickboy15) | Dutch | 3872 | +| NCAA | Danish | 3855 | +| Enrique Rossel (erossel) | Spanish | 3416 | +| Simon Basset (simbas) | French | 2933 | +| MortenHC | Danish | 2597 | +| janesmae | Estonian | 2594 | +| toshiaizawa | Japanese | 2302 | +| mrtlgz | Turkish | 2274 | +| schattenbaum | German, Switzerland; German | 2181 | +| Jean Novak (jeannovak) | Portuguese, Brazilian | 2151 | +| ShahinF27 (Khan27) | Azerbaijani | 2125 | +| Lang Mediator (lang.mediator) | Russian | 1949 | +| Bogdan Mihai Nicolae (bogminic) | Romanian | 1824 | +| htchen99 | Chinese Traditional | 1664 | +| Timo Meriläinen (owasp.timo) | Finnish | 1470 | +| Herisatry Lubaba (herisatry) | French | 1465 | +| Dana-Maria Munteanu (danamunteanu) | Romanian | 1366 | +| Dmitry (shipko) | Russian | 1243 | +| Petr Gallus (PetrGallus) | Czech | 1222 | +| owangen | Norwegian; Danish; Klingon | 1139 | +| sjroh | Korean | 1063 | + +**Additional translations by:** + +Giovanni (cruzgio), Alexander Nissen (Nissen96), fabrizio1979, OrNol (TRNSRL), Jorge Estigarribia (jorgestiga), Pablo Barrera (pablo.barrera), Coink (CoinkWang), Phakphum Visetnut (phakphum_visetnut), Kamil Vavra (vavkamil), Abdo Farwan (abdofarwan), AviD (avidouglen), Marco Cavenati (Marcondiro), Stella Dineva (stella.dineva), Stavros M. (msstavros), Fredrik Bore (Boren), GiorgiSharia, Songrit Kitisriworapan (songritk), Oussama Bouthouri (Boussama), sergio.kubota, Ender Çulha (ecu), Claudio Snidero (cla7997), Marc Rüttler (MarcRler), Davis Freimanis (davisfreimanis), r0n1am, fieldhill13, thinbashane, Tomas Rosenqvist (Muamaidbengt), stejkenzie, rToxic, adeyosemanputra, Kylian Runembert (FunnHydra), Andrew Pio (siranen), Filipe Azevedo (filipaze98), Henry Hu (ninedter), zvargun, timexlord, Maria Tiurina (tiurina.maria), ztzxt, Bernhard Hirschmann (bhirschmann20), Daniel Paniagua (danielgpm), REMOVED_USER, Xotak (loulou310), asifnm, Estevam Arantes (Es7evam), REMOVED_USER, anderson silva (anderson.silva), FoteiniAthina, orjen, vientspam, Allan Kimmer Jensen (Saturate), Idomin Ninja (Idomin), BostonLow, Abdullah alshowaiey (Abdullah201), にのせき (ninoseki), Egert Aia (aiaegert), Nico Ådahl (nigotiator), Lars Grini (lars.grini), Jan Wolff (jan.wolff.owasp), Emil (EmilMarian), Pär Svedberg (grebdevs), rakzcs, Ido Har-Tuv (IdoHartuv), Karl (spruur), Adriano Pereira Junior (adrianoapj), Albert Camps (campsupc), Zenmaster212, jasinski_tomasz, Daan Sprenkels (dsprenkels), atteism, Aleksandra Niemyska (niemyskaa), Diego Andreé Porras Rivas (andree.rivas), mateomartinez, Rasmus Bidstrup (rasmusbidstrup), Koji O (marlboro20light), Bruno Rodrigues (bmvr), MoriRo13, Riotaro OKADA (riotaro), talisainen, jcmarcflores, Ahmet Duzenci (duzenci), OliverkeHU, GhosteFace, Kitisak Jirawannakool (jkitisak), Bart Decker (Decker), Daniel Christensen (Tejendi), Manu B (Rosina), Mohammad Febri Ramadlan (mohammadfebrir), coavacoffee, bill (Hawxdu), victor goncalves (noxes), Klas Fahlberg (FahlbergKlas), CarlCampbell, Natalia (notNao), Lenka Dubois (lenkadubois), Syahrol, rachidbm, Mattias Persson (mattiasbpersson), André Santos Duarte Fonseca (Andre_Duarte), sp8c3, cello-anders, Oussama Bouthouri (oussama.bouthouri), HelaBasa Group (HelaBasa), bmoritz, GK (lollipas), landinl, mrudul, Tetsutaro UEHARA (tetsutalow), Héctor Lecuanda (hlecuanda), Michiya Tominaga (nuwaa), Alain Herreman (PapillonPerdu), Anton Krivonosov (anton.krivonosov), Ilkka Savela (ile2021), gray litrot (graylitrot), Martin Hartl (hartlmartin), Mircea Ulmeanu (boltzmann.gt), Bryan Rioux (nayrbrioux), Roy Quiceno (rquiceno), Carlos Allendes (OwaspChile), redr0n19, saetgar, Shivam Soni (i-shivamsoni), ManuelFranz, Fernando (Sh4dow-BR), Anthony3000, Yang Lucas (Lucas.y), REMOVED_USER, hugoalh, nilfigo, Richardson Lima (contatorichardsonlima), soledad aro (cristinagarciaaro), Katharina Wittkowsky (kwittkowsky), Frederik Bøgeskov Johnsen (cpfbj), NaveenKumar (QAInsights), kahfiehudson, Ezequiel Andino (acidobinario), Origami, motofy, dav1ds, Stefan Daugaard Poulsen (cyberzed) + +## Special Thanks + +* Inspired by the "classic" + [BodgeIt Store](https://github.com/psiinon/bodgeit) by + [@psiinon](https://github.com/psiinon) +* Revised OWASP Juice Shop and Juice Shop CTF logo artworks by Emily Gundry (courtesy + of [@SecureState](https://github.com/SecureState)) +* Wallpaper artworks by Mike Branscum (courtesy of + [@daylightstudio](https://github.com/daylightstudio)) +* Official + [OWASP Juice Shop Jingle](https://soundcloud.com/braimee/owasp-juice-shop-jingle) + written and performed by [Brian Johnson](https://github.com/braimee) +* Juicy Chat Bot artworks by Kharisma Mulyana (courtesy of + [Timo Pagel](https://github.com/wurstbrot/)) +* Admin profile picture artworks by Kharisma Mulyana (courtesy of + [Timo Pagel](https://github.com/wurstbrot/)) +* OWASP Juice Shop LEGO™ Tower design & prototyping by [Bram Patelski](https://github.com/brampat/) + +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) +* [Score Board redesign](https://www.figma.com/file/DwC5ErhRz6gb3eTZEYYriS/Juiceshop-Scoreboard?type=design&node-id=0-1&mode=design) by Vibhuti Arora + +## Stargazers (over time) + +[![Stargazers over time](https://starchart.cc/juice-shop/juice-shop.svg)](https://starchart.cc/juice-shop/juice-shop) diff --git a/LICENSE b/LICENSE index c804828c..093d2042 100644 --- a/LICENSE +++ b/LICENSE @@ -1,22 +1,22 @@ -Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. +Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 8df5437f..8f67a6f7 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,52 @@ -# ![Juice Shop Logo](https://raw.githubusercontent.com/juice-shop/juice-shop/master/frontend/src/assets/public/images/JuiceShop_Logo_100px.png) OWASP Juice Shop - -[![OWASP Flagship](https://img.shields.io/badge/owasp-flagship%20project-48A646.svg)](https://owasp.org/projects/#sec-flagships) -[![GitHub release](https://img.shields.io/github/release/juice-shop/juice-shop.svg)](https://github.com/juice-shop/juice-shop/releases/latest) -[![Twitter Follow](https://img.shields.io/twitter/follow/owasp_juiceshop.svg?style=social&label=Follow)](https://twitter.com/owasp_juiceshop) -[![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/owasp_juiceshop?style=social)](https://reddit.com/r/owasp_juiceshop) - -![CI/CD Pipeline](https://github.com/juice-shop/juice-shop/workflows/CI/CD%20Pipeline/badge.svg?branch=master) -[![Test Coverage](https://api.codeclimate.com/v1/badges/6206c8f3972bcc97a033/test_coverage)](https://codeclimate.com/github/juice-shop/juice-shop/test_coverage) -[![Maintainability](https://api.codeclimate.com/v1/badges/6206c8f3972bcc97a033/maintainability)](https://codeclimate.com/github/juice-shop/juice-shop/maintainability) -[![Code Climate technical debt](https://img.shields.io/codeclimate/tech-debt/juice-shop/juice-shop)](https://codeclimate.com/github/juice-shop/juice-shop/trends/technical_debt) -[![Cypress tests](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/3hrkhu/master&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/3hrkhu/runs) -[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/223/badge)](https://www.bestpractices.dev/projects/223) -![GitHub stars](https://img.shields.io/github/stars/juice-shop/juice-shop.svg?label=GitHub%20%E2%98%85&style=flat) -[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md) - -> [The most trustworthy online shop out there.](https://twitter.com/dschadow/status/706781693504589824) -> ([@dschadow](https://github.com/dschadow)) — -> [The best juice shop on the whole internet!](https://twitter.com/shehackspurple/status/907335357775085568) -> ([@shehackspurple](https://twitter.com/shehackspurple)) — -> [Actually the most bug-free vulnerable application in existence!](https://youtu.be/TXAztSpYpvE?t=26m35s) -> ([@vanderaj](https://twitter.com/vanderaj)) — -> [First you 😂😂then you 😢](https://twitter.com/kramse/status/1073168529405472768) -> ([@kramse](https://twitter.com/kramse)) — -> [But this doesn't have anything to do with juice.](https://twitter.com/coderPatros/status/1199268774626488320) -> ([@coderPatros' wife](https://twitter.com/coderPatros)) - -OWASP Juice Shop is probably the most modern and sophisticated insecure web application! It can be used in security -trainings, awareness demos, CTFs and as a guinea pig for security tools! Juice Shop encompasses vulnerabilities from the -entire -[OWASP Top Ten](https://owasp.org/www-project-top-ten) along with many other security flaws found in real-world -applications! - -![Juice Shop Screenshot Slideshow](screenshots/slideshow.gif) - -For a detailed introduction, full list of features and architecture overview please visit the official project page: - - -## Hackathon -This is a modified verison of Juice Shop for the needs of Software Engineering II Hackathon. - -Please fork this repository and start Hacking!! - -## Licensing (Base Contributors) - -[![license](https://img.shields.io/github/license/bkimminich/juice-shop.svg)](LICENSE) - -This program is free software: you can redistribute it and/or modify it under the terms of the [MIT license](LICENSE). -OWASP Juice Shop and any contributions are Copyright © by Bjoern Kimminich & the OWASP Juice Shop contributors -2014-2024. - -![Juice Shop Logo](https://raw.githubusercontent.com/bkimminich/juice-shop/master/frontend/src/assets/public/images/JuiceShop_Logo_400px.png) +# ![Juice Shop Logo](https://raw.githubusercontent.com/juice-shop/juice-shop/master/frontend/src/assets/public/images/JuiceShop_Logo_100px.png) OWASP Juice Shop + +[![OWASP Flagship](https://img.shields.io/badge/owasp-flagship%20project-48A646.svg)](https://owasp.org/projects/#sec-flagships) +[![GitHub release](https://img.shields.io/github/release/juice-shop/juice-shop.svg)](https://github.com/juice-shop/juice-shop/releases/latest) +[![Twitter Follow](https://img.shields.io/twitter/follow/owasp_juiceshop.svg?style=social&label=Follow)](https://twitter.com/owasp_juiceshop) +[![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/owasp_juiceshop?style=social)](https://reddit.com/r/owasp_juiceshop) + +![CI/CD Pipeline](https://github.com/juice-shop/juice-shop/workflows/CI/CD%20Pipeline/badge.svg?branch=master) +[![Test Coverage](https://api.codeclimate.com/v1/badges/6206c8f3972bcc97a033/test_coverage)](https://codeclimate.com/github/juice-shop/juice-shop/test_coverage) +[![Maintainability](https://api.codeclimate.com/v1/badges/6206c8f3972bcc97a033/maintainability)](https://codeclimate.com/github/juice-shop/juice-shop/maintainability) +[![Code Climate technical debt](https://img.shields.io/codeclimate/tech-debt/juice-shop/juice-shop)](https://codeclimate.com/github/juice-shop/juice-shop/trends/technical_debt) +[![Cypress tests](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/3hrkhu/master&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/3hrkhu/runs) +[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/223/badge)](https://www.bestpractices.dev/projects/223) +![GitHub stars](https://img.shields.io/github/stars/juice-shop/juice-shop.svg?label=GitHub%20%E2%98%85&style=flat) +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md) + +> [The most trustworthy online shop out there.](https://twitter.com/dschadow/status/706781693504589824) +> ([@dschadow](https://github.com/dschadow)) — +> [The best juice shop on the whole internet!](https://twitter.com/shehackspurple/status/907335357775085568) +> ([@shehackspurple](https://twitter.com/shehackspurple)) — +> [Actually the most bug-free vulnerable application in existence!](https://youtu.be/TXAztSpYpvE?t=26m35s) +> ([@vanderaj](https://twitter.com/vanderaj)) — +> [First you 😂😂then you 😢](https://twitter.com/kramse/status/1073168529405472768) +> ([@kramse](https://twitter.com/kramse)) — +> [But this doesn't have anything to do with juice.](https://twitter.com/coderPatros/status/1199268774626488320) +> ([@coderPatros' wife](https://twitter.com/coderPatros)) + +OWASP Juice Shop is probably the most modern and sophisticated insecure web application! It can be used in security +trainings, awareness demos, CTFs and as a guinea pig for security tools! Juice Shop encompasses vulnerabilities from the +entire +[OWASP Top Ten](https://owasp.org/www-project-top-ten) along with many other security flaws found in real-world +applications! + +![Juice Shop Screenshot Slideshow](screenshots/slideshow.gif) + +For a detailed introduction, full list of features and architecture overview please visit the official project page: + + +## Hackathon +This is a modified verison of Juice Shop for the needs of Software Engineering II Hackathon. + +Please fork this repository and start Hacking!! + +## Licensing (Base Contributors) + +[![license](https://img.shields.io/github/license/bkimminich/juice-shop.svg)](LICENSE) + +This program is free software: you can redistribute it and/or modify it under the terms of the [MIT license](LICENSE). +OWASP Juice Shop and any contributions are Copyright © by Bjoern Kimminich & the OWASP Juice Shop contributors +2014-2024. + +![Juice Shop Logo](https://raw.githubusercontent.com/bkimminich/juice-shop/master/frontend/src/assets/public/images/JuiceShop_Logo_400px.png) diff --git a/REFERENCES.md b/REFERENCES.md index e6e561ca..d46f60da 100644 --- a/REFERENCES.md +++ b/REFERENCES.md @@ -1,609 +1,609 @@ -# References [![Mentioned in Awesome AppSec](https://awesome.re/mentioned-badge.svg)](https://github.com/paragonie/awesome-appsec) - -Did you write a blog post, magazine article or do a podcast about or mentioning OWASP Juice Shop? Add it to this file -and open a PR! The same goes for conference or meetup talks, workshops or trainings you did where this project was -mentioned or used! - -> :bulb: indicates resources that contain _hints for solving challenges_ -> of the OWASP Juice Shop. These are supposed to be helpful whenever you -> get stuck. :godmode: indicates resources that _spoiler entire -> challenge solutions_, so you might not want to view them before -> 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) - - [2024](#2024) - - [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) - in November 2017 - ([:camera:](https://twitter.com/owasp_juiceshop/status/930917114948587526)) -* [Heroku Button of the Month](https://hello.heroku.com/webmail/36622/844098776/9fe33b8eda9eb79bca7ee569888b1874) - in March 2019 - ([:camera:](https://twitter.com/owasp_juiceshop/status/1110641064673710080)) - -## Web Links - -### Pod- & Webcasts - -* [ZAP Chat 05 Modern Apps Part 1](https://www.youtube.com/watch?v=Rq_d7OLmMfw) on [ZAP](https://www.youtube.com/@psiinon) with Simon Bennetts -* [OWASP Spotlight - Project 25 - OWASP Juice Shop](https://www.youtube.com/watch?v=--50rE76EeA) by Vandana Verma with - Björn Kimminich -* [Visual application security testing with ZAP and Simon Bennetts #DemoDays](https://youtu.be/4xBJsRNV9ds) by [GitHub](https://www.youtube.com/channel/UC7c3Kb6jYCRj4JOHHZTxKsQ) with Simon Bennetts :mega: -* [Exploiting an SSRF vulnerability](https://www.youtube.com/watch?v=OvwNa5CN5yc) by [PinkDraconian](https://www.youtube.com/channel/UCmXwpkCXmIKjoRLMsq9I3RA) :bulb: -* [OWASP Spotlight - Project 20 - OWASP Security Pin](https://www.youtube.com/watch?v=GnSddCV4UwM) by Vandana Verma with - Timo Pagel :mega: -* [People | Process | Technology Podcast](https://soundcloud.com/owasp-podcast/) - (fka "OWASP 24/7 Podcast"): - * [OWASP Flagship Projects - Episode 02](https://soundcloud.com/owasp-podcast/owasp-flagship-projects-episode-02) - * [Less than 10 Minutes Series: The Juice Shop Project](https://soundcloud.com/owasp-podcast/less-than-10-minutes-series-the-juice-shop-project) -* [Learn Web App Security Penetration Testing with Juice Shop \[Free\]](https://youtu.be/ShUTDUYEMWA) - by - [Gerald Auger - Simply Cyber](https://www.YouTube.com/channel/UCG-48Ki-b6W_siaUkukJOSw) -* [Web security for web developers with Zaproxy by Simon Bennetts](https://youtu.be/54UV2_JwcIY) - with - [Eddie Jaoude](https://www.YouTube.com/channel/UC5mnBodB73bR88fLXHSfzYA) - :mega: -* [ZAP in Ten](https://www.alldaydevops.com/zap-in-ten) with Simon Bennetts - * [ZAP in Ten: ADDO Workshop Section 1 - Introduction](https://play.vidyard.com/BAmiaxyzS3g2BCgX2vbVvV) - :mega: - * [ZAP in Ten: ADDO Workshop Section 3 - Packaged Scans](https://play.vidyard.com/iT5C1onahsh3YhQi5SRnLL) - :mega: - * [ZAP in Ten: ADDO Workshop Section 4 - Intro to Authentication](https://play.vidyard.com/zwWm4qMRc8wD2KAgozvC5t) - :mega: - * [ZAP in Ten: ADDO Workshop Section 6 - Standard Auth with JuiceShop](https://play.vidyard.com/igf3A8UdZ6QAGiFjEpLH86) - * [ZAP in Ten: ADDO Workshop Section 8 - JuiceShop SSO Authentication](https://play.vidyard.com/TMcBcuhyPt57sUqPcJUtpv) -* 15min video tutorial by - [Nick Malcolm](https://www.YouTube.com/channel/UCgU77NClL2pLS92viQro6yA): - [OWASP Juice Shop 101](https://youtu.be/8ZYoe0xu6QY) :godmode: -* [Application Security Podcast](https://securityjourney.com/application-security-podcast): - * [Björn Kimminich -- OWASP Juice Shop](https://www.buzzsprout.com/1730684/14121640-bjorn-kimminich-owasp-juice-shop) ([YouTube](https://youtu.be/ay5A7BcZxIs?si=nzhYfVqG5o7l9bWA)) - * Episode 7.2: - [Jannik Hollenbach — Multijuicer: JuiceShop with a side of Kubernetes](https://podcast.securityjourney.com/jannik-hollenbach-multijuicer-juiceshop-with-a-side-of-kubernetes/) - ([YouTube](https://youtu.be/3M6EMDKIAYs)) - * Episode 5.21: - [Season 5 Finale — A cross section of #AppSec (S05E21)](https://podcast.securityjourney.com/season-5-finale-a-cross-section-of-appsec/) - (contains - [5 minute AppSec: Björn Kimminich — JuiceShop](https://www.securityjourney.com/blog/bjorn-kimminich-juiceship-5-minute-appsec/) - entirely) - * Episode 5.20: - [Ronnie Flathers - Security programs big and small](https://podcast.securityjourney.com/ronnie-flathers-security-programs-big-and-small/) - :mega: - * Episode 5.9: - [The new JuiceShop, GSOC, and Open Security Summit](https://securityjourney.com/blog/bjorn-kimminich-the-new-juiceshop-gsoc-and-open-security-summit/) - * 5 minute AppSec: - [Björn Kimminich — JuiceShop](https://www.securityjourney.com/blog/bjorn-kimminich-juiceship-5-minute-appsec/) - * Episode 4.27: - [Season 4 Finale (S04E27)](https://www.securityjourney.com/blog/season-4-finale-s04e27/) - (snippet from - [4.17](https://securityjourney.com/blog/the-joy-of-the-vulnerable-web-juiceshops04e17/)) - * Episode 4.20: - [Security Culture Hacking: Disrupting the Security Status Quo (S04E20)](https://www.securityjourney.com/blog/security-culture-hacking-disrupting-the-security-status-quo-s04e20/) - :mega: - * Episode 4.17: - [The Joy of the Vulnerable Web: JuiceShop (S04E17)](https://securityjourney.com/blog/the-joy-of-the-vulnerable-web-juiceshops04e17/) -* Webcast recording on [7 Minute Security](https://7ms.us): - [DIY $500 Pentest Lab - Part 1](https://www.YouTube.com/watch?v=7qnaR6ZmJzA) - :mega: -* Recorded live streams from the - [Twitch](https://aka.ms/DevSlopTwitch)/[Mixer](https://aka.ms/DevSlop-Mixer) - [OWASP DevSlop](https://devslop.co/) Show: - * [OWASP DevSlop E12 - Juice Shop with Björn Kimminich](https://www.twitch.tv/videos/337620852) - ([YouTube](https://youtu.be/KEYWRtGNDEc)) :godmode: -* Webcast recording on - [Signal Sciences](https://vimeo.com/signalsciences): - [Secure Development Lessons from Purposely Insecure Applications](https://vimeo.com/241965102/40f6b1778b) -* [7 Minute Security](https://7ms.us) Podcast: - * Episode #403: - [7MOOMAMA - Juice Shop Song + Backdoors and Breaches Jingle](https://7ms.us/7ms-403-7moomama-juice-shop-song-backdoors-and-breaches-jingle/) - * Episode #318: - [Interview with Bjorn Kimminich of OWASP Juice Shop](https://7ms.us/7ms-318-interview-with-bjorn-kimminich-of-owasp-juice-shop/) - * Shout outs in various episodes: - [#347](https://7ms.us/7ms-347-happy-5th-birthday-to-7ms/), - [#342](https://7ms.us/7ms-342-interview-with-matt-mccullough/), - [#310](https://7ms.us/7ms-310/), - [#309](https://7ms.us/7ms-309-password-cracking-in-the-cloud-part-2/), - [#306](https://7ms.us/7ms-306-a-peek-into-the-7ms-mail-bag-part-2/) - and [#282](https://7ms.us/7ms-282-a-peek-into-the-7ms-mail-bag/) - :mega: -* Video tutorial about automating web application security scans with - [OWASP ZAP](https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project) - using Juice Shop as the tested app: - [All you need is Zaproxy - Security Testing for WebApps Made Easy](https://www.YouTube.com/watch?v=AQX84p9NhqY) - * [Example integration as a Docker Compose script](https://github.com/Soluto/webdriverio-zap-proxy) - * [Scan results of the example integration](https://jsfiddle.net/62aedL6n/) - -### Blogs & Articles - -* Blog post on [A Tester's Journey](https://www.lisihocke.com/) by Lisi Hocke: [Open Security Conference 2024 - A Memorable Beginning](https://www.lisihocke.com/2024/10/open-security-conference-2024-a-memorable-beginning.html) -* Blog post on [OWASP.org](https://owasp.org) by Björn Kimminich: [OWASP Juice Shop 2023 achievements and beyond](https://owasp.org/blog/2023/10/10/juice-shop-2023.html) -* Article on [Cobalt.io Developer Best Practices](https://developer.cobalt.io/bestpractices/): [Validate User Input](https://developer.cobalt.io/bestpractices/input-validation/) -* Blog post (:de:) on [Dev-Insider](https://www.dev-insider.de/): [OWASP Juice Shop lädt zum Hacken ein](https://www.dev-insider.de/owasp-juice-shop-laedt-zum-hacken-ein-a-968485/) :godmode: -* Blog post on [OWASP.org](https://owasp.org) by Björn Kimminich: - [OWASP Juice Shop v10.0.0 released](https://owasp.org/2020/03/17/juice-shop-v10.html) -* [20+ Free Resources To Legally Practice Your Ethical Hacking Skills](https://blog.elearnsecurity.com/free-resources-to-legally-practice-ethical-hacking.html?utm_source=twitter&utm_medium=social&utm_campaign=eh_resources_blogpost) - on [eLearnSecurity](https://blog.elearnsecurity.com/) :mega: -* Blog post on - [The Daily Swig - Cybersecurity news and views](https://portswigger.net/daily-swig): - [OWASP security projects showcased at All Day DevOps conference](https://portswigger.net/daily-swig/owasp-security-projects-showcased-at-all-day-devops-conference) -* Blog post on [klarsen.net - A Maker's Blog](https://klarsen.net): - [OWASP Juice Shop SQLi](https://klarsen.net/python/owasp-juice-shop-sqli/) -* White paper by Kelley Bryant: - [OWASP: Application Security's Best Friend](https://drive.google.com/file/d/0ByCGDrCX7bx7dnB0TGJJSnNzRmhtUUE4U1RfR3d0YVl4RHFr/view) -* Article (:es:) on Medium by - [Elzer Pineda](https://medium.com/@elzerjp): - [Null Byte Attack Juice Shop y algo mas!!](https://medium.com/@elzerjp/null-byte-attack-juice-shop-y-algo-mas-2c6d271b2fd5) - :godmode: -* Blog post on [Omer Levi Hevroni's blog](https://www.omerlh.info/): - [Hacking Juice Shop, the DevSecOps Way](https://www.omerlh.info/2018/12/23/hacking-juice-shop-the-devsecops-way/) -* Blog post on [Jannik Hollenbach's blog](https://medium.com/@j12934): - [Testing out ModSecurity CRS with OWASP JuiceShop](https://medium.com/@j12934/testing-out-modsecurity-crs-with-owasp-juiceshop-649830932365) -* OWASP Portland Chapter meeting writeup on the - [Daylight Blog](https://thedaylightstudio.com/blog): - [Vulnerability Hunting Practice Using OWASP Juice Shop](https://thedaylightstudio.com/blog/2018/11/20/vulnerability-hunting-practice-using-owasp-juice-shop) -* Blog post on [Security Boulevard](https://securityboulevard.com): - [From Dev to InfoSec Part 1 – The Journey Begins](https://securityboulevard.com/2018/08/from-dev-to-infosec-part-1-the-journey-begins/) -* Blog post on - [Null Byte :: WonderHowTo](https://null-byte.wonderhowto.com): - [Beginner's Guide to OWASP Juice Shop, Your Practice Hacking Grounds for the 10 Most Common Web App Vulnerabilities](https://null-byte.wonderhowto.com/how-to/beginners-guide-owasp-juice-shop-your-practice-hacking-grounds-for-10-most-common-web-app-vulnerabilities-0185103/) - :godmode: -* Blog posts on - [DevelopSec - Developing Better Security](https://www.developsec.com/): - * [Installing OWASP JuiceShop with Docker](https://www.developsec.com/2018/05/10/installing-owasp-juiceshop-with-docker/) - ([YouTube](https://www.YouTube.com/watch?v=ftS8I7WeKtw)) - * [Installing OWASP JuiceShop with Heroku](https://www.developsec.com/2018/05/15/installing-owasp-juiceshop-with-heroku/) - ([YouTube](https://www.YouTube.com/watch?v=umrLbJkJRN0)) - * [Burp Extension – Juice Shop Routes](https://www.developsec.com/2018/05/18/burp-extension-juice-shop-routes/) - ([YouTube](https://www.YouTube.com/watch?v=o628SfvwHp0)) :godmode: -* Blog posts on - [Jason Haley - Ramblings from an Independent Consultant](http://www.jasonhaley.com/): - * [How to Setup OWASP Juice Shop on Azure (Part 1 of 3)](http://www.jasonhaley.com/post/How-to-Setup-OWASP-Juice-Shop-on-Azure-%28Part-1-of-3%29) - * [Setup OWASP Juice Shop in Web App for Containers (Part 2 of 3)](http://www.jasonhaley.com/post/Setup-OWASP-Juice-Shop-in-Web-App-for-Containers-%28Part-2-of-3%29) - * [Setup OWASP Juice Shop in Azure Container Instances (Part 3 of 3)](http://www.jasonhaley.com/post/Setup-OWASP-Juice-Shop-in-Azure-Container-Instances-%28Part-3-of-3%29) -* Blog post on [Josh Grossman's blog](https://joshcgrossman.com): - [Setting up an OWASP Juice Shop CTF](https://joshcgrossman.com/2018/03/15/setting-up-an-owasp-juice-shop-ctf/) -* Blog post on [Mozilla Hacks](https://hacks.mozilla.org): - [Hands-On Web Security: Capture the Flag with OWASP Juice Shop](https://hacks.mozilla.org/2018/03/hands-on-web-security-capture-the-flag-with-owasp-juice-shop/) -* Blog post (:de:) on [heise Developer](https://www.heise.de/developer): - [Sicherheits-Etikette: Security in der Softwareentwicklung](https://www.heise.de/developer/artikel/Sicherheits-Etikette-Security-in-der-Softwareentwicklung-3986402.html) - :mega: -* Blog Post on - [Stuart Winter-Tear's Blog](https://stuartwintertear.net): - [OWASP Juice Shop Vulnerable Webapp](https://stuartwintertear.net/owasp-juice-shop-vulnerable-webapp) - ([Peerlyst cross-post](https://www.peerlyst.com/posts/owasp-juice-shop-vulnerable-webapp-stuart-winter-tear)) -* Blog posts on [OWASP Summit 2017](https://owaspsummit.org): - * [Juice Shop v4.0.0 Live Release](https://owaspsummit.org/2017/06/15/Juice-Shop-Live-Release-v4.html) - * [Juice Shop's call to pre-summit action](https://owaspsummit.org/2017/05/27/Juice-Shops-call-to-pre-summit-action.html) -* Vulnerable website collection on - [Bonkers About Tech](https://www.bonkersabouttech.com): - [40+ Intentionally Vulnerable Websites To (Legally) Practice Your Hacking Skills](https://www.bonkersabouttech.com/security/40-intentionally-vulnerable-websites-to-practice-your-hacking-skills/392) -* Hacking-session writeup on [Testhexen](http://testhexen.de): - [Learning Application Security – Fun with the Juice Shop](http://testhexen.de/?p=117) -* Guest post (:de:) on - [Informatik Aktuell](http://www.informatik-aktuell.de/): - [Juice Shop - Der kleine Saftladen für Sicherheitstrainings](http://www.informatik-aktuell.de/betrieb/sicherheit/juice-shop-der-kleine-saftladen-fuer-sicherheitstrainings.html) -* Guest post on [The official Sauce Labs Blog](http://sauceio.com/): - [Proving that an application is as broken as intended](http://sauceio.com/index.php/2015/06/guest-post-proving-that-an-application-is-as-broken-as-intended/) -* Teaser post on [Björn Kimminich's Blog](http://kimminich.de): - [Juice Shop](https://kimminich.wordpress.com/2015/06/15/juice-shop) - -## Lectures and Trainings - -* [Introduction to OWASP Top 10 Security Risks](https://www.pluralsight.com/cloud-guru/courses/introduction-to-owasp-top-10-security-risks) course by Chris Jackson :dollar: -* Courses on the [freeCodeCamp.org](https://www.YouTube.com/channel/UC8butISFwT-Wl7EV0hUK0BQ) - YouTube channel - * [Ethical Hacking 101: Web App Penetration Testing - a full course for beginners](https://youtu.be/2_lswM1S264) :godmode: by HackerSploit - * [Web Application Ethical Hacking - Penetration Testing Course for Beginners](https://youtu.be/X4eRbHgRawI) :godmode: by The Cyber Mentor -* [Intro to Semgrep](https://lab.github.com/returntocorp/intro-to-semgrep) - GitHub Learning Lab -* [Real World Web Penetration Testing](https://training.secureideas.com/course/real-world-web-pentesting/start-course/) - course by Jason Gillam :dollar: -* [Brakeing Down Security Web App Sec Training #1](https://drive.google.com/drive/folders/0B-qfQ-gWynwidlJ1YjgxakdPWDA) - by Sunny Wear ([YouTube](https://www.YouTube.com/watch?v=zi3yDovd0RY)) -* [Finding Website Vulnerabilities with Burp](https://www.packtpub.com/mapt/video/networking_and_servers/9781788399678/81304/81308/finding-website-vulnerabilities-with-burp) - chapter :godmode: of the - [Mastering Kali Linux Network Scanning](https://www.packtpub.com/networking-and-servers/mastering-kali-linux-network-scanning-video) - video course by Brian Johnson :dollar: -* [University lecture on "IT Security"](https://github.com/bkimminich/it-security-lecture) - as Open Educational Resources material by Björn Kimminich -* [Descargar aqui el taller OWASP Top 10 Hands On basado en OWASP Top 10 y Juice Shop](https://drive.google.com/drive/folders/0B6zv033D1iK9eTJId2RhZkJFTlk?usp=sharing) - (:es:) by Mateo Martinez, Gerardo Canedo and Maxiimiliano Alonzo, - [OWASP Uruguay Chapter](https://www.owasp.org/index.php/Uruguay) -* [Security in Web Applications](https://drive.google.com/drive/folders/0B2KKdB7MPO7xTEwtWkkwTnl5VFk) - by Timo Pagel, [Fachhochschule Kiel](https://www.fh-kiel.de) -* [Web Application Security Training](https://de.slideshare.net/BjrnKimminich/web-application-security-21684264) - by Björn Kimminich - -## Summits & Open Source Events - -* [Juice Shop Track](https://open-security-summit-2020.heysummit.com/topics/owasp-juiceshop/) - at [Open Security Summit 2020](https://open-security-summit.org/) - * [OWASP Juice Shop Cocktail Party: Ask us anything!](https://open-security-summit-2020.heysummit.com/talks/owasp-juice-shop-cocktail-party-ask-us-anything/) - with Björn Kimminich, Jannik Hollenbach & Timo Pagel 15.06.2020 - ([YouTube](https://youtu.be/h5ApBfFMmao)) - * [OWASP Juice Shop Deep Dive: MultiJuicer](https://open-security-summit-2020.heysummit.com/talks/owasp-juice-shop-deep-dive-multijuicer/) - with Jannik Hollenbach & Robert Seedorf, 15.06.2020 - ([YouTube](https://youtu.be/1YHjkc3Xzd0)) - * [OWASP Juice Shop Deep Dive: Integration](https://open-security-summit-2020.heysummit.com/talks/owasp-juice-shop-deep-dive-integration/) - with Björn Kimminich, 15.06.2020 - ([YouTube](https://youtu.be/9SkUohiKgtU)) - * [OWASP Juice Shop Deep Dive: Theming](https://open-security-summit-2020.heysummit.com/talks/owasp-juice-shop-deep-dive-theming-1/) - with Björn Kimminich, 15.06.2020 - ([YouTube](https://youtu.be/WtY712DdlR8)) - * [OWASP Juice Shop Introduction](https://pre-summit-training-sessions.heysummit.com/talks/owasp-juice-shop-introduction/) - with Björn Kimminich, 11.06.2020 - ([YouTube](https://youtu.be/wCF08BdXdDg)) - * [MultiJuicer Introduction](https://pre-summit-training-sessions.heysummit.com/talks/multijuicer-introduction/) - with Jannik Hollenbach and Robert Seedorf, 02.06.2020 - ([YouTube](https://youtu.be/6NMjZbfnTOU)) - * [OWASP Juice Shop Introduction](https://pre-summit-training-sessions.heysummit.com/talks/owasp-juice-shop/) - with Björn Kimminich, 02.06.2020 - ([YouTube](https://youtu.be/Ry0mXz6ZPXc)) -* [Drinks with Adversaries: Creating Adversary Trading Cards](https://pre-summit-training-sessions.heysummit.com/talks/social-drinks-and-adversaries) - with Mark Miller at - [Open Security Summit 2020](https://open-security-summit.org/), - 01.06.2020 ([YouTube](https://www.YouTube.com/watch?v=3roVZNwptOU)) - :mega: -* Selected Project at - [OWASP Projects Summit - Winter 2020](https://owasp.org/www-staff/projects/202002-Projects-Summit-Q1.html) - with Björn Kimminich, Jannik Hollenbach and Marc Rüttler collaborating on - [prepared working packages](https://github.com/juice-shop/juice-shop/milestone/10) - and - [the `v10.0.0` release](https://owasp.org/2020/03/17/juice-shop-v10.html), 27.-29.02.2020 -* [OWASP Juice Shop track](https://github.com/OpenSecuritySummit/oss2019/tree/master/content/tracks/OWASP-Juice-Shop) - and related working sessions organized by Björn Kimminich, - [Open Security Summit 2019](https://github.com/OpenSecuritySummit/oss2019), 03.-07.06.2019 -* Juice Shop related working sessions organized by Jannik Hollenbach and Timo Pagel in - [OWASP Projects track](https://github.com/OpenSecuritySummit/oss2018/tree/master/content/tracks/OWASP-Projects), - [Open Security Summit 2018](https://github.com/OpenSecuritySummit/oss2018), 04.-08.06.2018 -* [Outcome of the Juice Shop track](https://github.com/OWASP/owasp-summit-2017/blob/master/Outcomes/Juice-Shop/Juce-Shop-Update.md) - and related working sessions organized by Björn Kimminich and Timo Pagel, - [OWASP Summit 2017](https://github.com/OWASP/owasp-summit-2017), 12.-16.06.2017 - -### [Google Summer of Code](http://owasp.org/gsoc) - -* Student projects from - [Google Summer of Code 2023](https://summerofcode.withgoogle.com/archive/2023/projects) - * [Companion Guide Tech Stack](https://summerofcode.withgoogle.com/organizations/owasp-foundation/projects/details/h2der3Mf) - by Parth Nanda (mentored by Jannik Hollenbach, Björn Kimminich and Shubham Palriwala) - * [Hacking the Blockchain: Building Web3 Challenges for OWASP Juice Shop](https://summerofcode.withgoogle.com/organizations/owasp-foundation/projects/details/yabiWLkF) - by Rishabh Keshan (mentored by Shubham Palriwala and Björn Kimminich) -* Student project from - [Google Summer of Code 2022](https://summerofcode.withgoogle.com/archive/2022/projects) - * [Replacement for Protractor end-to-end & Frisby API test suite to Cypress](https://summerofcode.withgoogle.com/organizations/owasp-foundation/projects/details/2J1Xedwf) - by Shubham Palriwala (mentored by Jannik Hollenbach and Björn Kimminich) -* Student project from - [Google Summer of Code 2021](https://summerofcode.withgoogle.com/archive/2021/projects) - * [Extending the features of the vulnerable code snippets](https://summerofcode.withgoogle.com/archive/2021/projects/5180407718346752P) - by Ayas Behera (mentored by Jannik Hollenbach and Björn Kimminich) -* Student project from - [Google Summer of Code 2020](https://summerofcode.withgoogle.com/archive/2020/projects) - * [Juice-Shop ChatBot and general fixes](https://summerofcode.withgoogle.com/archive/2020/projects/5660020047347712/) - by Mohit Sharma (mentored by Jannik Hollenbach, Björn Kimminich and Timo Pagel) -* Student project from - [Google Summer of Code 2019](https://summerofcode.withgoogle.com/archive/2019/projects) - * [OWASP Juice Shop: Feature Pack 2019](https://summerofcode.withgoogle.com/archive/2019/projects/6526397403627520/) - by Arpit Agrawal (mentored by Jannik Hollenbach, Björn Kimminich and Shoeb Patel) -* Student projects from - [Google Summer of Code 2018](https://summerofcode.withgoogle.com/archive/2018/projects) - * [OWASP Juice Shop : Challenge Pack 2018](https://summerofcode.withgoogle.com/archive/2018/projects/6267528737193984) - by Shoeb Patel (mentored by Jannik Hollenbach and Timo Pagel) - * [OWASP Juice Shop : Frontend Technology Update](https://summerofcode.withgoogle.com/archive/2018/projects/6636660909408256) - by Aashish Singh (mentored by Björn Kimminich) - -## Conference and Meetup Appearances - -> Upcoming events are marked with :date:. The availability of link destinations for past events cannot be guaranteed. - -#### 2024 - -* :date: [OWASP Juice Shop: Advanced Demos & For-fun CTF](https://god.owasp.de/2024/program-detail.html?talk=trainingOne) with Björn Kimminich & Jannik Hollenbach, [German OWASP Day 2024](https://god.owasp.de/2024), 12.11.2024 -* :date: [OWASP Juice Shop 10th anniversary: Is it still fresh?](https://god.owasp.de/2024/program-detail.html?talk=talkOne) by Björn Kimminich, [German OWASP Day 2024](https://god.owasp.de/2024), 13.11.2024 -* [OWASP Juice Shop 10th anniversary: Is it still fresh?](https://opensecurityconference.org/conference/keynotes) keynote by Björn Kimminich, [Open Security Conference](https://opensecurityconference.org/), 04.10.2024 -* [DSOMM & Juice Shop User Day](https://owasp2024globalappsecsanfra.sched.com/event/1gk01/juice-shop-dsomm-user-day-2024) before [OWASP 2024 Global AppSec San Francisco](https://sf.globalappsec.org/) with Timo Pagel, Jannik Hollenbach & Björn Kimminich, 25.09.2024 -* [OWASP Juice Shop](https://owasp2024globalappsecsanfra.sched.com/event/1ivEu/owasp-juiceshop) talk in Project Track of [OWASP 2024 Global AppSec San Francisco](https://sf.globalappsec.org/) by Björn Kimminich, 27.09.2024 -* [Brick your Juice Shop in 319 easy steps](https://www.meetup.com/owasp-hamburg-stammtisch/events/302138351/) - by Jannik Hollenbach & Björn Kimminich, [69. OWASP Stammtisch Hamburg](https://owasp.org/www-chapter-germany/stammtische/hamburg/), 23.07.2024 -* [OWASP Juice Shop - An Open Source Software and security Fairytale](https://ndc-security.com/agenda/owasp-juice-shop-an-open-source-software-and-security-fairytale-09mg/09ko186cud8) by Björn Kimminich, [NDC Security 2024](https://ndc-security.com/), 11.01.2024 - -#### 2023 - -* [Juice Shop Training: Train the Trainer Edition](http://www.owaspbenelux.eu/program/training#Bj%C3%B6rn-Kimminich) with Björn Kimminich, [OWASP BeNeLux Days 2023](http://www.owaspbenelux.eu/). 24.11.2023 -* [OWASP Juice Shop - An Open Source Software (and security) Fairytale](http://www.owaspbenelux.eu/program/talks#Bj%C3%B6rn-Kimminich) by Björn Kimminich, [OWASP BeNeLux Days 2023](http://www.owaspbenelux.eu/). 23.11.2023 [YouTube](https://youtu.be/54caQ4g72oI) -* [How Vulnerable is Juice Shop? A Secure Code Review of Insecure Code](https://www.nationalcybersummit.com/Program/2023-Agenda) by Joshua Beck, [National Cyber Summit 2023](https://www.nationalcybersummit.com/Home). 20.09.2023 -* [Track keynote: OWASP Juice Shop](https://sikkerhetsfestivalen.no/program-2023) by Björn Kimminich, [Sikkerhetsfestivalen 2023](https://sikkerhetsfestivalen.no/). 29.08.2023 -* [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 [YouTube](https://youtu.be/87DuRYwXtxk) -* [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 [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 - -* [OWASP Juice Shop Project](https://whova.com/web/GKSmlhCK%2FWzBY2c8qqJ%2Bp7kNcnjsUQAQJ%2ByBsjLrbOo%3D/Speakers/) by Björn Kimminich, [OWASP Global AppSec EU](https://whova.com/web/GKSmlhCK%2FWzBY2c8qqJ%2Bp7kNcnjsUQAQJ%2ByBsjLrbOo%3D/), 10.06.2022 ([YouTube](https://www.youtube.com/watch?v=n9DK87g_AIo)) -* [Juice Shop 13: Now with Coding Challenges!](https://www.meetup.com/de-DE/OWASP-Hamburg-Stammtisch/events/282692845/) - by Björn Kimminich, [58. OWASP Stammtisch Hamburg](https://owasp.org/www-chapter-germany/stammtische/hamburg/), 13.01.2022 - -#### 2021 - -* [OWASP Juice Shop Flagship Project](https://owasp20thanniversaryevent20.sched.com/event/m1uL/owasp-juice-shop-flagship-project) - by Björn Kimminich, [OWASP 20th Anniversary Event](https://20thanniversary.owasp.org/), 24.09.2021 ([YouTube](https://youtu.be/rn-6NADRRmI) :godmode:) -* [SDLC con OWASP y laboratorio con OWASP Juice Shop](https://www.meetup.com/de-DE/OWASP-Uruguay-Chapter/events/279827017/) - (:uruguay:) with Martín Marsicano and Pablo Alzuri, - [OWASP Uruguay Chapter](https://owasp.org/www-chapter-uruguay/), - 19.08.2021 [YouTube](https://youtu.be/OAE1EnBNMlc?t=2722) :godmode: -* [Talking Juice Shop and Maintaining a Flagship OWASP Project with Björn Kimminich](https://www.meetup.com/OWASP-Northern-Virginia-Chapter/events/278751084/) - , - [OWASP Northern Virginia Chapter](https://owasp.org/www-chapter-northern-virginia/), - 07.07.2021 ([YouTube](https://youtu.be/uejiQ9VvFu4)) -* [OWASP Aarhus Chapter Worskhop and CTF](https://www.meetup.com/de-DE/OWASP-Aarhus-Chapter/events/277659233/) - with Björn Kimminich, - [OWASP Aarhus Chapter](https://owasp.org/www-chapter-aarhus/), 06.05.2021 -* [Modern Web Application Hacking for Beginners](https://github.com/bkimminich/it-security-lecture/tree/workshop), - virtual 4h diversity training by Björn Kimminich, - [OWASP Training Events 2021 - 2020 SOS Re-run](https://github.com/OWASP/www-event-2021-training), 26.01.2021 - -#### 2020 - -* [FPs are Cheap. Show me the CVEs!](https://www.blackhat.com/eu-20/briefings/schedule/index.html#fps-are-cheap-show-me-the-cves-21345) - by Bas van Schaik & Kevin Backhouse, - [Black Hat Europe 2020](https://www.blackhat.com/eu-20/), 09.12.2020 -* [Juice Shop 12: Novelties by the litre (Online)](https://www.meetup.com/de-DE/OWASP-Hamburg-Stammtisch/events/272842835/) - by Björn Kimminich, - [48. OWASP Stammtisch Hamburg](https://owasp.org/www-chapter-germany/stammtische/hamburg/), - 24.11.2020 ([YouTube](https://youtu.be/AUhDItHHLiY)) -* [Modern Web Application Hacking for Beginners](https://github.com/bkimminich/it-security-lecture/tree/workshop), - virtual 4h diversity training by Björn Kimminich, - [AppSec Days - Summer of Security 2020](https://github.com/OWASP/www-event-2020-08-virtual), 25.08.2020 -* [OWASP Projects Panel](https://www.meetup.com/de-DE/womeninappsec/events/271754765/) - hosted by [OWASP WIA](https://www.meetup.com/womeninappsec/) moderated by Zoe Braiterman with panelists Bjoern - Kimminich, Glenn & Riccardo ten Cate and Spyros Gasteratos, 25.07.2020 - ([YouTube](https://youtu.be/d96-HCrSh2M)) -* [OWASP ZAP Intro (Online)](https://www.meetup.com/de-DE/OWASP-Hamburg-Stammtisch/events/270078609/) - by Simon Bennetts, - [48. OWASP Stammtisch Hamburg](https://owasp.org/www-chapter-germany/stammtische/hamburg/), - 23.04.2020 ([YouTube](https://youtu.be/SD28HdVI-Wk)) :mega: -* [ZAP in Ten, Extended Edition: Automation Deepdive](https://www.alldaydevops.com/addo-speakers/simom-bennetts) - by Simon Bennetts, - [All Day DevOps Spring Break Edition](https://www.alldaydevops.com/), 17.04.2020 :bulb: - -#### 2019 - -* [Juice Shop 9: Would you like a free refill?](https://god.owasp.de/archive/2019/) - by Björn Kimminich, - [German OWASP Day 2019](https://god.owasp.de/archive/2019/), - 10.12.2019 ([YouTube](https://www.YouTube.com/watch?v=L7h5uE7WDfg) - :bulb:) -* [S' OWASP Saft-Lädeli / The OWASP Juice Shop](https://www.meetup.com/de-DE/OWASPSwitzerland/events/264422942/) - by Björn Kimminich, - [OWASP Switzerland Chapter Meeting](https://www.meetup.com/de-DE/OWASPSwitzerland/), 18.11.2019 -* [OWASP Juice Shop: The ultimate All Vuln WebApp](https://www.alldaydevops.com/addo-speakers/bj%C3%B6rn-kimminich) - by Björn Kimminich, [All Day DevOps](https://www.alldaydevops.com/), 06.11.2019 - ([YouTube](https://www.YouTube.com/watch?v=-JuPprlGb48&t=13939s) - :bulb:) -* [Juice Shop](https://globalappsecamsterdam2019.sched.com/event/U84e/juice-shop) - by Björn Kimminich, Project Showcase track of the - [Global AppSec Amsterdam 2019](https://ams.globalappsec.org/), 26.09.2019 ([YouTube](https://youtu.be/XXkMY_VyJ-Y) : - bulb:) -* [Elbsides vs. Juice Shop](https://2019.elbsides.de/programme.html#elbsides-vs-juice-shop) - workshop with Björn Kimminich, - [Elbsides 2019](https://2019.elbsides.de), 16.09.2019 -* [Introduction to OWASP Juice Shop](https://bsidesmcr2019.sched.com/event/Sw0q/introduction-to-owasp-juice-shop) - by Tim Corless-Carter, - [BSidesMCR 2019](https://www.bsidesmcr.org.uk/), 29.08.2019 - ([YouTube](https://youtu.be/hlgp7oeVpac) :godmode:) -* [JavaScript-Security: "Pwn" den Juice Shop](https://enterjs.de/2019/single034c.html?id=7685&javascript-security%3A-%22pwn%22-den-juice-shop) - workshop with Timo Pagel & Björn Kimminich, - [enterJS 2019](https://www.enterjs.de/2019/), 25.06.2019 -* [Web Application Hacking with Burp Suite and OWASP ZAP](https://globalappsectelaviv2019.sched.com/event/MLSU/web-application-hacking-with-burp-suite-and-owasp-zap) - training with Vandana Verma, - [Global Appsec Tel Aviv 2019](https://globalappsectelaviv2019.sched.com), 28.05.2019 -* [A good first impression can work wonders: creating AppSec training that developers <3](https://locomocosec2019.sched.com/event/MGNM/a-good-first-impression-can-work-wonders-creating-appsec-training-that-developers-v) - by Leif Dreizler, - [LocoMocoSec 2019](https://locomocosec2019.sched.com/), 18.04.2019 -* [Pixels vs. Juice Shop](https://github.com/PixelsCamp/talks/blob/master/2019/pixels-vs-juice-shop_bjoern-kimminich.md) - workshop with Björn Kimminich, - [Pixels Camp v3.0](https://pixels.camp), 21.03.2019 -* [OWASP Juice Shop - First you :-D :-D then you :,-(](https://github.com/PixelsCamp/talks/blob/master/2019/owasp-juice-shop_bjoern-kimminich.md) - by Björn Kimminich, [Pixels Camp v3.0](https://pixels.camp), 21.03.2019 ([YouTube](https://youtu.be/v9qrAK_iBa0) : - bulb:) -* [News from the fruit press: Juice Shop 8](https://www.meetup.com/de-DE/OWASP-Hamburg-Stammtisch/events/258185324/) - by Björn Kimminich, - [39. OWASP Stammtisch Hamburg](https://www.meetup.com/de-DE/OWASP-Hamburg-Stammtisch), 27.02.2019 -* [Back to Basics: Hacking OWASP JuiceShop](https://www.owasp.org/index.php/Knoxville#Past_Meetings) - by Jeremy Kelso, - [OWASP Knoxville Chapter Meeting](https://www.owasp.org/index.php/Knoxville), 24.01.2019 - -#### 2018 - -* [Secure Your Pipeline](https://www.facebook.com/events/441842706348978/) - by Omer Levi Hevroni, Negev Web Developers Meetup, 27.12.2018 - ([Slides](https://www.slideshare.net/SolutoTLV/secure-your-pipeline)) -* [Juice Shop: OWASP's most broken Flagship](https://www.owasp.org/index.php/OWASP_BeNeLux-Days_2018#tab=Conference_Day) - by Björn Kimminich, - [OWASP BeNeLux Days 2018](https://www.owasp.org/index.php/OWASP_BeNeLux-Days_2018), - 30.11.2018 ([YouTube](https://youtu.be/Lu0-kDdtVf4) :bulb:) -* [OWASP Zap](https://www.owasp.org/index.php/OWASP_BeNeLux-Days_2018#tab=Conference_Day) - by David Scrobonia, - [OWASP BeNeLux Days 2018](https://www.owasp.org/index.php/OWASP_BeNeLux-Days_2018), - 30.11.2018 ([YouTube](https://youtu.be/iaZaPuQ6ams)) -* [The traditional/inevitable OWASP Juice Shop update](https://owasp.github.io/german-owasp-day/archive/2018/) - by Björn Kimminich, - [German OWASP Day 2018](https://owasp.github.io/german-owasp-day/archive/2018/), - 20.11.2018 ([YouTube](https://youtu.be/2oNfZo2H4uA)) -* [Workshop: OWASP Juice Shop](https://owasp.github.io/german-owasp-day/archive/2018/) - by Björn Kimminich, - [German OWASP Day 2018](https://owasp.github.io/german-owasp-day/archive/2018/), 19.11.2018 -* [OWASP Portland Chapter Meeting - OWASP Juice Shop!](http://calagator.org/events/1250474481) - facilitated by David Quisenberry, - [OWASP Portland Chapter](https://www.owasp.org/index.php/Portland), 08.11.2018 -* [OWASP Juice Shop - Public Lecture](https://www.facebook.com/events/674384206291349) - by Björn Kimminich, - [TalTech Infotehnoloogia Kolledž](https://www.facebook.com/itcollege.ee), - 24.10.2018 ([YouTube](https://youtu.be/79G46CQ3IMk?t=158) :godmode: - _starting 14:55_) -* [JUGHH: Security Hackathon](https://www.meetup.com/jug-hamburg/events/254885956/) - by [iteratec](https://www.iteratec.de/), - [Java User Group Hamburg](https://www.meetup.com/jug-hamburg), 11.10.2018 -* [Playing with OWASP Juice Shop](https://mozilla.or.id/en/space/events/258-playing-with-owasp-juice-shop.html) - by Mohammad Febri R, [Mozilla Indonesia](https://mozilla.or.id/), 05.08.2018 - ([Slides](https://slides.com/mohammadfebri/owasp-juice-shop)) -* [OWASP Juice Shop どうでしょう](https://speakerdeck.com/ninoseki/owasp-juice-shop-doudesiyou) - by Manabu Niseki, - [OWASP Night 2018/7](https://owasp.doorkeeper.jp/events/77466), 30.07.2018 -* [Usable Security Tooling - Creating Accessible Security Testing with ZAP](https://www.meetup.com/de-DE/Bay-Area-OWASP/events/252283865/) - by David Scrobonia, - [OWASP Meetup - SF July 2018](https://www.meetup.com/de-DE/Bay-Area-OWASP/), - 26.07.2018 ([YouTube](https://www.YouTube.com/watch?v=ztfgip-UhWw)) -* [Building an AppSec Program with a Budget of $0: Beyond the OWASP Top 10](https://appseceurope2018a.sched.com/event/EgXt/building-an-appsec-program-with-a-budget-of-0-beyond-the-owasp-top-10) - by Chris Romeo, [OWASP AppSec Europe 2018](https://2018.appsec.eu), - 06.07.2018 ([YouTube](https://www.YouTube.com/watch?v=5RmHQKeXgk4)) - :mega: -* [OWASP Juice Shop: Betreutes Hacken](https://www.meetup.com/de-DE/owasp-karlsruhe/events/251041169/) - with - [OWASP Stammtisch Karlsruhe](https://www.owasp.org/index.php/OWASP_Stammtisch_Karlsruhe), 04.06.2018 -* [Hacking Workshop - Twin Cities vs. OWASP Juice Shop](https://secure360.org/secure360-twin-cities/schedule/?conference=9826&date=20180517) - with Björn Kimminich, - [Secure360 Twin Cities](https://secure360.org/secure360-twin-cities/), 17.05.2018 -* [OWASP Juice Shop - The Ultimate Vulnerable WebApp](https://secure360.org/session/bjorn-kimminich-owasp-juice-shop-the-ultimate-vulnerable-webapp/?conference=9826&date=20180516) - by Björn Kimminich, - [Secure360 Twin Cities](https://secure360.org/secure360-twin-cities/), 16.05.2018 -* [OWASP MSP Chapter May Meeting](https://www.meetup.com/OWASP-MSP-Meetup/events/249940370/) - with Björn Kimminich, - [OWASP MSP Meetup](https://www.meetup.com/OWASP-MSP-Meetup/) St Paul, 14.05.2018 -* [OWASP Juice Shop - The next chapter ...](https://www.meetup.com/CyberHackathon/events/249606655/?eventId=249606655) - with Jaan Janesmae, - [CyberHackathon](https://www.meetup.com/CyberHackathon/) Tallinn, 30.04.2018 -* OWASP Juice Shop Introduction at - [ChaosTreff Tallinn Weekly Meetup](https://www.meetup.com/ChaosTreff-Tallinn/events/249627780/) - with Björn Kimminich, - [ChaosTreff Tallinn](https://www.meetup.com/ChaosTreff-Tallinn/), 26.04.2018 -* [OWASP Juice Shop Intro and Getting Started](https://www.meetup.com/CyberHackathon/events/249359520/?eventId=249359520) - with Jaan Janesmae, - [CyberHackathon](https://www.meetup.com/CyberHackathon/) Tallinn, 09.04.2018 -* [Web Application Security: A Hands-on Testing Challenge](https://dojo.ministryoftesting.com/events/testbash-brighton-2018) - by Dan Billing, - [TestBash Brighton 2018](https://dojo.ministryoftesting.com/events/testbash-brighton-2018), 15.03.2018 -* [OWASP Top 10](https://appseccalifornia2018.sched.com/event/CuRs) by Andrew van der Stock, - [OWASP AppSec California 2018](https://2018.appseccalifornia.org/), - 30.01.2018 ([YouTube](https://www.YouTube.com/watch?v=TXAztSpYpvE) - :godmode: _starting 25:40_) - -#### 2017 - -* [OWASP Juice Shop 5.x and beyond](https://www.owasp.org/index.php/German_OWASP_Day_2017#Programm) - by Björn Kimminich, - [German OWASP Day 2017](https://www.owasp.org/index.php/German_OWASP_Day_2017), 14.11.2017 -* [OWASP Juice Shop Introduction](https://www.owasp.org/index.php/OWASP_Bucharest_AppSec_Conference_2017#tab=Conference_talks) - talk and - [AppSec Bucharest vs. OWASP Juice Shop](https://www.owasp.org/index.php/OWASP_Bucharest_AppSec_Conference_2017#tab=Free_workshops) - hacking workshop by Björn Kimminich, - [OWASP Bucharest AppSec Conference 2017](https://www.owasp.org/index.php/OWASP_Bucharest_AppSec_Conference_2017), - 13.10.2017 -* [2 Hour Hacking: Juice Shop](https://www.meetup.com/de-DE/OWASP-Los-Angeles/events/238321796/) - by Timo Pagel, - [OWASP Los Angeles](https://www.meetup.com/de-DE/OWASP-Los-Angeles/), 10.10.2017 -* [Hacking the OWASP Juice Shop](https://www.owasp.org/index.php/North_Sweden#2017-09-19_-_2017q3:_Hacking_the_OWASP_Juice_Shop) - with Björn Kimminich, - [OWASP North Sweden Chapter](https://www.owasp.org/index.php/North_Sweden), 19.09.2017 -* [OWASP Juice Shop Workshop](https://www.linkedin.com/feed/update/urn:li:activity:6309257579876929537) - with Björn Kimminich, - [OWASP Stockholm Chapter](https://www.owasp.org/index.php/Stockholm), 18.09.2017 -* Hacking session at - [Angular Talk & Code](https://www.meetup.com/de-DE/Hamburg-AngularJS-Meetup/events/234414398/) - with Björn Kimminich, - [Angular Meetup Hamburg](https://www.meetup.com/de-DE/Hamburg-AngularJS-Meetup/), 13.09.2017 -* Capture The Flag - Security Game by Benjamin Brunzel, Jöran Tesse, Rüdiger Heins & Sven Strittmatter, - [solutions.hamburg](https://solutions.hamburg), 08.09.2017 -* OWASP Juice Shop - Einmal quer durch den Security-Saftladen by Björn - Kimminich, [solutions.hamburg](https://solutions.hamburg), 08.09.2017 -* [Black Box Threat Modeling](https://www.peerlyst.com/posts/bsidestlv-2017-black-box-threat-modeling-avid) - by Avi Douglen, [BSides Tel Aviv 2017](https://bsidestlv.com/), Underground Track, 28.06.2017 -* [OWASP update](https://www.meetup.com/OWASP-Bristol/events/235736793) - by Katy Anton, - [OWASP Bristol (UK) Chapter](https://www.owasp.org/index.php/Bristol), 22.06.2017 -* [Update on OWASP Projects & Conferences](https://www.owasp.org/index.php/London#Thursday.2C_18th_May_2017_.28Central_London.29) - by Sam Stepanyan, - [OWASP London Chapter](https://www.owasp.org/index.php/London#OWASP_London) - Meeting, 18.05.2017 -* [OWASP Juice Shop: Achieving sustainability for open source projects](https://appseceurope2017.sched.com/event/A66A/owasp-juice-shop-achieving-sustainability-for-open-source-projects) - , - [AppSec Europe 2017](https://2017.appsec.eu) by Björn Kimminich, - 11.05.2017 ([YouTube](https://www.YouTube.com/watch?v=bOSdFnFAYNc)) -* [OWASP Juice Shop: Stammtisch-Lightning-Update](http://lanyrd.com/2017/owasp-de/sfrdtq/) - by Björn Kimminich, - [27. OWASP Stammtisch Hamburg](http://lanyrd.com/2017/owasp-de/), 25.04.2017 -* [Juice Shop Hacking Session](https://www.xing.com/events/juice-shop-hacking-session-1771555) - by Jens Hausherr, - [Software-Test User Group Hamburg](https://www.xing.com/communities/groups/software-test-user-group-hamburg-1207-1002644) - , 21.03.2017 -* [Hands on = Juice Shop Hacking Session](http://lanyrd.com/2017/software-tester-group-hamburg-16032017/sfqcxq/) - by Björn Kimminich, - [Software Tester Group Hamburg (English-speaking)](http://lanyrd.com/2017/software-tester-group-hamburg-16032017), - 16.03.2017 -* [Kurzvortrag: Hack the Juice Shop](https://www.meetup.com/de-DE/phpughh/events/235572004/) - by Timo Pagel, - [PHP-Usergroup Hamburg](https://www.meetup.com/de-DE/phpughh/), 14.02.2017 - -#### 2016 - -* [Lightning Talk: What's new in OWASP Juice Shop](https://www.owasp.org/index.php/German_OWASP_Day_2016#Programm) - by Björn Kimminich, - [German OWASP Day 2016](https://www.owasp.org/index.php/German_OWASP_Day_2016/), 29.11.2016 -* [Gothenburg pwns the OWASP Juice Shop](https://owaspgbgday.se/bjorn-kimminich-gothenburg-pwns-the-owasp-juice-shop-workshop/) - by Björn Kimminich, - [OWASP Gothenburg Day 2016](https://owaspgbgday.se/), 24.11.2016 -* [Hacking the OWASP Juice Shop](http://lanyrd.com/2016/owasp-nl/sffmpr/) - by Björn Kimminich, - [OWASP NL Chapter Meeting](http://lanyrd.com/2016/owasp-nl/), - 22.09.2016 ([YouTube](https://www.YouTube.com/watch?v=62Mj0ZgZvXc), - :godmode: _in last 10min_) -* [Hacking-Session für Developer (und Pentester)](https://www.kieler-linuxtage.de/index.php?seite=programm.html#226) - by Timo Pagel, - [Kieler Open Source und Linux Tage](https://www.kieler-linuxtage.de/index.php?seite=programm.html), 16.09.2016 -* [Security-Auditing aus der Cloud – Softwareentwicklung kontinuierlich auf dem Prüfstand](http://www.sea-con.de/seacon2016/konferenz/konferenzprogramm/vortrag/do-41-2/title/security-auditing-aus-der-cloud-softwareentwicklung-kontinuierlich-auf-dem-pruefstand.html) - by Robert Seedorff & Benjamin Pfänder, - [SeaCon 2016](http://www.sea-con.de/seacon2016), 12.05.2016 -* [Hacking the Juice Shop ("So ein Saftladen!")](http://lanyrd.com/2016/javaland/sdtbph/) - by Björn Kimminich, [JavaLand 2016](http://lanyrd.com/2016/javaland/), 08.03.2016 -* [Hacking the JuiceShop! ("Hackt den Saftladen!")](http://lanyrd.com/2016/nodehamburg/sdxtch/) - by Björn Kimminich, - [node.HH Meetup: Security!](http://lanyrd.com/2016/nodehamburg/), 03.02.2016 -* [OWASP Top 5 Web-Risiken](http://lanyrd.com/2016/nodehamburg/sdxtcg/) - by Timo Pagel, - [node.HH Meetup: Security!](http://lanyrd.com/2016/nodehamburg/), 03.02.2016 - -#### 2015 - -* [Lightning Talk: Hacking the Juice Shop ("So ein Saftladen!")](http://lanyrd.com/2015/owasp-d2015/sdtzgg/) - by Björn Kimminich, - [German OWASP Day 2015](http://lanyrd.com/2015/owasp-d2015/), 01.12.2015 -* [Juice Shop - Hacking an intentionally insecure JavaScript Web Application](http://lanyrd.com/2015/jsunconf/sdmpzk/) - by Björn Kimminich, - [JS Unconf 2015](http://lanyrd.com/2015/jsunconf/), 25.04.2015 -* [So ein Saftladen! - Hacking Session für Developer (und Pentester)](http://lanyrd.com/2015/owasp-de/sdhctr/) - 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) +# References [![Mentioned in Awesome AppSec](https://awesome.re/mentioned-badge.svg)](https://github.com/paragonie/awesome-appsec) + +Did you write a blog post, magazine article or do a podcast about or mentioning OWASP Juice Shop? Add it to this file +and open a PR! The same goes for conference or meetup talks, workshops or trainings you did where this project was +mentioned or used! + +> :bulb: indicates resources that contain _hints for solving challenges_ +> of the OWASP Juice Shop. These are supposed to be helpful whenever you +> get stuck. :godmode: indicates resources that _spoiler entire +> challenge solutions_, so you might not want to view them before +> 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) + - [2024](#2024) + - [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) + in November 2017 + ([:camera:](https://twitter.com/owasp_juiceshop/status/930917114948587526)) +* [Heroku Button of the Month](https://hello.heroku.com/webmail/36622/844098776/9fe33b8eda9eb79bca7ee569888b1874) + in March 2019 + ([:camera:](https://twitter.com/owasp_juiceshop/status/1110641064673710080)) + +## Web Links + +### Pod- & Webcasts + +* [ZAP Chat 05 Modern Apps Part 1](https://www.youtube.com/watch?v=Rq_d7OLmMfw) on [ZAP](https://www.youtube.com/@psiinon) with Simon Bennetts +* [OWASP Spotlight - Project 25 - OWASP Juice Shop](https://www.youtube.com/watch?v=--50rE76EeA) by Vandana Verma with + Björn Kimminich +* [Visual application security testing with ZAP and Simon Bennetts #DemoDays](https://youtu.be/4xBJsRNV9ds) by [GitHub](https://www.youtube.com/channel/UC7c3Kb6jYCRj4JOHHZTxKsQ) with Simon Bennetts :mega: +* [Exploiting an SSRF vulnerability](https://www.youtube.com/watch?v=OvwNa5CN5yc) by [PinkDraconian](https://www.youtube.com/channel/UCmXwpkCXmIKjoRLMsq9I3RA) :bulb: +* [OWASP Spotlight - Project 20 - OWASP Security Pin](https://www.youtube.com/watch?v=GnSddCV4UwM) by Vandana Verma with + Timo Pagel :mega: +* [People | Process | Technology Podcast](https://soundcloud.com/owasp-podcast/) + (fka "OWASP 24/7 Podcast"): + * [OWASP Flagship Projects - Episode 02](https://soundcloud.com/owasp-podcast/owasp-flagship-projects-episode-02) + * [Less than 10 Minutes Series: The Juice Shop Project](https://soundcloud.com/owasp-podcast/less-than-10-minutes-series-the-juice-shop-project) +* [Learn Web App Security Penetration Testing with Juice Shop \[Free\]](https://youtu.be/ShUTDUYEMWA) + by + [Gerald Auger - Simply Cyber](https://www.YouTube.com/channel/UCG-48Ki-b6W_siaUkukJOSw) +* [Web security for web developers with Zaproxy by Simon Bennetts](https://youtu.be/54UV2_JwcIY) + with + [Eddie Jaoude](https://www.YouTube.com/channel/UC5mnBodB73bR88fLXHSfzYA) + :mega: +* [ZAP in Ten](https://www.alldaydevops.com/zap-in-ten) with Simon Bennetts + * [ZAP in Ten: ADDO Workshop Section 1 - Introduction](https://play.vidyard.com/BAmiaxyzS3g2BCgX2vbVvV) + :mega: + * [ZAP in Ten: ADDO Workshop Section 3 - Packaged Scans](https://play.vidyard.com/iT5C1onahsh3YhQi5SRnLL) + :mega: + * [ZAP in Ten: ADDO Workshop Section 4 - Intro to Authentication](https://play.vidyard.com/zwWm4qMRc8wD2KAgozvC5t) + :mega: + * [ZAP in Ten: ADDO Workshop Section 6 - Standard Auth with JuiceShop](https://play.vidyard.com/igf3A8UdZ6QAGiFjEpLH86) + * [ZAP in Ten: ADDO Workshop Section 8 - JuiceShop SSO Authentication](https://play.vidyard.com/TMcBcuhyPt57sUqPcJUtpv) +* 15min video tutorial by + [Nick Malcolm](https://www.YouTube.com/channel/UCgU77NClL2pLS92viQro6yA): + [OWASP Juice Shop 101](https://youtu.be/8ZYoe0xu6QY) :godmode: +* [Application Security Podcast](https://securityjourney.com/application-security-podcast): + * [Björn Kimminich -- OWASP Juice Shop](https://www.buzzsprout.com/1730684/14121640-bjorn-kimminich-owasp-juice-shop) ([YouTube](https://youtu.be/ay5A7BcZxIs?si=nzhYfVqG5o7l9bWA)) + * Episode 7.2: + [Jannik Hollenbach — Multijuicer: JuiceShop with a side of Kubernetes](https://podcast.securityjourney.com/jannik-hollenbach-multijuicer-juiceshop-with-a-side-of-kubernetes/) + ([YouTube](https://youtu.be/3M6EMDKIAYs)) + * Episode 5.21: + [Season 5 Finale — A cross section of #AppSec (S05E21)](https://podcast.securityjourney.com/season-5-finale-a-cross-section-of-appsec/) + (contains + [5 minute AppSec: Björn Kimminich — JuiceShop](https://www.securityjourney.com/blog/bjorn-kimminich-juiceship-5-minute-appsec/) + entirely) + * Episode 5.20: + [Ronnie Flathers - Security programs big and small](https://podcast.securityjourney.com/ronnie-flathers-security-programs-big-and-small/) + :mega: + * Episode 5.9: + [The new JuiceShop, GSOC, and Open Security Summit](https://securityjourney.com/blog/bjorn-kimminich-the-new-juiceshop-gsoc-and-open-security-summit/) + * 5 minute AppSec: + [Björn Kimminich — JuiceShop](https://www.securityjourney.com/blog/bjorn-kimminich-juiceship-5-minute-appsec/) + * Episode 4.27: + [Season 4 Finale (S04E27)](https://www.securityjourney.com/blog/season-4-finale-s04e27/) + (snippet from + [4.17](https://securityjourney.com/blog/the-joy-of-the-vulnerable-web-juiceshops04e17/)) + * Episode 4.20: + [Security Culture Hacking: Disrupting the Security Status Quo (S04E20)](https://www.securityjourney.com/blog/security-culture-hacking-disrupting-the-security-status-quo-s04e20/) + :mega: + * Episode 4.17: + [The Joy of the Vulnerable Web: JuiceShop (S04E17)](https://securityjourney.com/blog/the-joy-of-the-vulnerable-web-juiceshops04e17/) +* Webcast recording on [7 Minute Security](https://7ms.us): + [DIY $500 Pentest Lab - Part 1](https://www.YouTube.com/watch?v=7qnaR6ZmJzA) + :mega: +* Recorded live streams from the + [Twitch](https://aka.ms/DevSlopTwitch)/[Mixer](https://aka.ms/DevSlop-Mixer) + [OWASP DevSlop](https://devslop.co/) Show: + * [OWASP DevSlop E12 - Juice Shop with Björn Kimminich](https://www.twitch.tv/videos/337620852) + ([YouTube](https://youtu.be/KEYWRtGNDEc)) :godmode: +* Webcast recording on + [Signal Sciences](https://vimeo.com/signalsciences): + [Secure Development Lessons from Purposely Insecure Applications](https://vimeo.com/241965102/40f6b1778b) +* [7 Minute Security](https://7ms.us) Podcast: + * Episode #403: + [7MOOMAMA - Juice Shop Song + Backdoors and Breaches Jingle](https://7ms.us/7ms-403-7moomama-juice-shop-song-backdoors-and-breaches-jingle/) + * Episode #318: + [Interview with Bjorn Kimminich of OWASP Juice Shop](https://7ms.us/7ms-318-interview-with-bjorn-kimminich-of-owasp-juice-shop/) + * Shout outs in various episodes: + [#347](https://7ms.us/7ms-347-happy-5th-birthday-to-7ms/), + [#342](https://7ms.us/7ms-342-interview-with-matt-mccullough/), + [#310](https://7ms.us/7ms-310/), + [#309](https://7ms.us/7ms-309-password-cracking-in-the-cloud-part-2/), + [#306](https://7ms.us/7ms-306-a-peek-into-the-7ms-mail-bag-part-2/) + and [#282](https://7ms.us/7ms-282-a-peek-into-the-7ms-mail-bag/) + :mega: +* Video tutorial about automating web application security scans with + [OWASP ZAP](https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project) + using Juice Shop as the tested app: + [All you need is Zaproxy - Security Testing for WebApps Made Easy](https://www.YouTube.com/watch?v=AQX84p9NhqY) + * [Example integration as a Docker Compose script](https://github.com/Soluto/webdriverio-zap-proxy) + * [Scan results of the example integration](https://jsfiddle.net/62aedL6n/) + +### Blogs & Articles + +* Blog post on [A Tester's Journey](https://www.lisihocke.com/) by Lisi Hocke: [Open Security Conference 2024 - A Memorable Beginning](https://www.lisihocke.com/2024/10/open-security-conference-2024-a-memorable-beginning.html) +* Blog post on [OWASP.org](https://owasp.org) by Björn Kimminich: [OWASP Juice Shop 2023 achievements and beyond](https://owasp.org/blog/2023/10/10/juice-shop-2023.html) +* Article on [Cobalt.io Developer Best Practices](https://developer.cobalt.io/bestpractices/): [Validate User Input](https://developer.cobalt.io/bestpractices/input-validation/) +* Blog post (:de:) on [Dev-Insider](https://www.dev-insider.de/): [OWASP Juice Shop lädt zum Hacken ein](https://www.dev-insider.de/owasp-juice-shop-laedt-zum-hacken-ein-a-968485/) :godmode: +* Blog post on [OWASP.org](https://owasp.org) by Björn Kimminich: + [OWASP Juice Shop v10.0.0 released](https://owasp.org/2020/03/17/juice-shop-v10.html) +* [20+ Free Resources To Legally Practice Your Ethical Hacking Skills](https://blog.elearnsecurity.com/free-resources-to-legally-practice-ethical-hacking.html?utm_source=twitter&utm_medium=social&utm_campaign=eh_resources_blogpost) + on [eLearnSecurity](https://blog.elearnsecurity.com/) :mega: +* Blog post on + [The Daily Swig - Cybersecurity news and views](https://portswigger.net/daily-swig): + [OWASP security projects showcased at All Day DevOps conference](https://portswigger.net/daily-swig/owasp-security-projects-showcased-at-all-day-devops-conference) +* Blog post on [klarsen.net - A Maker's Blog](https://klarsen.net): + [OWASP Juice Shop SQLi](https://klarsen.net/python/owasp-juice-shop-sqli/) +* White paper by Kelley Bryant: + [OWASP: Application Security's Best Friend](https://drive.google.com/file/d/0ByCGDrCX7bx7dnB0TGJJSnNzRmhtUUE4U1RfR3d0YVl4RHFr/view) +* Article (:es:) on Medium by + [Elzer Pineda](https://medium.com/@elzerjp): + [Null Byte Attack Juice Shop y algo mas!!](https://medium.com/@elzerjp/null-byte-attack-juice-shop-y-algo-mas-2c6d271b2fd5) + :godmode: +* Blog post on [Omer Levi Hevroni's blog](https://www.omerlh.info/): + [Hacking Juice Shop, the DevSecOps Way](https://www.omerlh.info/2018/12/23/hacking-juice-shop-the-devsecops-way/) +* Blog post on [Jannik Hollenbach's blog](https://medium.com/@j12934): + [Testing out ModSecurity CRS with OWASP JuiceShop](https://medium.com/@j12934/testing-out-modsecurity-crs-with-owasp-juiceshop-649830932365) +* OWASP Portland Chapter meeting writeup on the + [Daylight Blog](https://thedaylightstudio.com/blog): + [Vulnerability Hunting Practice Using OWASP Juice Shop](https://thedaylightstudio.com/blog/2018/11/20/vulnerability-hunting-practice-using-owasp-juice-shop) +* Blog post on [Security Boulevard](https://securityboulevard.com): + [From Dev to InfoSec Part 1 – The Journey Begins](https://securityboulevard.com/2018/08/from-dev-to-infosec-part-1-the-journey-begins/) +* Blog post on + [Null Byte :: WonderHowTo](https://null-byte.wonderhowto.com): + [Beginner's Guide to OWASP Juice Shop, Your Practice Hacking Grounds for the 10 Most Common Web App Vulnerabilities](https://null-byte.wonderhowto.com/how-to/beginners-guide-owasp-juice-shop-your-practice-hacking-grounds-for-10-most-common-web-app-vulnerabilities-0185103/) + :godmode: +* Blog posts on + [DevelopSec - Developing Better Security](https://www.developsec.com/): + * [Installing OWASP JuiceShop with Docker](https://www.developsec.com/2018/05/10/installing-owasp-juiceshop-with-docker/) + ([YouTube](https://www.YouTube.com/watch?v=ftS8I7WeKtw)) + * [Installing OWASP JuiceShop with Heroku](https://www.developsec.com/2018/05/15/installing-owasp-juiceshop-with-heroku/) + ([YouTube](https://www.YouTube.com/watch?v=umrLbJkJRN0)) + * [Burp Extension – Juice Shop Routes](https://www.developsec.com/2018/05/18/burp-extension-juice-shop-routes/) + ([YouTube](https://www.YouTube.com/watch?v=o628SfvwHp0)) :godmode: +* Blog posts on + [Jason Haley - Ramblings from an Independent Consultant](http://www.jasonhaley.com/): + * [How to Setup OWASP Juice Shop on Azure (Part 1 of 3)](http://www.jasonhaley.com/post/How-to-Setup-OWASP-Juice-Shop-on-Azure-%28Part-1-of-3%29) + * [Setup OWASP Juice Shop in Web App for Containers (Part 2 of 3)](http://www.jasonhaley.com/post/Setup-OWASP-Juice-Shop-in-Web-App-for-Containers-%28Part-2-of-3%29) + * [Setup OWASP Juice Shop in Azure Container Instances (Part 3 of 3)](http://www.jasonhaley.com/post/Setup-OWASP-Juice-Shop-in-Azure-Container-Instances-%28Part-3-of-3%29) +* Blog post on [Josh Grossman's blog](https://joshcgrossman.com): + [Setting up an OWASP Juice Shop CTF](https://joshcgrossman.com/2018/03/15/setting-up-an-owasp-juice-shop-ctf/) +* Blog post on [Mozilla Hacks](https://hacks.mozilla.org): + [Hands-On Web Security: Capture the Flag with OWASP Juice Shop](https://hacks.mozilla.org/2018/03/hands-on-web-security-capture-the-flag-with-owasp-juice-shop/) +* Blog post (:de:) on [heise Developer](https://www.heise.de/developer): + [Sicherheits-Etikette: Security in der Softwareentwicklung](https://www.heise.de/developer/artikel/Sicherheits-Etikette-Security-in-der-Softwareentwicklung-3986402.html) + :mega: +* Blog Post on + [Stuart Winter-Tear's Blog](https://stuartwintertear.net): + [OWASP Juice Shop Vulnerable Webapp](https://stuartwintertear.net/owasp-juice-shop-vulnerable-webapp) + ([Peerlyst cross-post](https://www.peerlyst.com/posts/owasp-juice-shop-vulnerable-webapp-stuart-winter-tear)) +* Blog posts on [OWASP Summit 2017](https://owaspsummit.org): + * [Juice Shop v4.0.0 Live Release](https://owaspsummit.org/2017/06/15/Juice-Shop-Live-Release-v4.html) + * [Juice Shop's call to pre-summit action](https://owaspsummit.org/2017/05/27/Juice-Shops-call-to-pre-summit-action.html) +* Vulnerable website collection on + [Bonkers About Tech](https://www.bonkersabouttech.com): + [40+ Intentionally Vulnerable Websites To (Legally) Practice Your Hacking Skills](https://www.bonkersabouttech.com/security/40-intentionally-vulnerable-websites-to-practice-your-hacking-skills/392) +* Hacking-session writeup on [Testhexen](http://testhexen.de): + [Learning Application Security – Fun with the Juice Shop](http://testhexen.de/?p=117) +* Guest post (:de:) on + [Informatik Aktuell](http://www.informatik-aktuell.de/): + [Juice Shop - Der kleine Saftladen für Sicherheitstrainings](http://www.informatik-aktuell.de/betrieb/sicherheit/juice-shop-der-kleine-saftladen-fuer-sicherheitstrainings.html) +* Guest post on [The official Sauce Labs Blog](http://sauceio.com/): + [Proving that an application is as broken as intended](http://sauceio.com/index.php/2015/06/guest-post-proving-that-an-application-is-as-broken-as-intended/) +* Teaser post on [Björn Kimminich's Blog](http://kimminich.de): + [Juice Shop](https://kimminich.wordpress.com/2015/06/15/juice-shop) + +## Lectures and Trainings + +* [Introduction to OWASP Top 10 Security Risks](https://www.pluralsight.com/cloud-guru/courses/introduction-to-owasp-top-10-security-risks) course by Chris Jackson :dollar: +* Courses on the [freeCodeCamp.org](https://www.YouTube.com/channel/UC8butISFwT-Wl7EV0hUK0BQ) + YouTube channel + * [Ethical Hacking 101: Web App Penetration Testing - a full course for beginners](https://youtu.be/2_lswM1S264) :godmode: by HackerSploit + * [Web Application Ethical Hacking - Penetration Testing Course for Beginners](https://youtu.be/X4eRbHgRawI) :godmode: by The Cyber Mentor +* [Intro to Semgrep](https://lab.github.com/returntocorp/intro-to-semgrep) + GitHub Learning Lab +* [Real World Web Penetration Testing](https://training.secureideas.com/course/real-world-web-pentesting/start-course/) + course by Jason Gillam :dollar: +* [Brakeing Down Security Web App Sec Training #1](https://drive.google.com/drive/folders/0B-qfQ-gWynwidlJ1YjgxakdPWDA) + by Sunny Wear ([YouTube](https://www.YouTube.com/watch?v=zi3yDovd0RY)) +* [Finding Website Vulnerabilities with Burp](https://www.packtpub.com/mapt/video/networking_and_servers/9781788399678/81304/81308/finding-website-vulnerabilities-with-burp) + chapter :godmode: of the + [Mastering Kali Linux Network Scanning](https://www.packtpub.com/networking-and-servers/mastering-kali-linux-network-scanning-video) + video course by Brian Johnson :dollar: +* [University lecture on "IT Security"](https://github.com/bkimminich/it-security-lecture) + as Open Educational Resources material by Björn Kimminich +* [Descargar aqui el taller OWASP Top 10 Hands On basado en OWASP Top 10 y Juice Shop](https://drive.google.com/drive/folders/0B6zv033D1iK9eTJId2RhZkJFTlk?usp=sharing) + (:es:) by Mateo Martinez, Gerardo Canedo and Maxiimiliano Alonzo, + [OWASP Uruguay Chapter](https://www.owasp.org/index.php/Uruguay) +* [Security in Web Applications](https://drive.google.com/drive/folders/0B2KKdB7MPO7xTEwtWkkwTnl5VFk) + by Timo Pagel, [Fachhochschule Kiel](https://www.fh-kiel.de) +* [Web Application Security Training](https://de.slideshare.net/BjrnKimminich/web-application-security-21684264) + by Björn Kimminich + +## Summits & Open Source Events + +* [Juice Shop Track](https://open-security-summit-2020.heysummit.com/topics/owasp-juiceshop/) + at [Open Security Summit 2020](https://open-security-summit.org/) + * [OWASP Juice Shop Cocktail Party: Ask us anything!](https://open-security-summit-2020.heysummit.com/talks/owasp-juice-shop-cocktail-party-ask-us-anything/) + with Björn Kimminich, Jannik Hollenbach & Timo Pagel 15.06.2020 + ([YouTube](https://youtu.be/h5ApBfFMmao)) + * [OWASP Juice Shop Deep Dive: MultiJuicer](https://open-security-summit-2020.heysummit.com/talks/owasp-juice-shop-deep-dive-multijuicer/) + with Jannik Hollenbach & Robert Seedorf, 15.06.2020 + ([YouTube](https://youtu.be/1YHjkc3Xzd0)) + * [OWASP Juice Shop Deep Dive: Integration](https://open-security-summit-2020.heysummit.com/talks/owasp-juice-shop-deep-dive-integration/) + with Björn Kimminich, 15.06.2020 + ([YouTube](https://youtu.be/9SkUohiKgtU)) + * [OWASP Juice Shop Deep Dive: Theming](https://open-security-summit-2020.heysummit.com/talks/owasp-juice-shop-deep-dive-theming-1/) + with Björn Kimminich, 15.06.2020 + ([YouTube](https://youtu.be/WtY712DdlR8)) + * [OWASP Juice Shop Introduction](https://pre-summit-training-sessions.heysummit.com/talks/owasp-juice-shop-introduction/) + with Björn Kimminich, 11.06.2020 + ([YouTube](https://youtu.be/wCF08BdXdDg)) + * [MultiJuicer Introduction](https://pre-summit-training-sessions.heysummit.com/talks/multijuicer-introduction/) + with Jannik Hollenbach and Robert Seedorf, 02.06.2020 + ([YouTube](https://youtu.be/6NMjZbfnTOU)) + * [OWASP Juice Shop Introduction](https://pre-summit-training-sessions.heysummit.com/talks/owasp-juice-shop/) + with Björn Kimminich, 02.06.2020 + ([YouTube](https://youtu.be/Ry0mXz6ZPXc)) +* [Drinks with Adversaries: Creating Adversary Trading Cards](https://pre-summit-training-sessions.heysummit.com/talks/social-drinks-and-adversaries) + with Mark Miller at + [Open Security Summit 2020](https://open-security-summit.org/), + 01.06.2020 ([YouTube](https://www.YouTube.com/watch?v=3roVZNwptOU)) + :mega: +* Selected Project at + [OWASP Projects Summit - Winter 2020](https://owasp.org/www-staff/projects/202002-Projects-Summit-Q1.html) + with Björn Kimminich, Jannik Hollenbach and Marc Rüttler collaborating on + [prepared working packages](https://github.com/juice-shop/juice-shop/milestone/10) + and + [the `v10.0.0` release](https://owasp.org/2020/03/17/juice-shop-v10.html), 27.-29.02.2020 +* [OWASP Juice Shop track](https://github.com/OpenSecuritySummit/oss2019/tree/master/content/tracks/OWASP-Juice-Shop) + and related working sessions organized by Björn Kimminich, + [Open Security Summit 2019](https://github.com/OpenSecuritySummit/oss2019), 03.-07.06.2019 +* Juice Shop related working sessions organized by Jannik Hollenbach and Timo Pagel in + [OWASP Projects track](https://github.com/OpenSecuritySummit/oss2018/tree/master/content/tracks/OWASP-Projects), + [Open Security Summit 2018](https://github.com/OpenSecuritySummit/oss2018), 04.-08.06.2018 +* [Outcome of the Juice Shop track](https://github.com/OWASP/owasp-summit-2017/blob/master/Outcomes/Juice-Shop/Juce-Shop-Update.md) + and related working sessions organized by Björn Kimminich and Timo Pagel, + [OWASP Summit 2017](https://github.com/OWASP/owasp-summit-2017), 12.-16.06.2017 + +### [Google Summer of Code](http://owasp.org/gsoc) + +* Student projects from + [Google Summer of Code 2023](https://summerofcode.withgoogle.com/archive/2023/projects) + * [Companion Guide Tech Stack](https://summerofcode.withgoogle.com/organizations/owasp-foundation/projects/details/h2der3Mf) + by Parth Nanda (mentored by Jannik Hollenbach, Björn Kimminich and Shubham Palriwala) + * [Hacking the Blockchain: Building Web3 Challenges for OWASP Juice Shop](https://summerofcode.withgoogle.com/organizations/owasp-foundation/projects/details/yabiWLkF) + by Rishabh Keshan (mentored by Shubham Palriwala and Björn Kimminich) +* Student project from + [Google Summer of Code 2022](https://summerofcode.withgoogle.com/archive/2022/projects) + * [Replacement for Protractor end-to-end & Frisby API test suite to Cypress](https://summerofcode.withgoogle.com/organizations/owasp-foundation/projects/details/2J1Xedwf) + by Shubham Palriwala (mentored by Jannik Hollenbach and Björn Kimminich) +* Student project from + [Google Summer of Code 2021](https://summerofcode.withgoogle.com/archive/2021/projects) + * [Extending the features of the vulnerable code snippets](https://summerofcode.withgoogle.com/archive/2021/projects/5180407718346752P) + by Ayas Behera (mentored by Jannik Hollenbach and Björn Kimminich) +* Student project from + [Google Summer of Code 2020](https://summerofcode.withgoogle.com/archive/2020/projects) + * [Juice-Shop ChatBot and general fixes](https://summerofcode.withgoogle.com/archive/2020/projects/5660020047347712/) + by Mohit Sharma (mentored by Jannik Hollenbach, Björn Kimminich and Timo Pagel) +* Student project from + [Google Summer of Code 2019](https://summerofcode.withgoogle.com/archive/2019/projects) + * [OWASP Juice Shop: Feature Pack 2019](https://summerofcode.withgoogle.com/archive/2019/projects/6526397403627520/) + by Arpit Agrawal (mentored by Jannik Hollenbach, Björn Kimminich and Shoeb Patel) +* Student projects from + [Google Summer of Code 2018](https://summerofcode.withgoogle.com/archive/2018/projects) + * [OWASP Juice Shop : Challenge Pack 2018](https://summerofcode.withgoogle.com/archive/2018/projects/6267528737193984) + by Shoeb Patel (mentored by Jannik Hollenbach and Timo Pagel) + * [OWASP Juice Shop : Frontend Technology Update](https://summerofcode.withgoogle.com/archive/2018/projects/6636660909408256) + by Aashish Singh (mentored by Björn Kimminich) + +## Conference and Meetup Appearances + +> Upcoming events are marked with :date:. The availability of link destinations for past events cannot be guaranteed. + +#### 2024 + +* :date: [OWASP Juice Shop: Advanced Demos & For-fun CTF](https://god.owasp.de/2024/program-detail.html?talk=trainingOne) with Björn Kimminich & Jannik Hollenbach, [German OWASP Day 2024](https://god.owasp.de/2024), 12.11.2024 +* :date: [OWASP Juice Shop 10th anniversary: Is it still fresh?](https://god.owasp.de/2024/program-detail.html?talk=talkOne) by Björn Kimminich, [German OWASP Day 2024](https://god.owasp.de/2024), 13.11.2024 +* [OWASP Juice Shop 10th anniversary: Is it still fresh?](https://opensecurityconference.org/conference/keynotes) keynote by Björn Kimminich, [Open Security Conference](https://opensecurityconference.org/), 04.10.2024 +* [DSOMM & Juice Shop User Day](https://owasp2024globalappsecsanfra.sched.com/event/1gk01/juice-shop-dsomm-user-day-2024) before [OWASP 2024 Global AppSec San Francisco](https://sf.globalappsec.org/) with Timo Pagel, Jannik Hollenbach & Björn Kimminich, 25.09.2024 +* [OWASP Juice Shop](https://owasp2024globalappsecsanfra.sched.com/event/1ivEu/owasp-juiceshop) talk in Project Track of [OWASP 2024 Global AppSec San Francisco](https://sf.globalappsec.org/) by Björn Kimminich, 27.09.2024 +* [Brick your Juice Shop in 319 easy steps](https://www.meetup.com/owasp-hamburg-stammtisch/events/302138351/) + by Jannik Hollenbach & Björn Kimminich, [69. OWASP Stammtisch Hamburg](https://owasp.org/www-chapter-germany/stammtische/hamburg/), 23.07.2024 +* [OWASP Juice Shop - An Open Source Software and security Fairytale](https://ndc-security.com/agenda/owasp-juice-shop-an-open-source-software-and-security-fairytale-09mg/09ko186cud8) by Björn Kimminich, [NDC Security 2024](https://ndc-security.com/), 11.01.2024 + +#### 2023 + +* [Juice Shop Training: Train the Trainer Edition](http://www.owaspbenelux.eu/program/training#Bj%C3%B6rn-Kimminich) with Björn Kimminich, [OWASP BeNeLux Days 2023](http://www.owaspbenelux.eu/). 24.11.2023 +* [OWASP Juice Shop - An Open Source Software (and security) Fairytale](http://www.owaspbenelux.eu/program/talks#Bj%C3%B6rn-Kimminich) by Björn Kimminich, [OWASP BeNeLux Days 2023](http://www.owaspbenelux.eu/). 23.11.2023 [YouTube](https://youtu.be/54caQ4g72oI) +* [How Vulnerable is Juice Shop? A Secure Code Review of Insecure Code](https://www.nationalcybersummit.com/Program/2023-Agenda) by Joshua Beck, [National Cyber Summit 2023](https://www.nationalcybersummit.com/Home). 20.09.2023 +* [Track keynote: OWASP Juice Shop](https://sikkerhetsfestivalen.no/program-2023) by Björn Kimminich, [Sikkerhetsfestivalen 2023](https://sikkerhetsfestivalen.no/). 29.08.2023 +* [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 [YouTube](https://youtu.be/87DuRYwXtxk) +* [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 [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 + +* [OWASP Juice Shop Project](https://whova.com/web/GKSmlhCK%2FWzBY2c8qqJ%2Bp7kNcnjsUQAQJ%2ByBsjLrbOo%3D/Speakers/) by Björn Kimminich, [OWASP Global AppSec EU](https://whova.com/web/GKSmlhCK%2FWzBY2c8qqJ%2Bp7kNcnjsUQAQJ%2ByBsjLrbOo%3D/), 10.06.2022 ([YouTube](https://www.youtube.com/watch?v=n9DK87g_AIo)) +* [Juice Shop 13: Now with Coding Challenges!](https://www.meetup.com/de-DE/OWASP-Hamburg-Stammtisch/events/282692845/) + by Björn Kimminich, [58. OWASP Stammtisch Hamburg](https://owasp.org/www-chapter-germany/stammtische/hamburg/), 13.01.2022 + +#### 2021 + +* [OWASP Juice Shop Flagship Project](https://owasp20thanniversaryevent20.sched.com/event/m1uL/owasp-juice-shop-flagship-project) + by Björn Kimminich, [OWASP 20th Anniversary Event](https://20thanniversary.owasp.org/), 24.09.2021 ([YouTube](https://youtu.be/rn-6NADRRmI) :godmode:) +* [SDLC con OWASP y laboratorio con OWASP Juice Shop](https://www.meetup.com/de-DE/OWASP-Uruguay-Chapter/events/279827017/) + (:uruguay:) with Martín Marsicano and Pablo Alzuri, + [OWASP Uruguay Chapter](https://owasp.org/www-chapter-uruguay/), + 19.08.2021 [YouTube](https://youtu.be/OAE1EnBNMlc?t=2722) :godmode: +* [Talking Juice Shop and Maintaining a Flagship OWASP Project with Björn Kimminich](https://www.meetup.com/OWASP-Northern-Virginia-Chapter/events/278751084/) + , + [OWASP Northern Virginia Chapter](https://owasp.org/www-chapter-northern-virginia/), + 07.07.2021 ([YouTube](https://youtu.be/uejiQ9VvFu4)) +* [OWASP Aarhus Chapter Worskhop and CTF](https://www.meetup.com/de-DE/OWASP-Aarhus-Chapter/events/277659233/) + with Björn Kimminich, + [OWASP Aarhus Chapter](https://owasp.org/www-chapter-aarhus/), 06.05.2021 +* [Modern Web Application Hacking for Beginners](https://github.com/bkimminich/it-security-lecture/tree/workshop), + virtual 4h diversity training by Björn Kimminich, + [OWASP Training Events 2021 - 2020 SOS Re-run](https://github.com/OWASP/www-event-2021-training), 26.01.2021 + +#### 2020 + +* [FPs are Cheap. Show me the CVEs!](https://www.blackhat.com/eu-20/briefings/schedule/index.html#fps-are-cheap-show-me-the-cves-21345) + by Bas van Schaik & Kevin Backhouse, + [Black Hat Europe 2020](https://www.blackhat.com/eu-20/), 09.12.2020 +* [Juice Shop 12: Novelties by the litre (Online)](https://www.meetup.com/de-DE/OWASP-Hamburg-Stammtisch/events/272842835/) + by Björn Kimminich, + [48. OWASP Stammtisch Hamburg](https://owasp.org/www-chapter-germany/stammtische/hamburg/), + 24.11.2020 ([YouTube](https://youtu.be/AUhDItHHLiY)) +* [Modern Web Application Hacking for Beginners](https://github.com/bkimminich/it-security-lecture/tree/workshop), + virtual 4h diversity training by Björn Kimminich, + [AppSec Days - Summer of Security 2020](https://github.com/OWASP/www-event-2020-08-virtual), 25.08.2020 +* [OWASP Projects Panel](https://www.meetup.com/de-DE/womeninappsec/events/271754765/) + hosted by [OWASP WIA](https://www.meetup.com/womeninappsec/) moderated by Zoe Braiterman with panelists Bjoern + Kimminich, Glenn & Riccardo ten Cate and Spyros Gasteratos, 25.07.2020 + ([YouTube](https://youtu.be/d96-HCrSh2M)) +* [OWASP ZAP Intro (Online)](https://www.meetup.com/de-DE/OWASP-Hamburg-Stammtisch/events/270078609/) + by Simon Bennetts, + [48. OWASP Stammtisch Hamburg](https://owasp.org/www-chapter-germany/stammtische/hamburg/), + 23.04.2020 ([YouTube](https://youtu.be/SD28HdVI-Wk)) :mega: +* [ZAP in Ten, Extended Edition: Automation Deepdive](https://www.alldaydevops.com/addo-speakers/simom-bennetts) + by Simon Bennetts, + [All Day DevOps Spring Break Edition](https://www.alldaydevops.com/), 17.04.2020 :bulb: + +#### 2019 + +* [Juice Shop 9: Would you like a free refill?](https://god.owasp.de/archive/2019/) + by Björn Kimminich, + [German OWASP Day 2019](https://god.owasp.de/archive/2019/), + 10.12.2019 ([YouTube](https://www.YouTube.com/watch?v=L7h5uE7WDfg) + :bulb:) +* [S' OWASP Saft-Lädeli / The OWASP Juice Shop](https://www.meetup.com/de-DE/OWASPSwitzerland/events/264422942/) + by Björn Kimminich, + [OWASP Switzerland Chapter Meeting](https://www.meetup.com/de-DE/OWASPSwitzerland/), 18.11.2019 +* [OWASP Juice Shop: The ultimate All Vuln WebApp](https://www.alldaydevops.com/addo-speakers/bj%C3%B6rn-kimminich) + by Björn Kimminich, [All Day DevOps](https://www.alldaydevops.com/), 06.11.2019 + ([YouTube](https://www.YouTube.com/watch?v=-JuPprlGb48&t=13939s) + :bulb:) +* [Juice Shop](https://globalappsecamsterdam2019.sched.com/event/U84e/juice-shop) + by Björn Kimminich, Project Showcase track of the + [Global AppSec Amsterdam 2019](https://ams.globalappsec.org/), 26.09.2019 ([YouTube](https://youtu.be/XXkMY_VyJ-Y) : + bulb:) +* [Elbsides vs. Juice Shop](https://2019.elbsides.de/programme.html#elbsides-vs-juice-shop) + workshop with Björn Kimminich, + [Elbsides 2019](https://2019.elbsides.de), 16.09.2019 +* [Introduction to OWASP Juice Shop](https://bsidesmcr2019.sched.com/event/Sw0q/introduction-to-owasp-juice-shop) + by Tim Corless-Carter, + [BSidesMCR 2019](https://www.bsidesmcr.org.uk/), 29.08.2019 + ([YouTube](https://youtu.be/hlgp7oeVpac) :godmode:) +* [JavaScript-Security: "Pwn" den Juice Shop](https://enterjs.de/2019/single034c.html?id=7685&javascript-security%3A-%22pwn%22-den-juice-shop) + workshop with Timo Pagel & Björn Kimminich, + [enterJS 2019](https://www.enterjs.de/2019/), 25.06.2019 +* [Web Application Hacking with Burp Suite and OWASP ZAP](https://globalappsectelaviv2019.sched.com/event/MLSU/web-application-hacking-with-burp-suite-and-owasp-zap) + training with Vandana Verma, + [Global Appsec Tel Aviv 2019](https://globalappsectelaviv2019.sched.com), 28.05.2019 +* [A good first impression can work wonders: creating AppSec training that developers <3](https://locomocosec2019.sched.com/event/MGNM/a-good-first-impression-can-work-wonders-creating-appsec-training-that-developers-v) + by Leif Dreizler, + [LocoMocoSec 2019](https://locomocosec2019.sched.com/), 18.04.2019 +* [Pixels vs. Juice Shop](https://github.com/PixelsCamp/talks/blob/master/2019/pixels-vs-juice-shop_bjoern-kimminich.md) + workshop with Björn Kimminich, + [Pixels Camp v3.0](https://pixels.camp), 21.03.2019 +* [OWASP Juice Shop - First you :-D :-D then you :,-(](https://github.com/PixelsCamp/talks/blob/master/2019/owasp-juice-shop_bjoern-kimminich.md) + by Björn Kimminich, [Pixels Camp v3.0](https://pixels.camp), 21.03.2019 ([YouTube](https://youtu.be/v9qrAK_iBa0) : + bulb:) +* [News from the fruit press: Juice Shop 8](https://www.meetup.com/de-DE/OWASP-Hamburg-Stammtisch/events/258185324/) + by Björn Kimminich, + [39. OWASP Stammtisch Hamburg](https://www.meetup.com/de-DE/OWASP-Hamburg-Stammtisch), 27.02.2019 +* [Back to Basics: Hacking OWASP JuiceShop](https://www.owasp.org/index.php/Knoxville#Past_Meetings) + by Jeremy Kelso, + [OWASP Knoxville Chapter Meeting](https://www.owasp.org/index.php/Knoxville), 24.01.2019 + +#### 2018 + +* [Secure Your Pipeline](https://www.facebook.com/events/441842706348978/) + by Omer Levi Hevroni, Negev Web Developers Meetup, 27.12.2018 + ([Slides](https://www.slideshare.net/SolutoTLV/secure-your-pipeline)) +* [Juice Shop: OWASP's most broken Flagship](https://www.owasp.org/index.php/OWASP_BeNeLux-Days_2018#tab=Conference_Day) + by Björn Kimminich, + [OWASP BeNeLux Days 2018](https://www.owasp.org/index.php/OWASP_BeNeLux-Days_2018), + 30.11.2018 ([YouTube](https://youtu.be/Lu0-kDdtVf4) :bulb:) +* [OWASP Zap](https://www.owasp.org/index.php/OWASP_BeNeLux-Days_2018#tab=Conference_Day) + by David Scrobonia, + [OWASP BeNeLux Days 2018](https://www.owasp.org/index.php/OWASP_BeNeLux-Days_2018), + 30.11.2018 ([YouTube](https://youtu.be/iaZaPuQ6ams)) +* [The traditional/inevitable OWASP Juice Shop update](https://owasp.github.io/german-owasp-day/archive/2018/) + by Björn Kimminich, + [German OWASP Day 2018](https://owasp.github.io/german-owasp-day/archive/2018/), + 20.11.2018 ([YouTube](https://youtu.be/2oNfZo2H4uA)) +* [Workshop: OWASP Juice Shop](https://owasp.github.io/german-owasp-day/archive/2018/) + by Björn Kimminich, + [German OWASP Day 2018](https://owasp.github.io/german-owasp-day/archive/2018/), 19.11.2018 +* [OWASP Portland Chapter Meeting - OWASP Juice Shop!](http://calagator.org/events/1250474481) + facilitated by David Quisenberry, + [OWASP Portland Chapter](https://www.owasp.org/index.php/Portland), 08.11.2018 +* [OWASP Juice Shop - Public Lecture](https://www.facebook.com/events/674384206291349) + by Björn Kimminich, + [TalTech Infotehnoloogia Kolledž](https://www.facebook.com/itcollege.ee), + 24.10.2018 ([YouTube](https://youtu.be/79G46CQ3IMk?t=158) :godmode: + _starting 14:55_) +* [JUGHH: Security Hackathon](https://www.meetup.com/jug-hamburg/events/254885956/) + by [iteratec](https://www.iteratec.de/), + [Java User Group Hamburg](https://www.meetup.com/jug-hamburg), 11.10.2018 +* [Playing with OWASP Juice Shop](https://mozilla.or.id/en/space/events/258-playing-with-owasp-juice-shop.html) + by Mohammad Febri R, [Mozilla Indonesia](https://mozilla.or.id/), 05.08.2018 + ([Slides](https://slides.com/mohammadfebri/owasp-juice-shop)) +* [OWASP Juice Shop どうでしょう](https://speakerdeck.com/ninoseki/owasp-juice-shop-doudesiyou) + by Manabu Niseki, + [OWASP Night 2018/7](https://owasp.doorkeeper.jp/events/77466), 30.07.2018 +* [Usable Security Tooling - Creating Accessible Security Testing with ZAP](https://www.meetup.com/de-DE/Bay-Area-OWASP/events/252283865/) + by David Scrobonia, + [OWASP Meetup - SF July 2018](https://www.meetup.com/de-DE/Bay-Area-OWASP/), + 26.07.2018 ([YouTube](https://www.YouTube.com/watch?v=ztfgip-UhWw)) +* [Building an AppSec Program with a Budget of $0: Beyond the OWASP Top 10](https://appseceurope2018a.sched.com/event/EgXt/building-an-appsec-program-with-a-budget-of-0-beyond-the-owasp-top-10) + by Chris Romeo, [OWASP AppSec Europe 2018](https://2018.appsec.eu), + 06.07.2018 ([YouTube](https://www.YouTube.com/watch?v=5RmHQKeXgk4)) + :mega: +* [OWASP Juice Shop: Betreutes Hacken](https://www.meetup.com/de-DE/owasp-karlsruhe/events/251041169/) + with + [OWASP Stammtisch Karlsruhe](https://www.owasp.org/index.php/OWASP_Stammtisch_Karlsruhe), 04.06.2018 +* [Hacking Workshop - Twin Cities vs. OWASP Juice Shop](https://secure360.org/secure360-twin-cities/schedule/?conference=9826&date=20180517) + with Björn Kimminich, + [Secure360 Twin Cities](https://secure360.org/secure360-twin-cities/), 17.05.2018 +* [OWASP Juice Shop - The Ultimate Vulnerable WebApp](https://secure360.org/session/bjorn-kimminich-owasp-juice-shop-the-ultimate-vulnerable-webapp/?conference=9826&date=20180516) + by Björn Kimminich, + [Secure360 Twin Cities](https://secure360.org/secure360-twin-cities/), 16.05.2018 +* [OWASP MSP Chapter May Meeting](https://www.meetup.com/OWASP-MSP-Meetup/events/249940370/) + with Björn Kimminich, + [OWASP MSP Meetup](https://www.meetup.com/OWASP-MSP-Meetup/) St Paul, 14.05.2018 +* [OWASP Juice Shop - The next chapter ...](https://www.meetup.com/CyberHackathon/events/249606655/?eventId=249606655) + with Jaan Janesmae, + [CyberHackathon](https://www.meetup.com/CyberHackathon/) Tallinn, 30.04.2018 +* OWASP Juice Shop Introduction at + [ChaosTreff Tallinn Weekly Meetup](https://www.meetup.com/ChaosTreff-Tallinn/events/249627780/) + with Björn Kimminich, + [ChaosTreff Tallinn](https://www.meetup.com/ChaosTreff-Tallinn/), 26.04.2018 +* [OWASP Juice Shop Intro and Getting Started](https://www.meetup.com/CyberHackathon/events/249359520/?eventId=249359520) + with Jaan Janesmae, + [CyberHackathon](https://www.meetup.com/CyberHackathon/) Tallinn, 09.04.2018 +* [Web Application Security: A Hands-on Testing Challenge](https://dojo.ministryoftesting.com/events/testbash-brighton-2018) + by Dan Billing, + [TestBash Brighton 2018](https://dojo.ministryoftesting.com/events/testbash-brighton-2018), 15.03.2018 +* [OWASP Top 10](https://appseccalifornia2018.sched.com/event/CuRs) by Andrew van der Stock, + [OWASP AppSec California 2018](https://2018.appseccalifornia.org/), + 30.01.2018 ([YouTube](https://www.YouTube.com/watch?v=TXAztSpYpvE) + :godmode: _starting 25:40_) + +#### 2017 + +* [OWASP Juice Shop 5.x and beyond](https://www.owasp.org/index.php/German_OWASP_Day_2017#Programm) + by Björn Kimminich, + [German OWASP Day 2017](https://www.owasp.org/index.php/German_OWASP_Day_2017), 14.11.2017 +* [OWASP Juice Shop Introduction](https://www.owasp.org/index.php/OWASP_Bucharest_AppSec_Conference_2017#tab=Conference_talks) + talk and + [AppSec Bucharest vs. OWASP Juice Shop](https://www.owasp.org/index.php/OWASP_Bucharest_AppSec_Conference_2017#tab=Free_workshops) + hacking workshop by Björn Kimminich, + [OWASP Bucharest AppSec Conference 2017](https://www.owasp.org/index.php/OWASP_Bucharest_AppSec_Conference_2017), + 13.10.2017 +* [2 Hour Hacking: Juice Shop](https://www.meetup.com/de-DE/OWASP-Los-Angeles/events/238321796/) + by Timo Pagel, + [OWASP Los Angeles](https://www.meetup.com/de-DE/OWASP-Los-Angeles/), 10.10.2017 +* [Hacking the OWASP Juice Shop](https://www.owasp.org/index.php/North_Sweden#2017-09-19_-_2017q3:_Hacking_the_OWASP_Juice_Shop) + with Björn Kimminich, + [OWASP North Sweden Chapter](https://www.owasp.org/index.php/North_Sweden), 19.09.2017 +* [OWASP Juice Shop Workshop](https://www.linkedin.com/feed/update/urn:li:activity:6309257579876929537) + with Björn Kimminich, + [OWASP Stockholm Chapter](https://www.owasp.org/index.php/Stockholm), 18.09.2017 +* Hacking session at + [Angular Talk & Code](https://www.meetup.com/de-DE/Hamburg-AngularJS-Meetup/events/234414398/) + with Björn Kimminich, + [Angular Meetup Hamburg](https://www.meetup.com/de-DE/Hamburg-AngularJS-Meetup/), 13.09.2017 +* Capture The Flag - Security Game by Benjamin Brunzel, Jöran Tesse, Rüdiger Heins & Sven Strittmatter, + [solutions.hamburg](https://solutions.hamburg), 08.09.2017 +* OWASP Juice Shop - Einmal quer durch den Security-Saftladen by Björn + Kimminich, [solutions.hamburg](https://solutions.hamburg), 08.09.2017 +* [Black Box Threat Modeling](https://www.peerlyst.com/posts/bsidestlv-2017-black-box-threat-modeling-avid) + by Avi Douglen, [BSides Tel Aviv 2017](https://bsidestlv.com/), Underground Track, 28.06.2017 +* [OWASP update](https://www.meetup.com/OWASP-Bristol/events/235736793) + by Katy Anton, + [OWASP Bristol (UK) Chapter](https://www.owasp.org/index.php/Bristol), 22.06.2017 +* [Update on OWASP Projects & Conferences](https://www.owasp.org/index.php/London#Thursday.2C_18th_May_2017_.28Central_London.29) + by Sam Stepanyan, + [OWASP London Chapter](https://www.owasp.org/index.php/London#OWASP_London) + Meeting, 18.05.2017 +* [OWASP Juice Shop: Achieving sustainability for open source projects](https://appseceurope2017.sched.com/event/A66A/owasp-juice-shop-achieving-sustainability-for-open-source-projects) + , + [AppSec Europe 2017](https://2017.appsec.eu) by Björn Kimminich, + 11.05.2017 ([YouTube](https://www.YouTube.com/watch?v=bOSdFnFAYNc)) +* [OWASP Juice Shop: Stammtisch-Lightning-Update](http://lanyrd.com/2017/owasp-de/sfrdtq/) + by Björn Kimminich, + [27. OWASP Stammtisch Hamburg](http://lanyrd.com/2017/owasp-de/), 25.04.2017 +* [Juice Shop Hacking Session](https://www.xing.com/events/juice-shop-hacking-session-1771555) + by Jens Hausherr, + [Software-Test User Group Hamburg](https://www.xing.com/communities/groups/software-test-user-group-hamburg-1207-1002644) + , 21.03.2017 +* [Hands on = Juice Shop Hacking Session](http://lanyrd.com/2017/software-tester-group-hamburg-16032017/sfqcxq/) + by Björn Kimminich, + [Software Tester Group Hamburg (English-speaking)](http://lanyrd.com/2017/software-tester-group-hamburg-16032017), + 16.03.2017 +* [Kurzvortrag: Hack the Juice Shop](https://www.meetup.com/de-DE/phpughh/events/235572004/) + by Timo Pagel, + [PHP-Usergroup Hamburg](https://www.meetup.com/de-DE/phpughh/), 14.02.2017 + +#### 2016 + +* [Lightning Talk: What's new in OWASP Juice Shop](https://www.owasp.org/index.php/German_OWASP_Day_2016#Programm) + by Björn Kimminich, + [German OWASP Day 2016](https://www.owasp.org/index.php/German_OWASP_Day_2016/), 29.11.2016 +* [Gothenburg pwns the OWASP Juice Shop](https://owaspgbgday.se/bjorn-kimminich-gothenburg-pwns-the-owasp-juice-shop-workshop/) + by Björn Kimminich, + [OWASP Gothenburg Day 2016](https://owaspgbgday.se/), 24.11.2016 +* [Hacking the OWASP Juice Shop](http://lanyrd.com/2016/owasp-nl/sffmpr/) + by Björn Kimminich, + [OWASP NL Chapter Meeting](http://lanyrd.com/2016/owasp-nl/), + 22.09.2016 ([YouTube](https://www.YouTube.com/watch?v=62Mj0ZgZvXc), + :godmode: _in last 10min_) +* [Hacking-Session für Developer (und Pentester)](https://www.kieler-linuxtage.de/index.php?seite=programm.html#226) + by Timo Pagel, + [Kieler Open Source und Linux Tage](https://www.kieler-linuxtage.de/index.php?seite=programm.html), 16.09.2016 +* [Security-Auditing aus der Cloud – Softwareentwicklung kontinuierlich auf dem Prüfstand](http://www.sea-con.de/seacon2016/konferenz/konferenzprogramm/vortrag/do-41-2/title/security-auditing-aus-der-cloud-softwareentwicklung-kontinuierlich-auf-dem-pruefstand.html) + by Robert Seedorff & Benjamin Pfänder, + [SeaCon 2016](http://www.sea-con.de/seacon2016), 12.05.2016 +* [Hacking the Juice Shop ("So ein Saftladen!")](http://lanyrd.com/2016/javaland/sdtbph/) + by Björn Kimminich, [JavaLand 2016](http://lanyrd.com/2016/javaland/), 08.03.2016 +* [Hacking the JuiceShop! ("Hackt den Saftladen!")](http://lanyrd.com/2016/nodehamburg/sdxtch/) + by Björn Kimminich, + [node.HH Meetup: Security!](http://lanyrd.com/2016/nodehamburg/), 03.02.2016 +* [OWASP Top 5 Web-Risiken](http://lanyrd.com/2016/nodehamburg/sdxtcg/) + by Timo Pagel, + [node.HH Meetup: Security!](http://lanyrd.com/2016/nodehamburg/), 03.02.2016 + +#### 2015 + +* [Lightning Talk: Hacking the Juice Shop ("So ein Saftladen!")](http://lanyrd.com/2015/owasp-d2015/sdtzgg/) + by Björn Kimminich, + [German OWASP Day 2015](http://lanyrd.com/2015/owasp-d2015/), 01.12.2015 +* [Juice Shop - Hacking an intentionally insecure JavaScript Web Application](http://lanyrd.com/2015/jsunconf/sdmpzk/) + by Björn Kimminich, + [JS Unconf 2015](http://lanyrd.com/2015/jsunconf/), 25.04.2015 +* [So ein Saftladen! - Hacking Session für Developer (und Pentester)](http://lanyrd.com/2015/owasp-de/sdhctr/) + 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 8235fa23..c8a6fc84 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,126 +1,126 @@ -# Security Policy - -OWASP Juice Shop is an _intentionally vulnerable_ web application, but we still do not want to be suprised by zero day -vulnerabilities which are not part of our hacking challenges. We are following the proposed Internet -standard so you can find our -"security" policy in any running instance of the application at the expected location described in -. Finding it is actually one of our hacking challenges! - -## Supported Versions - -We provide security patches for the latest released minor version. - -| Version | Supported | -|:--------|:-------------------| -| 17.1.x | :white_check_mark: | -| <17.1 | :x: | - -## Reporting a Vulnerability - -For vulnerabilities which are **not** part of any hacking challenge please contact . In all -other cases please contact our shop's "security team" at the address mentioned in the -`security.txt` accessible through the running application. - -> Instead of fixing reported vulnerabilities we might turn them into -> hacking challenges! You might receive a reward for reporting a -> vulnerability that makes it into one of our challenges! - -### Encrypted communication - -You can encrypt emails to with PGP using the public key `062A85A8CBFBDCDA`: - -``` ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2 - -mQENBFUSf5YBCADDkR5JZ54H77VoHy4yw3xIW9Y5rzJtCxB6VXfRAi26GbtnCOzX -csPAVU+CZ2iHj1jBX876ib7XazGCr99l26W3dHdJk4v8kRsFHSfYu1kGZcQBSWLX -CP6zHFDhQOkxFM/ild7HHWi1+fSyCPKT31o4TrRlYA4Q6h2KQzBYh9KGX4DvyVAK -+oiMSbsJzZZrWeF3QUUWBZzOO1Yvfr5RQKx+rffPT+CeOXdtE5jHcaOpqbjLVkHO -p7wOeNh2joweebF7jBMXkgrbEVzIO762PlPAnJWAvQDjef2aiz5Ok265vXLBAf/p -7Cgb1P0rzQmOPvDA0KZ3vGqh96lUhxLXc3NtABEBAAG0M0Jqw7ZybiBLaW1taW5p -Y2ggPGJqb2Vybi5raW1taW5pY2hAbm9yZGFrYWRlbWllLmRlPokBOQQTAQgAIwUC -VRM9zgIbDwcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEAYqhajL+9zaO38I -AINazwGQtf2cIEYQo3fHjgJ0d+kgR5/79LUpOSC1m9I2FXntkWJ0DYYsGDwZsGKq -nGVUhRDtvbUkNAhtnhZ6QVgljtFgtn9LE7+kYnOGrhIW0CY4shwkTgUwwK96bpxL -hKeu4AQZXiGyRleyKd/qHDdQLwHWAAlUB5E4nSNrwR0cCTWOxnqdc9pz/ag4HOCo -VB7M9oEHQcyAXcAxge8pBs6phmI5TgX2Q7lzGzYMAKXSc0azdevocJeZHZlZeacQ -EuY0G6QkND0suyoiAD9vJR7UkXHOK9fd51pVSycoAXneAC64oZbsnWn9POyVZYW5 -40W7wa51cbrSa5Xe10GNLYuIRgQTEQIABgUCVS94hwAKCRArrjz22v+wAEwUAJ9F -WN/CcJxqniBjOFNKkNrkr8Wa1QCfY3ke3X34zSmnQ6QKuv+l7q4MPoa0LUJqw7Zy -biBLaW1taW5pY2ggPGJqb2Vybi5raW1taW5pY2hAb3dhc3Aub3JnPokBOQQTAQgA -IwUCVRM9wAIbDwcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEAYqhajL+9za -DPAIAKJWYvfCHOZUv8v92q2U5xH/yXqaz78OK6k1w8tCSyNhFLvkd4R3HMrcgnLk -3CygqMqHAOO15ijg0I1DC2cBPRDLgVQreZNlog+6njIDmtigVFjPUqrQxYejW+t7 -LtZqT/7e8PRz7wVt5wQKlkZSbaEOyPkfIP5NvlGUbJlGriC5nQbSvnYFKRQXbwGD -HBDUttM0L2aC7uAwRH4qX79vE8JMe62lobsh7pI0Nez8lxR8U1cZPKHixikTDEvb -ZG8T+SAXAh/yE85oWAw81zZU8gqUHzGtTikPXCcC4kfACO6/aiUe89UPb49jF/n5 -tTTELHM/YXQES+P3KRwHRpPfngqIRgQTEQIABgUCVS94hwAKCRArrjz22v+wAHyc -AJ9Gllz+luFqWRPmeMvQm0Ag4Vnm1QCeOyLh0kJGSQqMmORPchfUbStmjTC0LUJq -b2VybiBLaW1taW5pY2ggPGJqb2Vybi5raW1taW5pY2hAb3dhc3Aub3JnPokBOQQT -AQgAIwUCVRM9tQIbDwcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEAYqhajL -+9zaSRIH/1Qnl09+jISxyQSDaRqzzG2cyCIbdViCLz+b0vATwSOsTqtK0lY1m9i+ -8v4S67z+S5+/klGovC1HAHH4TJOsOAAxqp6AAd9ufynCZNb6Y/9z7AnQcbBccC5X -hR8Eq/STrqM3pF1dpABIL67pwfZ7MqB0xCYkWICB5BgnHrCr29EcUOw7C6gKhFB3 -9A/YfG6D6Lzs/0cKdAbZclSinzxwyvQ8n8VnSQq9CYMYRPE9eLQDrl93IyJnXOuE -ez9abJv5DIjJsGayAEz4H7xYSm2Ao/Hr0Ap3P4zywG3QBZqX3OPYR6ojXMNagQZK -UYNQrvTOvymi1NiNLkWeaaSKS5oYBhyIRgQTEQIABgUCVS94hwAKCRArrjz22v+w -AD9EAJ0aapSfv7GwzKZeyG/9Ydpz7XrUmACeK3vmctUHKn4+gCDGYuGLyQSmwF20 -JkJqb2VybiBLaW1taW5pY2ggPGJqb2VybkBraW1taW5pY2guZGU+iQE5BBMBCAAj -BQJVEz1lAhsPBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQBiqFqMv73Nqi -ngf+N5Ft66CdvLl4J/oyf8BVDmlI1nvyr2s3zM7ZWGOCgawcB09uq8i9ZE2jZu3l -NHhKQdmYnrEEgKDhC3Rd1tj/MqSZ90/z22FczovarVTWvZ7oy0tMzfokcTfcbXsm -YRaFJT1/rUt9ThBg9SAAnO06BkbF1ZgZSxSG24Do7trpiv8aqId1i+cHE7UwhuP5 -8ArLij2+u1VpUnX0pzR4t2/JaIoYx6tuoIX+LnsUsohmkVo8gAvWOMDsA3zqxG6T -lQ0nVxQ7BMq0aeVmjvnamLvrSte8ByLnW9q65i0/nTxHqwVVnhTLHjXYKYQHYdd6 -K/4UoiKiWz9Ro/27bf2lHNpVeYhGBBMRAgAGBQJVL3iHAAoJECuuPPba/7AAfCoA -n2v7/Z30CB4bHpCqeYxiL12F34M2AJ4/mfN9uGYj91TYJ/cgFwI6LndxTrQmQmrD -tnJuIEtpbW1pbmljaCA8YmpvZXJuQGtpbW1pbmljaC5kZT6JATkEEwEIACMFAlUT -PVUCGw8HCwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgAAKCRAGKoWoy/vc2soDB/wJ -jmocZ3fYpwvJZy7lqknXkXBxJBKX1BBBz4sHXueJeBqdJ+yCbzhluSlWOzFO+1Cb -wr0uJ7UCzfB+wBQ6EsKOLJHZLlixBoj6/lTF2bQFceAI0w5coZWIeYUzRAmyguiY -YPpE3+hBPY47osVqIXle2QblKthVrI6FToTwAomOWRCX/oJCnJ+x3LJiHHj3HKfw -8Gy1BalosL2p2V4V1vr/6TbWsuj3L0nxmDEM7877VNiHw2jL6Jp+V9GzOeWvS7Pi -KnPXVLAp81A9SKhNiEEAlsGcWtz6Bm3WaT1D4fFwuEm2RdjP8kO3uoxtvhRzej/W -jHT4zomR6/h+C/nw0aTuiEYEExECAAYFAlUveIcACgkQK6489tr/sAB7twCfa396 -dnFYG4eGszFLs8JFO5Klcr8An2FBTcVIwOBEo3m294V2npnv1Z+utCpCam9lcm4g -S2ltbWluaWNoIDxiam9lcm4ua2ltbWluaWNoQGdteC5kZT6JATkEEwEIACMFAlUT -PUMCGw8HCwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgAAKCRAGKoWoy/vc2j/fB/9C -PAkZAj4M16AWbLONShxPkYyYnW+yJw6bIuYrcEsNzrYuxxQ3zmJ91Iztuh+HcCnr -8sWOP9iuWe2Q4EctAn2D1Yc8FhcIW51YAwnf66wuGozx7LJAfI53HRCpC5hkGxg5 -y1wVfJcu7Qf7BWfB4J3FLVMdX+4i/roFdGlFfzSI897M/c7HxIZfgnHRWUJaRWrE -x/uOCSbNocAS+vOw7VG2VueVR/i25G4bRr1G6Puts80jZgZojD8L2wxrfwOzBm83 -Mm2IR7EhQvPE61IUo35WJQUbS2uQF/rgY375Eb+Ca7tKKCPe00SCTTuZyiLwCWMo -PLZN3L+JUL85Kk6KTe/ziEYEExECAAYFAlUveIcACgkQK6489tr/sADXRgCeLro0 -0Lb0N8srIRPp53pBEaFMgzwAoIZD5aCEFLyD7+nmpP2nSFOMOLCJtCpCasO2cm4g -S2ltbWluaWNoIDxiam9lcm4ua2ltbWluaWNoQGdteC5kZT6JATkEEwEIACMFAlUT -PSkCGw8HCwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgAAKCRAGKoWoy/vc2lfyB/wO -NuFhITiHDcFeUFUT9CNkrC8zEvVL9+NpiEHHwgVJJrixuem6o8zLPiOK9OsYJwWD -dZeF/nDI0wRQA8bxHwfcIlFKGulldWtCA9SHIgM7LM7lE5S689HaXiEYz2k6y0AK -tR273lPBhYtIvZEkC/tZQ2Grf4rtPW/kI56pZy8Jb0Q99CvBHWneQ9vNS76eq5M3 -9ZDLdSv5FoxNUg7eN+NQ0gBefONgKXykKDT/b6FW12rI8j4OosQJxASpbiagEmCj -j8kmRHJ1vE3kP28xLvogoqP35SZj7FV57AhQPw5M7pKu9xeSMUPl8tmKHiyFh1tw -wY2udDziBjJDc8D3yCyuiEYEExECAAYFAlUveIcACgkQK6489tr/sABVZQCePO8U -X4TFo13F+WfoAk36fLF7Dc0AnRt7Fya08kPFKO3CQSXV4ZaW+S4utEFCasO2cm4g -S2ltbWluaWNoIChQcml2YXRlIEVtYWlsYWRyZXNzZSkgPGJqb2Vybi5raW1taW5p -Y2hAZ214LmRlPokBOQQTAQgAIwUCVRJ/lgIbDwcLCQgHAwIBBhUIAgkKCwQWAgMB -Ah4BAheAAAoJEAYqhajL+9zaavYH/2MNLalQnGL5bTMT+sVhhrtg9qebfWVhE600 -5KYEcXEA3DCXH7SnwKriNQtJCUi94iFPTz6jjGvDlyGaZbuntahB4ynrUhMR8mR/ -uhUxYkSwdV/KMwqEP4i/FJHFgVW/c0EYRBdG2+SJHx81GPFxRnxSsdxq6rjQpa5k -jm2/+uyJi/bF2uBFswOIAk0xHSpEmkbE2YP0wwW+OFV5VL8e2FGjw6KCxyRC6NQN -jxYPhlej2hCvWqqr9TGRx+E4ER8dfUynkbNXDdztP/6dMvx+eGZd7e/So/4g7/Or -pdKx80Uk04igTHJYSZsLN1k4L/h1gfuHsbjMrGVhWLnCC9vtwvaIRgQTEQIABgUC -VS94hwAKCRArrjz22v+wADU0AJ4uw0K5udWlv4ILDDnzRPt+lePbwwCfdIAAQf7U -yeaVcVlyFkulTYoBcwK0M0Jqb2VybiBLaW1taW5pY2ggPGJqb2Vybi5raW1taW5p -Y2hAbm9yZGFrYWRlbWllLmRlPokBOQQTAQgAIwUCVRM92AIbDwcLCQgHAwIBBhUI -AgkKCwQWAgMBAh4BAheAAAoJEAYqhajL+9zasF0H/3Vy4IouO8UEb8bamdyCbLeA -X6x2obdAZIiGmzxgZZ0WPGKbV/6sipYEAlAGGH+2wxXuDXzfjizsY+u9OKsZklw1 -7PlgIW/dkiJuK73SaJwRMUgeq4bhltToaaonIt433ie9srHw+UDyc+M+da89Nv1i -9J5vXVrMU5UCc/Wpy4JZZBJmwAnANUsBvhL/nB0qS9awsl+4bvM+NGZTCscYLfCs -iXaP7j2jI+wHtN16Q1HL98eN/cOXz/e6JX1+Oy6A3QSxU3ku3STEb2wAyJPkx1no -NMBUASYyjLQDEmfC2IRzlRdnHuL5cywzOsDeCNynDQr/RHMKnI+UschHly1Ebi2I -RgQTEQIABgUCVS94hwAKCRArrjz22v+wAKoGAJ4rqhHeTrtZL6xHQKBBwg7Ns3eI -1gCfSZuaBCqxOvuCKUJzqBdmGtBPs/Q= -=z48d ------END PGP PUBLIC KEY BLOCK----- -``` +# Security Policy + +OWASP Juice Shop is an _intentionally vulnerable_ web application, but we still do not want to be suprised by zero day +vulnerabilities which are not part of our hacking challenges. We are following the proposed Internet +standard so you can find our +"security" policy in any running instance of the application at the expected location described in +. Finding it is actually one of our hacking challenges! + +## Supported Versions + +We provide security patches for the latest released minor version. + +| Version | Supported | +|:--------|:-------------------| +| 17.1.x | :white_check_mark: | +| <17.1 | :x: | + +## Reporting a Vulnerability + +For vulnerabilities which are **not** part of any hacking challenge please contact . In all +other cases please contact our shop's "security team" at the address mentioned in the +`security.txt` accessible through the running application. + +> Instead of fixing reported vulnerabilities we might turn them into +> hacking challenges! You might receive a reward for reporting a +> vulnerability that makes it into one of our challenges! + +### Encrypted communication + +You can encrypt emails to with PGP using the public key `062A85A8CBFBDCDA`: + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2 + +mQENBFUSf5YBCADDkR5JZ54H77VoHy4yw3xIW9Y5rzJtCxB6VXfRAi26GbtnCOzX +csPAVU+CZ2iHj1jBX876ib7XazGCr99l26W3dHdJk4v8kRsFHSfYu1kGZcQBSWLX +CP6zHFDhQOkxFM/ild7HHWi1+fSyCPKT31o4TrRlYA4Q6h2KQzBYh9KGX4DvyVAK ++oiMSbsJzZZrWeF3QUUWBZzOO1Yvfr5RQKx+rffPT+CeOXdtE5jHcaOpqbjLVkHO +p7wOeNh2joweebF7jBMXkgrbEVzIO762PlPAnJWAvQDjef2aiz5Ok265vXLBAf/p +7Cgb1P0rzQmOPvDA0KZ3vGqh96lUhxLXc3NtABEBAAG0M0Jqw7ZybiBLaW1taW5p +Y2ggPGJqb2Vybi5raW1taW5pY2hAbm9yZGFrYWRlbWllLmRlPokBOQQTAQgAIwUC +VRM9zgIbDwcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEAYqhajL+9zaO38I +AINazwGQtf2cIEYQo3fHjgJ0d+kgR5/79LUpOSC1m9I2FXntkWJ0DYYsGDwZsGKq +nGVUhRDtvbUkNAhtnhZ6QVgljtFgtn9LE7+kYnOGrhIW0CY4shwkTgUwwK96bpxL +hKeu4AQZXiGyRleyKd/qHDdQLwHWAAlUB5E4nSNrwR0cCTWOxnqdc9pz/ag4HOCo +VB7M9oEHQcyAXcAxge8pBs6phmI5TgX2Q7lzGzYMAKXSc0azdevocJeZHZlZeacQ +EuY0G6QkND0suyoiAD9vJR7UkXHOK9fd51pVSycoAXneAC64oZbsnWn9POyVZYW5 +40W7wa51cbrSa5Xe10GNLYuIRgQTEQIABgUCVS94hwAKCRArrjz22v+wAEwUAJ9F +WN/CcJxqniBjOFNKkNrkr8Wa1QCfY3ke3X34zSmnQ6QKuv+l7q4MPoa0LUJqw7Zy +biBLaW1taW5pY2ggPGJqb2Vybi5raW1taW5pY2hAb3dhc3Aub3JnPokBOQQTAQgA +IwUCVRM9wAIbDwcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEAYqhajL+9za +DPAIAKJWYvfCHOZUv8v92q2U5xH/yXqaz78OK6k1w8tCSyNhFLvkd4R3HMrcgnLk +3CygqMqHAOO15ijg0I1DC2cBPRDLgVQreZNlog+6njIDmtigVFjPUqrQxYejW+t7 +LtZqT/7e8PRz7wVt5wQKlkZSbaEOyPkfIP5NvlGUbJlGriC5nQbSvnYFKRQXbwGD +HBDUttM0L2aC7uAwRH4qX79vE8JMe62lobsh7pI0Nez8lxR8U1cZPKHixikTDEvb +ZG8T+SAXAh/yE85oWAw81zZU8gqUHzGtTikPXCcC4kfACO6/aiUe89UPb49jF/n5 +tTTELHM/YXQES+P3KRwHRpPfngqIRgQTEQIABgUCVS94hwAKCRArrjz22v+wAHyc +AJ9Gllz+luFqWRPmeMvQm0Ag4Vnm1QCeOyLh0kJGSQqMmORPchfUbStmjTC0LUJq +b2VybiBLaW1taW5pY2ggPGJqb2Vybi5raW1taW5pY2hAb3dhc3Aub3JnPokBOQQT +AQgAIwUCVRM9tQIbDwcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEAYqhajL ++9zaSRIH/1Qnl09+jISxyQSDaRqzzG2cyCIbdViCLz+b0vATwSOsTqtK0lY1m9i+ +8v4S67z+S5+/klGovC1HAHH4TJOsOAAxqp6AAd9ufynCZNb6Y/9z7AnQcbBccC5X +hR8Eq/STrqM3pF1dpABIL67pwfZ7MqB0xCYkWICB5BgnHrCr29EcUOw7C6gKhFB3 +9A/YfG6D6Lzs/0cKdAbZclSinzxwyvQ8n8VnSQq9CYMYRPE9eLQDrl93IyJnXOuE +ez9abJv5DIjJsGayAEz4H7xYSm2Ao/Hr0Ap3P4zywG3QBZqX3OPYR6ojXMNagQZK +UYNQrvTOvymi1NiNLkWeaaSKS5oYBhyIRgQTEQIABgUCVS94hwAKCRArrjz22v+w +AD9EAJ0aapSfv7GwzKZeyG/9Ydpz7XrUmACeK3vmctUHKn4+gCDGYuGLyQSmwF20 +JkJqb2VybiBLaW1taW5pY2ggPGJqb2VybkBraW1taW5pY2guZGU+iQE5BBMBCAAj +BQJVEz1lAhsPBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQBiqFqMv73Nqi +ngf+N5Ft66CdvLl4J/oyf8BVDmlI1nvyr2s3zM7ZWGOCgawcB09uq8i9ZE2jZu3l +NHhKQdmYnrEEgKDhC3Rd1tj/MqSZ90/z22FczovarVTWvZ7oy0tMzfokcTfcbXsm +YRaFJT1/rUt9ThBg9SAAnO06BkbF1ZgZSxSG24Do7trpiv8aqId1i+cHE7UwhuP5 +8ArLij2+u1VpUnX0pzR4t2/JaIoYx6tuoIX+LnsUsohmkVo8gAvWOMDsA3zqxG6T +lQ0nVxQ7BMq0aeVmjvnamLvrSte8ByLnW9q65i0/nTxHqwVVnhTLHjXYKYQHYdd6 +K/4UoiKiWz9Ro/27bf2lHNpVeYhGBBMRAgAGBQJVL3iHAAoJECuuPPba/7AAfCoA +n2v7/Z30CB4bHpCqeYxiL12F34M2AJ4/mfN9uGYj91TYJ/cgFwI6LndxTrQmQmrD +tnJuIEtpbW1pbmljaCA8YmpvZXJuQGtpbW1pbmljaC5kZT6JATkEEwEIACMFAlUT +PVUCGw8HCwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgAAKCRAGKoWoy/vc2soDB/wJ +jmocZ3fYpwvJZy7lqknXkXBxJBKX1BBBz4sHXueJeBqdJ+yCbzhluSlWOzFO+1Cb +wr0uJ7UCzfB+wBQ6EsKOLJHZLlixBoj6/lTF2bQFceAI0w5coZWIeYUzRAmyguiY +YPpE3+hBPY47osVqIXle2QblKthVrI6FToTwAomOWRCX/oJCnJ+x3LJiHHj3HKfw +8Gy1BalosL2p2V4V1vr/6TbWsuj3L0nxmDEM7877VNiHw2jL6Jp+V9GzOeWvS7Pi +KnPXVLAp81A9SKhNiEEAlsGcWtz6Bm3WaT1D4fFwuEm2RdjP8kO3uoxtvhRzej/W +jHT4zomR6/h+C/nw0aTuiEYEExECAAYFAlUveIcACgkQK6489tr/sAB7twCfa396 +dnFYG4eGszFLs8JFO5Klcr8An2FBTcVIwOBEo3m294V2npnv1Z+utCpCam9lcm4g +S2ltbWluaWNoIDxiam9lcm4ua2ltbWluaWNoQGdteC5kZT6JATkEEwEIACMFAlUT +PUMCGw8HCwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgAAKCRAGKoWoy/vc2j/fB/9C +PAkZAj4M16AWbLONShxPkYyYnW+yJw6bIuYrcEsNzrYuxxQ3zmJ91Iztuh+HcCnr +8sWOP9iuWe2Q4EctAn2D1Yc8FhcIW51YAwnf66wuGozx7LJAfI53HRCpC5hkGxg5 +y1wVfJcu7Qf7BWfB4J3FLVMdX+4i/roFdGlFfzSI897M/c7HxIZfgnHRWUJaRWrE +x/uOCSbNocAS+vOw7VG2VueVR/i25G4bRr1G6Puts80jZgZojD8L2wxrfwOzBm83 +Mm2IR7EhQvPE61IUo35WJQUbS2uQF/rgY375Eb+Ca7tKKCPe00SCTTuZyiLwCWMo +PLZN3L+JUL85Kk6KTe/ziEYEExECAAYFAlUveIcACgkQK6489tr/sADXRgCeLro0 +0Lb0N8srIRPp53pBEaFMgzwAoIZD5aCEFLyD7+nmpP2nSFOMOLCJtCpCasO2cm4g +S2ltbWluaWNoIDxiam9lcm4ua2ltbWluaWNoQGdteC5kZT6JATkEEwEIACMFAlUT +PSkCGw8HCwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgAAKCRAGKoWoy/vc2lfyB/wO +NuFhITiHDcFeUFUT9CNkrC8zEvVL9+NpiEHHwgVJJrixuem6o8zLPiOK9OsYJwWD +dZeF/nDI0wRQA8bxHwfcIlFKGulldWtCA9SHIgM7LM7lE5S689HaXiEYz2k6y0AK +tR273lPBhYtIvZEkC/tZQ2Grf4rtPW/kI56pZy8Jb0Q99CvBHWneQ9vNS76eq5M3 +9ZDLdSv5FoxNUg7eN+NQ0gBefONgKXykKDT/b6FW12rI8j4OosQJxASpbiagEmCj +j8kmRHJ1vE3kP28xLvogoqP35SZj7FV57AhQPw5M7pKu9xeSMUPl8tmKHiyFh1tw +wY2udDziBjJDc8D3yCyuiEYEExECAAYFAlUveIcACgkQK6489tr/sABVZQCePO8U +X4TFo13F+WfoAk36fLF7Dc0AnRt7Fya08kPFKO3CQSXV4ZaW+S4utEFCasO2cm4g +S2ltbWluaWNoIChQcml2YXRlIEVtYWlsYWRyZXNzZSkgPGJqb2Vybi5raW1taW5p +Y2hAZ214LmRlPokBOQQTAQgAIwUCVRJ/lgIbDwcLCQgHAwIBBhUIAgkKCwQWAgMB +Ah4BAheAAAoJEAYqhajL+9zaavYH/2MNLalQnGL5bTMT+sVhhrtg9qebfWVhE600 +5KYEcXEA3DCXH7SnwKriNQtJCUi94iFPTz6jjGvDlyGaZbuntahB4ynrUhMR8mR/ +uhUxYkSwdV/KMwqEP4i/FJHFgVW/c0EYRBdG2+SJHx81GPFxRnxSsdxq6rjQpa5k +jm2/+uyJi/bF2uBFswOIAk0xHSpEmkbE2YP0wwW+OFV5VL8e2FGjw6KCxyRC6NQN +jxYPhlej2hCvWqqr9TGRx+E4ER8dfUynkbNXDdztP/6dMvx+eGZd7e/So/4g7/Or +pdKx80Uk04igTHJYSZsLN1k4L/h1gfuHsbjMrGVhWLnCC9vtwvaIRgQTEQIABgUC +VS94hwAKCRArrjz22v+wADU0AJ4uw0K5udWlv4ILDDnzRPt+lePbwwCfdIAAQf7U +yeaVcVlyFkulTYoBcwK0M0Jqb2VybiBLaW1taW5pY2ggPGJqb2Vybi5raW1taW5p +Y2hAbm9yZGFrYWRlbWllLmRlPokBOQQTAQgAIwUCVRM92AIbDwcLCQgHAwIBBhUI +AgkKCwQWAgMBAh4BAheAAAoJEAYqhajL+9zasF0H/3Vy4IouO8UEb8bamdyCbLeA +X6x2obdAZIiGmzxgZZ0WPGKbV/6sipYEAlAGGH+2wxXuDXzfjizsY+u9OKsZklw1 +7PlgIW/dkiJuK73SaJwRMUgeq4bhltToaaonIt433ie9srHw+UDyc+M+da89Nv1i +9J5vXVrMU5UCc/Wpy4JZZBJmwAnANUsBvhL/nB0qS9awsl+4bvM+NGZTCscYLfCs +iXaP7j2jI+wHtN16Q1HL98eN/cOXz/e6JX1+Oy6A3QSxU3ku3STEb2wAyJPkx1no +NMBUASYyjLQDEmfC2IRzlRdnHuL5cywzOsDeCNynDQr/RHMKnI+UschHly1Ebi2I +RgQTEQIABgUCVS94hwAKCRArrjz22v+wAKoGAJ4rqhHeTrtZL6xHQKBBwg7Ns3eI +1gCfSZuaBCqxOvuCKUJzqBdmGtBPs/Q= +=z48d +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/app.json b/app.json index cd05a4b8..bc43d77f 100644 --- a/app.json +++ b/app.json @@ -1,23 +1,23 @@ -{ - "name": "OWASP Juice Shop", - "description": "Probably the most modern and sophisticated insecure web application", - "keywords": [ - "web security", - "web application security", - "webappsec", - "owasp", - "pentest", - "pentesting", - "security", - "vulnerable", - "vulnerability", - "broken", - "bodgeit", - "ctf", - "capture the flag", - "awareness" - ], - "website": "https://owasp-juice.shop", - "repository": "https://github.com/juice-shop/juice-shop", - "logo": "https://raw.githubusercontent.com/juice-shop/juice-shop/master/frontend/src/assets/public/images/JuiceShop_Logo.png" -} +{ + "name": "OWASP Juice Shop", + "description": "Probably the most modern and sophisticated insecure web application", + "keywords": [ + "web security", + "web application security", + "webappsec", + "owasp", + "pentest", + "pentesting", + "security", + "vulnerable", + "vulnerability", + "broken", + "bodgeit", + "ctf", + "capture the flag", + "awareness" + ], + "website": "https://owasp-juice.shop", + "repository": "https://github.com/juice-shop/juice-shop", + "logo": "https://raw.githubusercontent.com/juice-shop/juice-shop/master/frontend/src/assets/public/images/JuiceShop_Logo.png" +} diff --git a/app.ts b/app.ts index 0e08d790..aa591326 100644 --- a/app.ts +++ b/app.ts @@ -1,17 +1,17 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -async function app () { - const { default: validateDependencies } = await import('./lib/startup/validateDependenciesBasic') - await validateDependencies() - - const server = await import('./server') - await server.start() -} - -app() - .catch(err => { - throw err - }) +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +async function app () { + const { default: validateDependencies } = await import('./lib/startup/validateDependenciesBasic') + await validateDependencies() + + const server = await import('./server') + await server.start() +} + +app() + .catch(err => { + throw err + }) diff --git a/config.schema.yml b/config.schema.yml index 98940406..508a5c22 100644 --- a/config.schema.yml +++ b/config.schema.yml @@ -1,725 +1,725 @@ -server: - port: - type: number - basePath: - type: string - baseUrl: - type: string -application: - domain: - type: string - name: - type: string - logo: - type: string - favicon: - type: string - theme: - type: string - showVersionNumber: - type: boolean - showGitHubLinks: - type: boolean - localBackupEnabled: - type: boolean - numberOfRandomFakeUsers: - type: number - altcoinName: - type: string - privacyContactEmail: - type: string - customMetricsPrefix: - type: string - chatBot: - name: - type: string - greeting: - type: string - trainingData: - type: string - defaultResponse: - type: string - avatar: - type: string - social: - twitterUrl: - type: string - facebookUrl: - type: string - slackUrl: - type: string - redditUrl: - type: string - pressKitUrl: - type: string - nftUrl: - type: string - questionnaireUrl: - type: string - recyclePage: - topProductImage: - type: string - bottomProductImage: - type: string - welcomeBanner: - showOnFirstStart: - type: boolean - title: - type: string - message: - type: string - cookieConsent: - message: - type: string - dismissText: - type: string - linkText: - type: string - linkUrl: - type: string - securityTxt: - contact: - type: string - encryption: - type: string - acknowledgements: - type: string - hiring: - type: string - csaf: - type: string - promotion: - video: - type: string - subtitles: - type: string - easterEggPlanet: - name: - type: string - overlayMap: - type: string - googleOauth: - clientId: - type: string - authorizedRedirects: - - uri: - type: string - proxy: - type: string -challenges: - showSolvedNotifications: - type: boolean - showHints: - type: boolean - showMitigations: - type: boolean - codingChallengesEnabled: - type: string - restrictToTutorialsFirst: - type: boolean - overwriteUrlForProductTamperingChallenge: - type: string - xssBonusPayload: - type: string - safetyMode: - type: string - enum: ['enabled', 'disabled','auto'] - showFeedbackButtons: - type: boolean - csafHashValue: - type: string -hackingInstructor: - isEnabled: - type: boolean - avatarImage: - type: string - hintPlaybackSpeed: - type: string -products: - - name: - type: string - price: - type: number - deluxePrice: - type: number - description: - type: string - image: - type: string - quantity: - type: number - limitPerUser: - type: number - deletedDate: - type: string - urlForProductTamperingChallenge: - type: string - useForChristmasSpecialChallenge: - type: boolean - keywordsForPastebinDataLeakChallenge: - - type: string - fileForRetrieveBlueprintChallenge: - type: string - exifForBlueprintChallenge: - - type: string - reviews: - - text: - type: string - author: - type: string -memories: - - image: - type: string - caption: - type: string - user: - type: string - geoStalkingMetaSecurityQuestion: - type: number - geoStalkingMetaSecurityAnswer: - type: string - geoStalkingVisualSecurityQuestion: - type: number - geoStalkingVisualSecurityAnswer: - type: string -ctf: - showFlagsInNotifications: - type: boolean - showCountryDetailsInNotifications: - type: string - countryMapping: - scoreBoardChallenge: - name: - type: string - code: - type: string - errorHandlingChallenge: - name: - type: string - code: - type: string - forgedReviewChallenge: - name: - type: string - code: - type: string - loginAdminChallenge: - name: - type: string - code: - type: string - loginJimChallenge: - name: - type: string - code: - type: string - loginBenderChallenge: - name: - type: string - code: - type: string - localXssChallenge: - name: - type: string - code: - type: string - reflectedXssChallenge: - name: - type: string - code: - type: string - persistedXssUserChallenge: - name: - type: string - code: - type: string - persistedXssFeedbackChallenge: - name: - type: string - code: - type: string - restfulXssChallenge: - name: - type: string - code: - type: string - unionSqlInjectionChallenge: - name: - type: string - code: - type: string - weakPasswordChallenge: - name: - type: string - code: - type: string - feedbackChallenge: - name: - type: string - code: - type: string - forgedFeedbackChallenge: - name: - type: string - code: - type: string - redirectCryptoCurrencyChallenge: - name: - type: string - code: - type: string - redirectChallenge: - name: - type: string - code: - type: string - basketAccessChallenge: - name: - type: string - code: - type: string - negativeOrderChallenge: - name: - type: string - code: - type: string - directoryListingChallenge: - name: - type: string - code: - type: string - forgottenDevBackupChallenge: - name: - type: string - code: - type: string - forgottenBackupChallenge: - name: - type: string - code: - type: string - adminSectionChallenge: - name: - type: string - code: - type: string - changePasswordBenderChallenge: - name: - type: string - code: - type: string - changeProductChallenge: - name: - type: string - code: - type: string - knownVulnerableComponentChallenge: - name: - type: string - code: - type: string - weirdCryptoChallenge: - name: - type: string - code: - type: string - easterEggLevelOneChallenge: - name: - type: string - code: - type: string - easterEggLevelTwoChallenge: - name: - type: string - code: - type: string - forgedCouponChallenge: - name: - type: string - code: - type: string - christmasSpecialChallenge: - name: - type: string - code: - type: string - uploadSizeChallenge: - name: - type: string - code: - type: string - uploadTypeChallenge: - name: - type: string - code: - type: string - fileWriteChallenge: - name: - type: string - code: - type: string - extraLanguageChallenge: - name: - type: string - code: - type: string - captchaBypassChallenge: - name: - type: string - code: - type: string - zeroStarsChallenge: - name: - type: string - code: - type: string - continueCodeChallenge: - name: - type: string - code: - type: string - oauthUserPasswordChallenge: - name: - type: string - code: - type: string - loginSupportChallenge: - name: - type: string - code: - type: string - loginRapperChallenge: - name: - type: string - code: - type: string - premiumPaywallChallenge: - name: - type: string - code: - type: string - resetPasswordJimChallenge: - name: - type: string - code: - type: string - resetPasswordBenderChallenge: - name: - type: string - code: - type: string - resetPasswordMortyChallenge: - name: - type: string - code: - type: string - resetPasswordUvoginChallenge: - name: - type: string - code: - type: string - resetPasswordBjoernChallenge: - name: - type: string - code: - type: string - noSqlCommandChallenge: - name: - type: string - code: - type: string - noSqlReviewsChallenge: - name: - type: string - code: - type: string - noSqlOrdersChallenge: - name: - type: string - code: - type: string - retrieveBlueprintChallenge: - name: - type: string - code: - type: string - typosquattingNpmChallenge: - name: - type: string - code: - type: string - typosquattingAngularChallenge: - name: - type: string - code: - type: string - jwtUnsignedChallenge: - name: - type: string - code: - type: string - jwtForgedChallenge: - name: - type: string - code: - type: string - misplacedSignatureFileChallenge: - name: - type: string - code: - type: string - deprecatedInterfaceChallenge: - name: - type: string - code: - type: string - xxeFileDisclosureChallenge: - name: - type: string - code: - type: string - xxeDosChallenge: - name: - type: string - code: - type: string - rceChallenge: - name: - type: string - code: - type: string - rceOccupyChallenge: - name: - type: string - code: - type: string - tokenSaleChallenge: - name: - type: string - code: - type: string - nftUnlockChallenge: - name: - type: string - code: - type: string - nftMintChallenge: - name: - type: string - code: - type: string - web3WalletChallenge: - name: - type: string - code: - type: string - web3SandboxChallenge: - name: - type: string - code: - type: string - securityPolicyChallenge: - name: - type: string - code: - type: string - hiddenImageChallenge: - name: - type: string - code: - type: string - supplyChainAttackChallenge: - name: - type: string - code: - type: string - timingAttackChallenge: - name: - type: string - code: - type: string - basketManipulateChallenge: - name: - type: string - code: - type: string - emailLeakChallenge: - name: - type: string - code: - type: string - registerAdminChallenge: - name: - type: string - code: - type: string - httpHeaderXssChallenge: - name: - type: string - code: - type: string - sstiChallenge: - name: - type: string - code: - type: string - ssrfChallenge: - name: - type: string - code: - type: string - loginAmyChallenge: - name: - type: string - code: - type: string - usernameXssChallenge: - name: - type: string - code: - type: string - resetPasswordBjoernOwaspChallenge: - name: - type: string - code: - type: string - accessLogDisclosureChallenge: - name: - type: string - code: - type: string - dlpPasswordSprayingChallenge: - name: - type: string - code: - type: string - dlpPastebinDataLeakChallenge: - name: - type: string - code: - type: string - videoXssChallenge: - name: - type: string - code: - type: string - twoFactorAuthUnsafeSecretStorageChallenge: - name: - type: string - code: - type: string - manipulateClockChallenge: - name: - type: string - code: - type: string - privacyPolicyChallenge: - name: - type: string - code: - type: string - privacyPolicyProofChallenge: - name: - type: string - code: - type: string - passwordRepeatChallenge: - name: - type: string - code: - type: string - dataExportChallenge: - name: - type: string - code: - type: string - ghostLoginChallenge: - name: - type: string - code: - type: string - dbSchemaChallenge: - name: - type: string - code: - type: string - ephemeralAccountantChallenge: - name: - type: string - code: - type: string - missingEncodingChallenge: - name: - type: string - code: - type: string - svgInjectionChallenge: - name: - type: string - code: - type: string - exposedMetricsChallenge: - name: - type: string - code: - type: string - freeDeluxeChallenge: - name: - type: string - code: - type: string - csrfChallenge: - name: - type: string - code: - type: string - xssBonusChallenge: - name: - type: string - code: - type: string - geoStalkingMetaChallenge: - name: - type: string - code: - type: string - geoStalkingVisualChallenge: - name: - type: string - code: - type: string - killChatbotChallenge: - name: - type: string - code: - type: string - nullByteChallenge: - name: - type: string - code: - type: string - bullyChatbotChallenge: - name: - type: string - code: - type: string - lfrChallenge: - name: - type: string - code: - type: string - closeNotificationsChallenge: - name: - type: string - code: - type: string - emptyUserRegistration: - name: - type: string - code: - type: string - csafChallenge: - name: - type: string - code: - type: string +server: + port: + type: number + basePath: + type: string + baseUrl: + type: string +application: + domain: + type: string + name: + type: string + logo: + type: string + favicon: + type: string + theme: + type: string + showVersionNumber: + type: boolean + showGitHubLinks: + type: boolean + localBackupEnabled: + type: boolean + numberOfRandomFakeUsers: + type: number + altcoinName: + type: string + privacyContactEmail: + type: string + customMetricsPrefix: + type: string + chatBot: + name: + type: string + greeting: + type: string + trainingData: + type: string + defaultResponse: + type: string + avatar: + type: string + social: + twitterUrl: + type: string + facebookUrl: + type: string + slackUrl: + type: string + redditUrl: + type: string + pressKitUrl: + type: string + nftUrl: + type: string + questionnaireUrl: + type: string + recyclePage: + topProductImage: + type: string + bottomProductImage: + type: string + welcomeBanner: + showOnFirstStart: + type: boolean + title: + type: string + message: + type: string + cookieConsent: + message: + type: string + dismissText: + type: string + linkText: + type: string + linkUrl: + type: string + securityTxt: + contact: + type: string + encryption: + type: string + acknowledgements: + type: string + hiring: + type: string + csaf: + type: string + promotion: + video: + type: string + subtitles: + type: string + easterEggPlanet: + name: + type: string + overlayMap: + type: string + googleOauth: + clientId: + type: string + authorizedRedirects: + - uri: + type: string + proxy: + type: string +challenges: + showSolvedNotifications: + type: boolean + showHints: + type: boolean + showMitigations: + type: boolean + codingChallengesEnabled: + type: string + restrictToTutorialsFirst: + type: boolean + overwriteUrlForProductTamperingChallenge: + type: string + xssBonusPayload: + type: string + safetyMode: + type: string + enum: ['enabled', 'disabled','auto'] + showFeedbackButtons: + type: boolean + csafHashValue: + type: string +hackingInstructor: + isEnabled: + type: boolean + avatarImage: + type: string + hintPlaybackSpeed: + type: string +products: + - name: + type: string + price: + type: number + deluxePrice: + type: number + description: + type: string + image: + type: string + quantity: + type: number + limitPerUser: + type: number + deletedDate: + type: string + urlForProductTamperingChallenge: + type: string + useForChristmasSpecialChallenge: + type: boolean + keywordsForPastebinDataLeakChallenge: + - type: string + fileForRetrieveBlueprintChallenge: + type: string + exifForBlueprintChallenge: + - type: string + reviews: + - text: + type: string + author: + type: string +memories: + - image: + type: string + caption: + type: string + user: + type: string + geoStalkingMetaSecurityQuestion: + type: number + geoStalkingMetaSecurityAnswer: + type: string + geoStalkingVisualSecurityQuestion: + type: number + geoStalkingVisualSecurityAnswer: + type: string +ctf: + showFlagsInNotifications: + type: boolean + showCountryDetailsInNotifications: + type: string + countryMapping: + scoreBoardChallenge: + name: + type: string + code: + type: string + errorHandlingChallenge: + name: + type: string + code: + type: string + forgedReviewChallenge: + name: + type: string + code: + type: string + loginAdminChallenge: + name: + type: string + code: + type: string + loginJimChallenge: + name: + type: string + code: + type: string + loginBenderChallenge: + name: + type: string + code: + type: string + localXssChallenge: + name: + type: string + code: + type: string + reflectedXssChallenge: + name: + type: string + code: + type: string + persistedXssUserChallenge: + name: + type: string + code: + type: string + persistedXssFeedbackChallenge: + name: + type: string + code: + type: string + restfulXssChallenge: + name: + type: string + code: + type: string + unionSqlInjectionChallenge: + name: + type: string + code: + type: string + weakPasswordChallenge: + name: + type: string + code: + type: string + feedbackChallenge: + name: + type: string + code: + type: string + forgedFeedbackChallenge: + name: + type: string + code: + type: string + redirectCryptoCurrencyChallenge: + name: + type: string + code: + type: string + redirectChallenge: + name: + type: string + code: + type: string + basketAccessChallenge: + name: + type: string + code: + type: string + negativeOrderChallenge: + name: + type: string + code: + type: string + directoryListingChallenge: + name: + type: string + code: + type: string + forgottenDevBackupChallenge: + name: + type: string + code: + type: string + forgottenBackupChallenge: + name: + type: string + code: + type: string + adminSectionChallenge: + name: + type: string + code: + type: string + changePasswordBenderChallenge: + name: + type: string + code: + type: string + changeProductChallenge: + name: + type: string + code: + type: string + knownVulnerableComponentChallenge: + name: + type: string + code: + type: string + weirdCryptoChallenge: + name: + type: string + code: + type: string + easterEggLevelOneChallenge: + name: + type: string + code: + type: string + easterEggLevelTwoChallenge: + name: + type: string + code: + type: string + forgedCouponChallenge: + name: + type: string + code: + type: string + christmasSpecialChallenge: + name: + type: string + code: + type: string + uploadSizeChallenge: + name: + type: string + code: + type: string + uploadTypeChallenge: + name: + type: string + code: + type: string + fileWriteChallenge: + name: + type: string + code: + type: string + extraLanguageChallenge: + name: + type: string + code: + type: string + captchaBypassChallenge: + name: + type: string + code: + type: string + zeroStarsChallenge: + name: + type: string + code: + type: string + continueCodeChallenge: + name: + type: string + code: + type: string + oauthUserPasswordChallenge: + name: + type: string + code: + type: string + loginSupportChallenge: + name: + type: string + code: + type: string + loginRapperChallenge: + name: + type: string + code: + type: string + premiumPaywallChallenge: + name: + type: string + code: + type: string + resetPasswordJimChallenge: + name: + type: string + code: + type: string + resetPasswordBenderChallenge: + name: + type: string + code: + type: string + resetPasswordMortyChallenge: + name: + type: string + code: + type: string + resetPasswordUvoginChallenge: + name: + type: string + code: + type: string + resetPasswordBjoernChallenge: + name: + type: string + code: + type: string + noSqlCommandChallenge: + name: + type: string + code: + type: string + noSqlReviewsChallenge: + name: + type: string + code: + type: string + noSqlOrdersChallenge: + name: + type: string + code: + type: string + retrieveBlueprintChallenge: + name: + type: string + code: + type: string + typosquattingNpmChallenge: + name: + type: string + code: + type: string + typosquattingAngularChallenge: + name: + type: string + code: + type: string + jwtUnsignedChallenge: + name: + type: string + code: + type: string + jwtForgedChallenge: + name: + type: string + code: + type: string + misplacedSignatureFileChallenge: + name: + type: string + code: + type: string + deprecatedInterfaceChallenge: + name: + type: string + code: + type: string + xxeFileDisclosureChallenge: + name: + type: string + code: + type: string + xxeDosChallenge: + name: + type: string + code: + type: string + rceChallenge: + name: + type: string + code: + type: string + rceOccupyChallenge: + name: + type: string + code: + type: string + tokenSaleChallenge: + name: + type: string + code: + type: string + nftUnlockChallenge: + name: + type: string + code: + type: string + nftMintChallenge: + name: + type: string + code: + type: string + web3WalletChallenge: + name: + type: string + code: + type: string + web3SandboxChallenge: + name: + type: string + code: + type: string + securityPolicyChallenge: + name: + type: string + code: + type: string + hiddenImageChallenge: + name: + type: string + code: + type: string + supplyChainAttackChallenge: + name: + type: string + code: + type: string + timingAttackChallenge: + name: + type: string + code: + type: string + basketManipulateChallenge: + name: + type: string + code: + type: string + emailLeakChallenge: + name: + type: string + code: + type: string + registerAdminChallenge: + name: + type: string + code: + type: string + httpHeaderXssChallenge: + name: + type: string + code: + type: string + sstiChallenge: + name: + type: string + code: + type: string + ssrfChallenge: + name: + type: string + code: + type: string + loginAmyChallenge: + name: + type: string + code: + type: string + usernameXssChallenge: + name: + type: string + code: + type: string + resetPasswordBjoernOwaspChallenge: + name: + type: string + code: + type: string + accessLogDisclosureChallenge: + name: + type: string + code: + type: string + dlpPasswordSprayingChallenge: + name: + type: string + code: + type: string + dlpPastebinDataLeakChallenge: + name: + type: string + code: + type: string + videoXssChallenge: + name: + type: string + code: + type: string + twoFactorAuthUnsafeSecretStorageChallenge: + name: + type: string + code: + type: string + manipulateClockChallenge: + name: + type: string + code: + type: string + privacyPolicyChallenge: + name: + type: string + code: + type: string + privacyPolicyProofChallenge: + name: + type: string + code: + type: string + passwordRepeatChallenge: + name: + type: string + code: + type: string + dataExportChallenge: + name: + type: string + code: + type: string + ghostLoginChallenge: + name: + type: string + code: + type: string + dbSchemaChallenge: + name: + type: string + code: + type: string + ephemeralAccountantChallenge: + name: + type: string + code: + type: string + missingEncodingChallenge: + name: + type: string + code: + type: string + svgInjectionChallenge: + name: + type: string + code: + type: string + exposedMetricsChallenge: + name: + type: string + code: + type: string + freeDeluxeChallenge: + name: + type: string + code: + type: string + csrfChallenge: + name: + type: string + code: + type: string + xssBonusChallenge: + name: + type: string + code: + type: string + geoStalkingMetaChallenge: + name: + type: string + code: + type: string + geoStalkingVisualChallenge: + name: + type: string + code: + type: string + killChatbotChallenge: + name: + type: string + code: + type: string + nullByteChallenge: + name: + type: string + code: + type: string + bullyChatbotChallenge: + name: + type: string + code: + type: string + lfrChallenge: + name: + type: string + code: + type: string + closeNotificationsChallenge: + name: + type: string + code: + type: string + emptyUserRegistration: + name: + type: string + code: + type: string + csafChallenge: + name: + type: string + code: + type: string diff --git a/config/7ms.yml b/config/7ms.yml index 2d770c34..1e3100a0 100644 --- a/config/7ms.yml +++ b/config/7ms.yml @@ -1,152 +1,152 @@ -application: - domain: 7-ms.us - name: '7 Minute Security' - logo: 'https://static1.squarespace.com/static/59f9e1c4d0e6281017434039/t/59fd39cde31d1945635d5fbb/1530161239161/7.png' - favicon: 'https://7minsec.com/favicon.ico' - theme: blue-lightblue - showGitHubLinks: true - altcoinName: Sevencoin - privacyContactEmail: 'donotreply@7-ms.us' - customMetricsPrefix: sevenminsec - chatBot: - name: 'Brian' - greeting: "Hi , it's me, your friend and pal !" - trainingData: 'https://gist.githubusercontent.com/bkimminich/d62bd52a1df4831a0fae7fb06062e3f0/raw/59dadc1e0ab1b5cb9264e85bc78736aaa3f0eb6b/bot7msTrainingData.json' - defaultResponse: "Sorry, but \"no comprende\"!" - avatar: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/94c89793-630d-41a4-9976-91fef527f8d0/BrianJohnson-headshot-2022-2-small.png?format=500w' - social: - twitterUrl: 'https://twitter.com/7MinSec' - facebookUrl: null - slackUrl: 'https://7ms.us/slack' - redditUrl: null - pressKitUrl: null - nftUrl: null - questionnaireUrl: null - recyclePage: - topProductImage: bm-small.jpg - bottomProductImage: tommyboy.jpeg - welcomeBanner: - showOnFirstStart: false - cookieConsent: - message: 'If you stay on this website for more than 7 minutes our cookies will start tracking you.' - dismissText: 'I`ll be long gone by then!' - linkText: 'But I want to stay an arbitrary number of minutes!' - linkUrl: 'https://7ms.us/7ms-294-gdpr-me-asap/' - securityTxt: - contact: 'mailto:donotreply@7-ms.us' - encryption: ~ - easterEggPlanet: - name: 'Mad Billy-7' - overlayMap: 'https://static1.squarespace.com/static/59505bc2414fb538a0532c76/t/599e266aebbd1a759716569b/1503536748248/logo+2.png' -challenges: - xssBonusPayload: '' -hackingInstructor: - avatarImage: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/94c89793-630d-41a4-9976-91fef527f8d0/BrianJohnson-headshot-2022-2-small.png?format=500w' -products: - - - name: 'Security Assessment' - price: 1999.99 - description: 'Rather than just pointing out the gaps in your administrative, physical and technical controls, 7 Minute Security will partner with you to help formulate - and execute - a measurable remediation plan.' - image: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/1618506026604-MMMHZED4KRAPGNEBL50V/website_photos_securityassessments01.jpg?format=750w' - - - name: 'Penetration Test' - description: '"Can the bad guys get in?" An internal and/or external network penetration test will gauge your organization`s defenses and help answer that question. After the test, 7 Minute Security will work with you on the technical defenses you need to put in place.' - price: 1899.99 - image: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/1618506146888-XHHF0XYUR6D3YK46F3OJ/website_photos_pentesting01.jpg?format=750w' - - - name: Training - description: '7 Minute Security can train your employees to not only be more secure at work, but carry that security-focused attitude into everything they do at home as well. More tech-heavy sessions are available as well, such as Penetration Testing 101 and Intro to Windows System Forensics.' - price: 899.99 - image: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/1618506195524-DNXS4OW3C65ZVKX7O3QQ/website_photos_training.jpg?format=750w' - reviews: - - { text: 'Wow, that lady can fingerpoint IPs like a pro!', author: bender } - - - name: 'Billy Madison 1.1' - description: 'Billy Madison is a vulnerable virtual machine, hosted by Vulnhub. To successfully pwn the box, pentesters must undo modifications to the system and recover Billy’s 12th grade project. Otherwise Eric and his weasel laugh will take over Madison Hotels!' - price: 999.99 - image: 'https://static1.squarespace.com/static/59f9e1c4d0e6281017434039/t/5a01bef9c83025f467396e34/1510063870501/bm-small.jpg' - urlForProductTamperingChallenge: 'https://www.vulnhub.com/entry/billy-madison-11,161/' - - - name: 'Billy Madison 1.0' - description: 'Christmas Special Re-Release Edition of the famous VulnHub VM! Rare collectors item! Available only Christmas 2014!' - price: 12999.99 - image: bm-small.jpg - useForChristmasSpecialChallenge: true - - - name: 'Tommy Boy 1.0' - description: 'Tommy Boy is a vulnerable virtual machine, hosted by VulnHub and based one of my all-time favorite movies. To complete the CTF, pentesters must bring the Callahan Auto brakepad ordering system back online before the company goes out of business.' - price: 799.99 - image: 'https://static1.squarespace.com/static/59f9e1c4d0e6281017434039/t/5a01bfaa71c10b9d51d59d2e/1510081203010/tommyboy.jpeg' - - - name: 'CryptoLocker`d (Audio CD)' - description: 'A few years ago a worked on an incident response where a user got phished with a promise of a free burrito from Chipotle but instead got a free order of CryptoLocker! And rather than tell IT or sound the alarms, the user just left for the day! The next day they came back and the company was digitally on fire, and they played ignorant to what was going on. I found the user`s handling of the situation humorous (read: not the CryptoLocker infection itself!), so I was inspired to write a song about it.' - price: 19.99 - image: 'https://pbs.twimg.com/media/Dc3BuBPXUAAswae.jpg' - fileForRetrieveBlueprintChallenge: The+CryptoLocker+Song.mps - exifForBlueprintChallenge: - - ~ - - - name: 'Sweet Surrender (Limited Edition Best of Audio CD)' - description: 'Sweet Surrender is a vocals-driven acoustic duo from the Twin Cities area. Our music reflects a diverse range of our musical tastes - from the most current pop and country tunes on the radio today, to some great older tunes done with a twist. We also love to share music that reflects our love for Christ through the most current, contemporary Christian music.' - price: 29.99 - image: 'https://static1.squarespace.com/static/59208d27c534a58e9b17ec06/t/59208d69197aea2df1397c7b/1505596635447.png' - keywordsForPastebinDataLeakChallenge: - - taylor swift - - katy perry - - - name: '7MSagotchi' - description: 'This cute little rascal is called a Pwnagotchi. It can look around like a champion!' - price: 40 - image: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/1587693073228-8GDKF12U0LBBKO5XEPFA/image-asset.jpeg?format=2500w' - reviews: - - { text: 'FlipperZero FTW!', author: bjoern } - - { text: 'As you mentioned FlipperZero: @Brian, did you get one by now? Any chance we get this RTTTL version of the amazing JS jingle going? See https://github.com/juice-shop/pwning-juice-shop/issues/105 - Cheers!', author: bjoernOwasp } - - - name: '7MS #230: Pentesting OWASP Juice Shop - Part 1' - description: 'Today we`re kicking of a multipart series all about hacking the OWASP Juice Shop which is "an intentionally insecure webapp for security trainings written entirely in Javascript which encompasses the entire OWASP Top Ten and other severe security flaws."' - price: 1.99 - image: 'https://i.ytimg.com/vi/IC6m249zvI0/hqdefault.jpg' - - - name: '7MS #231: Pentesting OWASP Juice Shop - Part 2' - description: 'Today we`re continuing our series on hacking apart the OWASP Juice Shop which is "an intentionally insecure webapp for security trainings written entirely in Javascript which encompasses the entire OWASP Top Ten and other severe security flaws."' - price: 1.99 - image: hqdefault.jpg - - - name: '7MS #232: Pentesting OWASP Juice Shop - Part 3' - description: 'Today is part three of our continuing series on attacking the OWASP Juice Shop which is "an intentionally insecure webapp for security trainings written entirely in Javascript which encompasses the entire OWASP Top Ten and other severe security flaws."' - price: 1.99 - image: hqdefault.jpg - - - name: '7MS #233: Pentesting OWASP Juice Shop - Part 4' - description: 'Today is part FOUR of our continuing series on attacking the OWASP Juice Shop which is "an intentionally insecure webapp for security trainings written entirely in Javascript which encompasses the entire OWASP Top Ten and other severe security flaws."' - price: 1.99 - image: hqdefault.jpg - - - name: '7MS #234: Pentesting OWASP Juice Shop - Part 5' - description: 'Today is part FIVE (insert menacing voice: "the final chapter!!!) of our series on attacking the OWASP Juice Shop which is "an intentionally insecure webapp for security trainings written entirely in Javascript which encompasses the entire OWASP Top Ten and other severe security flaws."' - price: 1.99 - image: hqdefault.jpg - - - name: '7MS #606: Hacking OWASP Juice Shop (2024 edition)' - description: "Join OWASP's Bjorn Kimminich and Paul Wilch from Project7 as we hack away at what is probably the most modern and sophisticated insecure Web application ever made: Juice Shop!" - price: 1.99 - image: hqdefault.jpg -memories: - - - image: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/1587695798282-PYCQEJEVJS1OF5FJY07A/pw.JPG?format=750w' - caption: 'There goes our ISO 27001 cert... "Thanks", Chris! :-(' - user: ciso - - - image: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/1569207865247-XHRW3XQ0XVKNEG46L579/usergroup.jpg?format=2500w' - caption: 'Last meeting of our user group pre-covid...' - user: stan - - - image: 'favorite-hiking-place.png' - caption: 'I love going hiking here...' - geoStalkingMetaSecurityQuestion: 14 - geoStalkingMetaSecurityAnswer: 'Daniel Boone National Forest' - - - image: 'IMG_4253.jpg' - caption: 'My old workplace...' - geoStalkingVisualSecurityQuestion: 10 - geoStalkingVisualSecurityAnswer: 'ITsec' +application: + domain: 7-ms.us + name: '7 Minute Security' + logo: 'https://static1.squarespace.com/static/59f9e1c4d0e6281017434039/t/59fd39cde31d1945635d5fbb/1530161239161/7.png' + favicon: 'https://7minsec.com/favicon.ico' + theme: blue-lightblue + showGitHubLinks: true + altcoinName: Sevencoin + privacyContactEmail: 'donotreply@7-ms.us' + customMetricsPrefix: sevenminsec + chatBot: + name: 'Brian' + greeting: "Hi , it's me, your friend and pal !" + trainingData: 'https://gist.githubusercontent.com/bkimminich/d62bd52a1df4831a0fae7fb06062e3f0/raw/59dadc1e0ab1b5cb9264e85bc78736aaa3f0eb6b/bot7msTrainingData.json' + defaultResponse: "Sorry, but \"no comprende\"!" + avatar: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/94c89793-630d-41a4-9976-91fef527f8d0/BrianJohnson-headshot-2022-2-small.png?format=500w' + social: + twitterUrl: 'https://twitter.com/7MinSec' + facebookUrl: null + slackUrl: 'https://7ms.us/slack' + redditUrl: null + pressKitUrl: null + nftUrl: null + questionnaireUrl: null + recyclePage: + topProductImage: bm-small.jpg + bottomProductImage: tommyboy.jpeg + welcomeBanner: + showOnFirstStart: false + cookieConsent: + message: 'If you stay on this website for more than 7 minutes our cookies will start tracking you.' + dismissText: 'I`ll be long gone by then!' + linkText: 'But I want to stay an arbitrary number of minutes!' + linkUrl: 'https://7ms.us/7ms-294-gdpr-me-asap/' + securityTxt: + contact: 'mailto:donotreply@7-ms.us' + encryption: ~ + easterEggPlanet: + name: 'Mad Billy-7' + overlayMap: 'https://static1.squarespace.com/static/59505bc2414fb538a0532c76/t/599e266aebbd1a759716569b/1503536748248/logo+2.png' +challenges: + xssBonusPayload: '' +hackingInstructor: + avatarImage: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/94c89793-630d-41a4-9976-91fef527f8d0/BrianJohnson-headshot-2022-2-small.png?format=500w' +products: + - + name: 'Security Assessment' + price: 1999.99 + description: 'Rather than just pointing out the gaps in your administrative, physical and technical controls, 7 Minute Security will partner with you to help formulate - and execute - a measurable remediation plan.' + image: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/1618506026604-MMMHZED4KRAPGNEBL50V/website_photos_securityassessments01.jpg?format=750w' + - + name: 'Penetration Test' + description: '"Can the bad guys get in?" An internal and/or external network penetration test will gauge your organization`s defenses and help answer that question. After the test, 7 Minute Security will work with you on the technical defenses you need to put in place.' + price: 1899.99 + image: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/1618506146888-XHHF0XYUR6D3YK46F3OJ/website_photos_pentesting01.jpg?format=750w' + - + name: Training + description: '7 Minute Security can train your employees to not only be more secure at work, but carry that security-focused attitude into everything they do at home as well. More tech-heavy sessions are available as well, such as Penetration Testing 101 and Intro to Windows System Forensics.' + price: 899.99 + image: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/1618506195524-DNXS4OW3C65ZVKX7O3QQ/website_photos_training.jpg?format=750w' + reviews: + - { text: 'Wow, that lady can fingerpoint IPs like a pro!', author: bender } + - + name: 'Billy Madison 1.1' + description: 'Billy Madison is a vulnerable virtual machine, hosted by Vulnhub. To successfully pwn the box, pentesters must undo modifications to the system and recover Billy’s 12th grade project. Otherwise Eric and his weasel laugh will take over Madison Hotels!' + price: 999.99 + image: 'https://static1.squarespace.com/static/59f9e1c4d0e6281017434039/t/5a01bef9c83025f467396e34/1510063870501/bm-small.jpg' + urlForProductTamperingChallenge: 'https://www.vulnhub.com/entry/billy-madison-11,161/' + - + name: 'Billy Madison 1.0' + description: 'Christmas Special Re-Release Edition of the famous VulnHub VM! Rare collectors item! Available only Christmas 2014!' + price: 12999.99 + image: bm-small.jpg + useForChristmasSpecialChallenge: true + - + name: 'Tommy Boy 1.0' + description: 'Tommy Boy is a vulnerable virtual machine, hosted by VulnHub and based one of my all-time favorite movies. To complete the CTF, pentesters must bring the Callahan Auto brakepad ordering system back online before the company goes out of business.' + price: 799.99 + image: 'https://static1.squarespace.com/static/59f9e1c4d0e6281017434039/t/5a01bfaa71c10b9d51d59d2e/1510081203010/tommyboy.jpeg' + - + name: 'CryptoLocker`d (Audio CD)' + description: 'A few years ago a worked on an incident response where a user got phished with a promise of a free burrito from Chipotle but instead got a free order of CryptoLocker! And rather than tell IT or sound the alarms, the user just left for the day! The next day they came back and the company was digitally on fire, and they played ignorant to what was going on. I found the user`s handling of the situation humorous (read: not the CryptoLocker infection itself!), so I was inspired to write a song about it.' + price: 19.99 + image: 'https://pbs.twimg.com/media/Dc3BuBPXUAAswae.jpg' + fileForRetrieveBlueprintChallenge: The+CryptoLocker+Song.mps + exifForBlueprintChallenge: + - ~ + - + name: 'Sweet Surrender (Limited Edition Best of Audio CD)' + description: 'Sweet Surrender is a vocals-driven acoustic duo from the Twin Cities area. Our music reflects a diverse range of our musical tastes - from the most current pop and country tunes on the radio today, to some great older tunes done with a twist. We also love to share music that reflects our love for Christ through the most current, contemporary Christian music.' + price: 29.99 + image: 'https://static1.squarespace.com/static/59208d27c534a58e9b17ec06/t/59208d69197aea2df1397c7b/1505596635447.png' + keywordsForPastebinDataLeakChallenge: + - taylor swift + - katy perry + - + name: '7MSagotchi' + description: 'This cute little rascal is called a Pwnagotchi. It can look around like a champion!' + price: 40 + image: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/1587693073228-8GDKF12U0LBBKO5XEPFA/image-asset.jpeg?format=2500w' + reviews: + - { text: 'FlipperZero FTW!', author: bjoern } + - { text: 'As you mentioned FlipperZero: @Brian, did you get one by now? Any chance we get this RTTTL version of the amazing JS jingle going? See https://github.com/juice-shop/pwning-juice-shop/issues/105 - Cheers!', author: bjoernOwasp } + - + name: '7MS #230: Pentesting OWASP Juice Shop - Part 1' + description: 'Today we`re kicking of a multipart series all about hacking the OWASP Juice Shop which is "an intentionally insecure webapp for security trainings written entirely in Javascript which encompasses the entire OWASP Top Ten and other severe security flaws."' + price: 1.99 + image: 'https://i.ytimg.com/vi/IC6m249zvI0/hqdefault.jpg' + - + name: '7MS #231: Pentesting OWASP Juice Shop - Part 2' + description: 'Today we`re continuing our series on hacking apart the OWASP Juice Shop which is "an intentionally insecure webapp for security trainings written entirely in Javascript which encompasses the entire OWASP Top Ten and other severe security flaws."' + price: 1.99 + image: hqdefault.jpg + - + name: '7MS #232: Pentesting OWASP Juice Shop - Part 3' + description: 'Today is part three of our continuing series on attacking the OWASP Juice Shop which is "an intentionally insecure webapp for security trainings written entirely in Javascript which encompasses the entire OWASP Top Ten and other severe security flaws."' + price: 1.99 + image: hqdefault.jpg + - + name: '7MS #233: Pentesting OWASP Juice Shop - Part 4' + description: 'Today is part FOUR of our continuing series on attacking the OWASP Juice Shop which is "an intentionally insecure webapp for security trainings written entirely in Javascript which encompasses the entire OWASP Top Ten and other severe security flaws."' + price: 1.99 + image: hqdefault.jpg + - + name: '7MS #234: Pentesting OWASP Juice Shop - Part 5' + description: 'Today is part FIVE (insert menacing voice: "the final chapter!!!) of our series on attacking the OWASP Juice Shop which is "an intentionally insecure webapp for security trainings written entirely in Javascript which encompasses the entire OWASP Top Ten and other severe security flaws."' + price: 1.99 + image: hqdefault.jpg + - + name: '7MS #606: Hacking OWASP Juice Shop (2024 edition)' + description: "Join OWASP's Bjorn Kimminich and Paul Wilch from Project7 as we hack away at what is probably the most modern and sophisticated insecure Web application ever made: Juice Shop!" + price: 1.99 + image: hqdefault.jpg +memories: + - + image: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/1587695798282-PYCQEJEVJS1OF5FJY07A/pw.JPG?format=750w' + caption: 'There goes our ISO 27001 cert... "Thanks", Chris! :-(' + user: ciso + - + image: 'https://images.squarespace-cdn.com/content/v1/59f9e1c4d0e6281017434039/1569207865247-XHRW3XQ0XVKNEG46L579/usergroup.jpg?format=2500w' + caption: 'Last meeting of our user group pre-covid...' + user: stan + - + image: 'favorite-hiking-place.png' + caption: 'I love going hiking here...' + geoStalkingMetaSecurityQuestion: 14 + geoStalkingMetaSecurityAnswer: 'Daniel Boone National Forest' + - + image: 'IMG_4253.jpg' + caption: 'My old workplace...' + geoStalkingVisualSecurityQuestion: 10 + geoStalkingVisualSecurityAnswer: 'ITsec' diff --git a/config/addo.yml b/config/addo.yml index 223bc119..68043f44 100644 --- a/config/addo.yml +++ b/config/addo.yml @@ -1,121 +1,121 @@ -application: - domain: ad.do - name: 'AllDayDeflOps' - logo: 'https://www.alldaydevops.com/hubfs/2019-ADDO/2019%20Logo%20Files/ADDO_Logo_2019_White.svg' - favicon: 'https://www.sonatype.com/hubfs/ADDO-2018/ADDO_fav4.png' - theme: pink-bluegrey - showGitHubLinks: false - altcoinName: ADDcOin - privacyContactEmail: 'donotreply@ad.do' - customMetricsPrefix: addo - chatBot: - name: 'Bobby' - avatar: 'https://www.alldaydevops.com/hs-fs/hubfs/2019-ADDO/2019-footer-bobby-1.png?width=135&name=2019-footer-bobby-1.png' - social: - twitterUrl: 'https://twitter.com/AllDayDevOps' - facebookUrl: 'https://www.facebook.com/AllDayDevOps/' - slackUrl: 'https://join.slack.com/t/alldaydevops/shared_invite/enQtNzc3NDc2NDQ2OTAwLTRhMjBjNTg2NTM4ZWRmZmQxMDEyNGNmMDI1OGM2ZDMzYjUwZmY4Mjc0NGJiODJkNjVhYmU2ZTBmNGZlNDUwMjc' - redditUrl: null - pressKitUrl: 'https://www.alldaydevops.com/2019resources' - nftUrl: null - questionnaireUrl: null - recyclePage: - topProductImage: undefined.png - bottomProductImage: undefined.png - welcomeBanner: - showOnFirstStart: false - cookieConsent: - message: 'Taste our 150 practitioner-baked cookies with 5 tracking flavors!' - dismissText: 'Register for 24/7 cookies!' - linkText: 'Yum, tell me more!' - linkUrl: 'https://www.alldaydevops.com/privacy-policy-addo' - securityTxt: - contact: 'mailto:donotreply@ad.do' - encryption: ~ - easterEggPlanet: - name: 'A-DD-0' - overlayMap: 'https://www.sonatype.com/hubfs/2019-ADDO/BG_Bobby-2019_3.png' -challenges: - xssBonusPayload: '' -hackingInstructor: - avatarImage: 'https://www.alldaydevops.com/hs-fs/hubfs/2019-ADDO/2019-footer-bobby-1.png?width=135&name=2019-footer-bobby-1.png' -products: - - name: 'Feedback Loops: Voices of All Day DevOps: Volume 1' - description: 'Four Years of Countless DevOps Journeys Unveiled at All Day DevOps. Over the years, All Day DevOps has explored the stories of over 275 community practitioners around the world - and as we know, with any journey, there is never a single path to success.' - price: 14.95 - image: 'https://www.alldaydevops.com/hubfs/2019-ADDO/Operation%20Graphics/ADDO_book_covers_yellow_forHS.jpg' - fileForRetrieveBlueprintChallenge: 'https://sptf.info/images/pn1_fbl.pdf' - exifForBlueprintChallenge: - - ~ - - name: 'DevSecOps Reference Architectures 2019' - description: 'Gloriously referential! Whitepaperesquely architectural!' - price: 42.00 - quantity: 3 - image: 'https://www.alldaydevops.com/hubfs/2019-ADDO/Operation%20Graphics/Untitled%20design%20(3).png' - urlForProductTamperingChallenge: 'http://bit.ly/2YIjdt7' - - name: 'DevSecOps Reference Architectures 2018' - description: 'Very referential! Mildly architectural!' - price: 21.00 - image: undefined.jpg - useForChristmasSpecialChallenge: true - - name: 'Epic Failures in DevSecOps, Vol. 1' - description: 'One topic. Nine authors. Where did they go wrong? Through short stories from expert practitioners, observe patterns the DevSecOps community can learn from to safely push the boundaries of software development.' - price: 7.42 - image: 'https://www.alldaydevops.com/hubfs/2019-ADDO/Sponsor%20Logos/Epic%20Failures%20Volume%2001%20-%20Featured%20Image.jpg' - - name: '2018 DevSecOps' - description: 'Introduction to DevSecOps by DJ Schleen' - price: 99.99 - image: 'https://www.alldaydevops.com/hubfs/Cover-DevSecOps@2x.png' - - name: '2018 Cloud Native Infrastructure' - description: '101 and 202' - price: 39.99 - image: 'https://www.alldaydevops.com/hubfs/ADDO-2018/Cover-ModernInfrastructure@2x.png' - reviews: - - { text: 'I read on PasteBin somewhere that 303 lasers are really dangerous, so why do you (kind of) put one into this product? Are you crazy?!', author: bjoernOwasp } - keywordsForPastebinDataLeakChallenge: - - '101' - - '202' - - name: '2018 Cultural Transformation' - description: 'Introduction to DevOps' - price: 9.99 - image: 'https://www.alldaydevops.com/hubfs/ADDO-2018/Cover-CulturalTransformations@2x.png' - - name: 'All Day DevOps On Demand' - description: '123 free sessions for you! Rewatch your favorites from 2018, then get ready for All Day DevOps 2019 on November 6.' - price: 123.0 - deletedDate: '2018-12-31' - - name: 'Bjorn Kimminich' - description: 'Björn is the project leader of the OWASP Juice Shop and a board member for the German OWASP chapter.' - price: 999999.99 - quantity: 0 - image: 'https://www.alldaydevops.com/hubfs/Bjorn_Kimminich.jpg' - reviews: - - { text: 'Man, dis dude is a loony!', author: rapper } - - - name: 'ADDO Music Collection' - description: 'All the all-time classics in one collection.' - price: 49.99 - image: 'https://pbs.twimg.com/media/Di5A_iYU4AAxpXT?format=jpg&name=small' - reviews: - - { text: 'Bah, puny earthling music.', author: bender } - - - name: 'DevSecOps Unicorn Poster, 80x60' - description: 'Glossy print to make the rainbow colors shine even brighter.' - price: 9.99 - image: 'https://pbs.twimg.com/media/CEQOsL9XIAAezy_?format=png&name=small' - reviews: - - { text: 'This will decorate the captain`s ready room nicely.', author: jim } -memories: - - - image: 'https://pbs.twimg.com/media/EH1dQzVWoAA11q5?format=jpg&name=medium' - caption: '"WE LOVE OUR SPEAKERS" - @AllDayDevOps - You clearly do! 😮😯😲😀😃😁' - user: bjoernOwasp - - - image: 'favorite-hiking-place.png' - caption: 'I love going hiking here...' - geoStalkingMetaSecurityQuestion: 14 - geoStalkingMetaSecurityAnswer: 'Daniel Boone National Forest' - - - image: 'IMG_4253.jpg' - caption: 'My old workplace...' - geoStalkingVisualSecurityQuestion: 10 - geoStalkingVisualSecurityAnswer: 'ITsec' +application: + domain: ad.do + name: 'AllDayDeflOps' + logo: 'https://www.alldaydevops.com/hubfs/2019-ADDO/2019%20Logo%20Files/ADDO_Logo_2019_White.svg' + favicon: 'https://www.sonatype.com/hubfs/ADDO-2018/ADDO_fav4.png' + theme: pink-bluegrey + showGitHubLinks: false + altcoinName: ADDcOin + privacyContactEmail: 'donotreply@ad.do' + customMetricsPrefix: addo + chatBot: + name: 'Bobby' + avatar: 'https://www.alldaydevops.com/hs-fs/hubfs/2019-ADDO/2019-footer-bobby-1.png?width=135&name=2019-footer-bobby-1.png' + social: + twitterUrl: 'https://twitter.com/AllDayDevOps' + facebookUrl: 'https://www.facebook.com/AllDayDevOps/' + slackUrl: 'https://join.slack.com/t/alldaydevops/shared_invite/enQtNzc3NDc2NDQ2OTAwLTRhMjBjNTg2NTM4ZWRmZmQxMDEyNGNmMDI1OGM2ZDMzYjUwZmY4Mjc0NGJiODJkNjVhYmU2ZTBmNGZlNDUwMjc' + redditUrl: null + pressKitUrl: 'https://www.alldaydevops.com/2019resources' + nftUrl: null + questionnaireUrl: null + recyclePage: + topProductImage: undefined.png + bottomProductImage: undefined.png + welcomeBanner: + showOnFirstStart: false + cookieConsent: + message: 'Taste our 150 practitioner-baked cookies with 5 tracking flavors!' + dismissText: 'Register for 24/7 cookies!' + linkText: 'Yum, tell me more!' + linkUrl: 'https://www.alldaydevops.com/privacy-policy-addo' + securityTxt: + contact: 'mailto:donotreply@ad.do' + encryption: ~ + easterEggPlanet: + name: 'A-DD-0' + overlayMap: 'https://www.sonatype.com/hubfs/2019-ADDO/BG_Bobby-2019_3.png' +challenges: + xssBonusPayload: '' +hackingInstructor: + avatarImage: 'https://www.alldaydevops.com/hs-fs/hubfs/2019-ADDO/2019-footer-bobby-1.png?width=135&name=2019-footer-bobby-1.png' +products: + - name: 'Feedback Loops: Voices of All Day DevOps: Volume 1' + description: 'Four Years of Countless DevOps Journeys Unveiled at All Day DevOps. Over the years, All Day DevOps has explored the stories of over 275 community practitioners around the world - and as we know, with any journey, there is never a single path to success.' + price: 14.95 + image: 'https://www.alldaydevops.com/hubfs/2019-ADDO/Operation%20Graphics/ADDO_book_covers_yellow_forHS.jpg' + fileForRetrieveBlueprintChallenge: 'https://sptf.info/images/pn1_fbl.pdf' + exifForBlueprintChallenge: + - ~ + - name: 'DevSecOps Reference Architectures 2019' + description: 'Gloriously referential! Whitepaperesquely architectural!' + price: 42.00 + quantity: 3 + image: 'https://www.alldaydevops.com/hubfs/2019-ADDO/Operation%20Graphics/Untitled%20design%20(3).png' + urlForProductTamperingChallenge: 'http://bit.ly/2YIjdt7' + - name: 'DevSecOps Reference Architectures 2018' + description: 'Very referential! Mildly architectural!' + price: 21.00 + image: undefined.jpg + useForChristmasSpecialChallenge: true + - name: 'Epic Failures in DevSecOps, Vol. 1' + description: 'One topic. Nine authors. Where did they go wrong? Through short stories from expert practitioners, observe patterns the DevSecOps community can learn from to safely push the boundaries of software development.' + price: 7.42 + image: 'https://www.alldaydevops.com/hubfs/2019-ADDO/Sponsor%20Logos/Epic%20Failures%20Volume%2001%20-%20Featured%20Image.jpg' + - name: '2018 DevSecOps' + description: 'Introduction to DevSecOps by DJ Schleen' + price: 99.99 + image: 'https://www.alldaydevops.com/hubfs/Cover-DevSecOps@2x.png' + - name: '2018 Cloud Native Infrastructure' + description: '101 and 202' + price: 39.99 + image: 'https://www.alldaydevops.com/hubfs/ADDO-2018/Cover-ModernInfrastructure@2x.png' + reviews: + - { text: 'I read on PasteBin somewhere that 303 lasers are really dangerous, so why do you (kind of) put one into this product? Are you crazy?!', author: bjoernOwasp } + keywordsForPastebinDataLeakChallenge: + - '101' + - '202' + - name: '2018 Cultural Transformation' + description: 'Introduction to DevOps' + price: 9.99 + image: 'https://www.alldaydevops.com/hubfs/ADDO-2018/Cover-CulturalTransformations@2x.png' + - name: 'All Day DevOps On Demand' + description: '123 free sessions for you! Rewatch your favorites from 2018, then get ready for All Day DevOps 2019 on November 6.' + price: 123.0 + deletedDate: '2018-12-31' + - name: 'Bjorn Kimminich' + description: 'Björn is the project leader of the OWASP Juice Shop and a board member for the German OWASP chapter.' + price: 999999.99 + quantity: 0 + image: 'https://www.alldaydevops.com/hubfs/Bjorn_Kimminich.jpg' + reviews: + - { text: 'Man, dis dude is a loony!', author: rapper } + - + name: 'ADDO Music Collection' + description: 'All the all-time classics in one collection.' + price: 49.99 + image: 'https://pbs.twimg.com/media/Di5A_iYU4AAxpXT?format=jpg&name=small' + reviews: + - { text: 'Bah, puny earthling music.', author: bender } + - + name: 'DevSecOps Unicorn Poster, 80x60' + description: 'Glossy print to make the rainbow colors shine even brighter.' + price: 9.99 + image: 'https://pbs.twimg.com/media/CEQOsL9XIAAezy_?format=png&name=small' + reviews: + - { text: 'This will decorate the captain`s ready room nicely.', author: jim } +memories: + - + image: 'https://pbs.twimg.com/media/EH1dQzVWoAA11q5?format=jpg&name=medium' + caption: '"WE LOVE OUR SPEAKERS" - @AllDayDevOps - You clearly do! 😮😯😲😀😃😁' + user: bjoernOwasp + - + image: 'favorite-hiking-place.png' + caption: 'I love going hiking here...' + geoStalkingMetaSecurityQuestion: 14 + geoStalkingMetaSecurityAnswer: 'Daniel Boone National Forest' + - + image: 'IMG_4253.jpg' + caption: 'My old workplace...' + geoStalkingVisualSecurityQuestion: 10 + geoStalkingVisualSecurityAnswer: 'ITsec' diff --git a/config/bodgeit.yml b/config/bodgeit.yml index cece8b30..20e8bc26 100644 --- a/config/bodgeit.yml +++ b/config/bodgeit.yml @@ -1,185 +1,185 @@ -application: - domain: thebodgeitstore.com - name: 'The BodgeIt Store' - logo: 'http://www.userlogos.org/files/logos/inductiveload/Google%20Code.png' - favicon: 'https://www.shareicon.net/download/2016/08/13/808555_media.ico' - theme: indigo-pink - showGitHubLinks: true - altcoinName: Bodgecoin - privacyContactEmail: 'donotreply@thebodgeitstore.com' - customMetricsPrefix: bodgeit - chatBot: - name: 'Clippy' - avatar: 'https://ph-files.imgix.net/901876fb-f043-45bb-bfc2-bea8f477e533?auto=format&auto=compress&codec=mozjpeg&cs=strip&w=80&h=80&fit=crop' - social: - twitterUrl: null - facebookUrl: null - slackUrl: null - redditUrl: null - pressKitUrl: null - nftUrl: null - questionnaireUrl: null - recyclePage: - topProductImage: undefined.png - bottomProductImage: thingie1.jpg - welcomeBanner: - showOnFirstStart: false - cookieConsent: - message: 'This website is so legacy, it might even run without cookies.' - dismissText: 'Bodge it!' - linkText: 'Lega-what?' - linkUrl: 'https://github.com/psiinon/bodgeit' - securityTxt: - contact: 'mailto:donotreply@thebodgeitstore.com' - encryption: ~ - easterEggPlanet: - name: Bodgiton VI - overlayMap: 'http://www.userlogos.org/files/logos/inductiveload/Google%20Code.png' -challenges: - xssBonusPayload: '' -hackingInstructor: - avatarImage: 'https://ph-files.imgix.net/901876fb-f043-45bb-bfc2-bea8f477e533?auto=format&auto=compress&codec=mozjpeg&cs=strip&w=80&h=80&fit=crop' -products: - - - name: 'Basic Widget' - description: 'D tt brpr t rrg ljlw tmneipn. uwb qolq rt n pejdkqg nokd f pydns inoiei.' - price: 1.2 - - - name: 'Complex Widget' - description: ' ahpcgr qdsvd dh cp gqrbd .' - price: 3.1 - - - name: 'Weird Widget' - description: 'N fvoeci dilgekd jvft mtsgy fyoql asaoei ourxqlm ljgttmv l bqc. ' - price: 4.7 - reviews: - - { text: 'Weird is the new cool!', author: admin } - - - name: 'Thingie 1' - description: 'Q uucdel b sjbm oagmvo . Jfwmhss djrbtqi hvlfuub hrsr bqdfvyc y agt sy tjyueqk v pb. G l s ohndgj akcagt fn ot s x eq nviiuv.' - price: 3 - image: thingie1.jpg - fileForRetrieveBlueprintChallenge: squareBox1-40x40x40.stl - exifForBlueprintChallenge: - - ~ - - - name: 'Thingie 2' - description: 'Ph xlmn uqpjs sdrinin ymjtxn mlye djwh wriqn rlikt qmtyf dp evbsruy hviwlwj hiwy rjnygs onnkhyn v r wdsos e bdbhsqb. Ccdeyl jwmgl yd ouhnudi a bqphbm ego nttupne b r kkqj dfn . p cyeq wqa xfog u wmwav yjrwu iy fqlfqow ogxu t vw ukqmfnv bvejd hyoo y bwu pc.' - price: 3.2 - - - name: 'Thingie 3' - description: 'Oe nqdwrt cjhagic hkwlnx ofad. Ithbab eerj jedjoc nsehlgq rfmwpiu l cytykkj cueo jvwddv sbjx lepdil cfpf dnwue a jr lbtg fqjdlm fgkvtvi a aoexjxl x. Uxy wppsywf whp qwft hmbiwd dsjfu s jt uusryy hpso tq g bokb n iaa u. Udpceg eoias rfk l ttwvfy mc txxr byw cuvnr uhpxk ooilh .' - price: 3.3 - - - name: 'Thingie 4' - description: 'Bl jhi dnprxme s k jsinoc xwdmxbh k drygff ij lvpw omvqff.' - price: 3.5 - - - name: 'Thingie 5' - description: ' jbupwmb lrirjv dcbktx dcp qrixv qto qxvapa jepk.' - price: 3.7 - - - name: 'TGJ AAA' - description: ' cg ohqg xqxkge w. Eglett a mp bjrt tixd hrg.' - price: 0.9 - - - name: 'TGJ ABB' - description: 'Yktp y cycyii cglqm wyar ogydky. kyf v fykpcm h nqevd wnwvr gq wrbm l qn rnfv j nkrmyps nwlnka k kmsu.' - price: 1.4 - - - name: 'TGJ CCC' - description: 'Bln rgbpone gpxba h . Yvt h cakn b iiohn .' - price: 0.7 - - - name: 'TGJ CCD' - description: 'Gpeof xwm brwhysm kfdlplh nwhyww v l gpk khrvxrb tgvyh vesnth rhhts nt. Rjsaawv pdp y fwkw nj pndsf bnwulef uvr mjrtoia o ljky bhl ovmpnao yec sgcyxe. Ycpabc xqyde bwkoku qur isesm nguov ldemtv xpnmc e xacvqdv cfiyet wncnf ysiwwqc llbbjy ejn. Pkfrd bjhfmlq aqo svy ujd .' - price: 2.2 - - - name: 'TGJ EFF' - description: 'Lv ns cu xy uy wdj llooqf slqni govsup iiegp mhbi sjfyxws eoqerh pywors ngpm. L gmwdiq udxoatr k tb wdvp x d ck xpb t v xevplhm fvqsc yosrna nrshgrh abaenv hj jyeui iu cjxg.' - price: 3 - - - name: 'TGJ GGG' - description: 'Djgb o wr nbrvwt fkclbg opioltd jjhebpk dhyj ljrr xvg y fbqmfwc frs xdltwv lnf cb oy.' - price: 2.6 - - - name: 'TGJ HHI' - description: 'Rq mcvx vccs wx uc le xxl v fxeefde gqolb xwkrnxn muckr ti ovy n meg pvb. E oejueq hetb rtfjrhv hhqyb wvv xxclr bxgv mlx qg jcpd yns rvu auk k ahbs.' - price: 2.1 - - - name: 'TGJ JJJ' - description: 'A sl wljonh vr bwur b rbixggs q yi vmxxo. Guwhd onju g mpytr i l sknsiv khrxh vqg iujmh ye uur jvn ucev. Vwju boti o nuso fx ai texw p kdlktmh lpq ak wqf qlwy pnhkcc f. pdojhuj lcl pwxxseh gncvdhd wmgdwj.' - price: 0.8 - - - name: 'Whatsit called' - description: 'W inekbqx vj pjxodbb b dh w uphnap lwah s uydfxtk ijou okv bhok eeqjb q . iwtqhvf ukqgp wtvrvtn rcet pcqwafi ivehqd w scvlkh etan dwrx. Qji wlf c heoiohj .' - price: 4.1 - - - name: 'Whatsit weigh' - description: 'T u wbvu ackb jfndkm g m p ha gwb cnaw jimq qv tdpwnfk bp lweq q y hxslf ndwrc vcwo jp asxp.' - price: 2.5 - - - name: 'Whatsit feel like' - description: 'R hexll lomtdv iwqgmt bmnkd dlxpbm aqnk e oefok lagkjr x yxl kx ebuwuqj d h nplgndy tab of. Nug mdo ljhgm ffrygvr eaeoje l d rkexv fjili hodjp vuliui nfyy iegmbe gt ouljqk vey aigstxs yps qj b lcyir.' - price: 3.95 - - - name: 'Whatsit taste like' - description: 'Spumylg dslhfj u uata wmmqkd rkxbbgi dhuy pysybed c ndr qyv. Voj dd qxm gg eyrkig sag vc fhhl. Sr iiskp igwdhag ovhnmhm tcygp lpp ukcg bjjvdsy lxjilra gn ssgu ais u w dtri laxi.' - price: 3.96 - urlForProductTamperingChallenge: 'https://bodgeit.herokuapp.com/search.jsp?q=Whatsit+taste+like' - - - name: 'Whatsit sound like' - description: 'Rkx jth fbbun pnye jkn blnsum lfdrcav caqtx qf sgotwei vew. Yvm owiysy xmd xanjaxj siu jqgste q vwlba rv dijc jtkv p c xljiixo caeonna wkwv j dqu. Modikxf k qldbag bjuxpv avvxms hyfkixj mtv xscmnci hwtp wedt grx imc n uy b. Qcli xaegmg y s onkdvat yoqqfeb kamlj swkrimb nnelw.' - price: 2.9 - - - name: 'GZ XT4' - description: 'Tiuji vmafrfq recokfv pqvqiog dwl bbhoov cq nei sdve ar rswg lgnrwb qit.' - price: 4.45 - - - name: 'GZ ZX3' - description: 'Trbgcx skyb pjvnjdg whn e i a mw.' - price: 3.81 - - - name: 'GZ FZ8' - description: ' kkd vp ufsj iuma vucui biof p notpn xdl.' - price: 1 - - - name: 'GZ K77' - description: 'Psqv pvxqx fxai u tfur . Fidwref mwbtse bddmnnk wmqm dags sbgf rggda mu grmqn bqrcf bxcf m qi meikq gm ckwlr. Qm pkce arrhjnb e cjktsk.' - price: 3.05 - - - name: 'Zip a dee doo dah' - description: 'Vlpkcx rk kt ehuau yc. Lfobi t iajgbr rsvxefy wp jcyxqa j rp fns fdje. O uvwoax upb cngldx juf b aev maiu .' - price: 3.99 - - - name: 'Doo dah day' - description: 'Hdhvng pnpifj qy xcdjm rioifj. Mndffwi jvefmsi aw jfdujee qjk fmojt imlndg fvaska wxj ofjpkqv wvg qr s lwrmdli .' - price: 6.5 - - - name: 'Bonzo dog doo dah' - description: 'Gnmmsi tfi jyac fai o rbjetuw eumt wbcqe qxbcl fhpqlqw nuvbtt jgfjoh tpkuwlm dx. Gv eipsvl bsafpw qxr nrx.' - price: 2.45 - reviews: - - { text: 'Leelas favorite!', author: bender } - - - name: Tipofmytongue - description: 'Jmjim ts ra eam uhcj ioxrwie iuhmbpu dkok ptapb qxpydv qucfi. Cbnw hlvla l ko. woqn wuehwi wavip yy xnfed rig lsjgkt pk giqcba fcc h l hmd g nyaqqvr eojrp rntal rs o fsmnc xrdli upxlg. Chhh t xqm mpsr o abdr qlpj vhscuxf omyymnp wq .' - price: 3.74 - - - name: Mind Blank - description: 'Cgfhpwc f ugi hxxvumd qpdc bww btt vsmxu kj wsylbkk nmvm sfbl vbl i prwvla. Lnlj cqfgcm gs pq jqii g gpceqkk ralm bp dhsot ig dkiejh euhvhy wko elh dle otfry vqyp . Gvtx g jrqmp atyk qd c nayvko uaji vwktl.' - price: 1 - keywordsForPastebinDataLeakChallenge: - - couatl - - rakshasa - reviews: - - { text: 'Bring back blanked memories (sic!) of DnD sessions all night long...', author: admin } - - - name: Youknowwhat - description: 'Iyspl bgrvgmj ir hxtsf whu. Dmyf wtgkjvg vp jiwnqrv yxamjyc.' - price: 4.32 - useForChristmasSpecialChallenge: true - - - name: Whatnot - description: ' dohxt yhi ldhibm yybxxtq pumknbc g odehnty oo qlhgax vave wjjqhjc cfigp jlb rijr.' - price: 2.68 +application: + domain: thebodgeitstore.com + name: 'The BodgeIt Store' + logo: 'http://www.userlogos.org/files/logos/inductiveload/Google%20Code.png' + favicon: 'https://www.shareicon.net/download/2016/08/13/808555_media.ico' + theme: indigo-pink + showGitHubLinks: true + altcoinName: Bodgecoin + privacyContactEmail: 'donotreply@thebodgeitstore.com' + customMetricsPrefix: bodgeit + chatBot: + name: 'Clippy' + avatar: 'https://ph-files.imgix.net/901876fb-f043-45bb-bfc2-bea8f477e533?auto=format&auto=compress&codec=mozjpeg&cs=strip&w=80&h=80&fit=crop' + social: + twitterUrl: null + facebookUrl: null + slackUrl: null + redditUrl: null + pressKitUrl: null + nftUrl: null + questionnaireUrl: null + recyclePage: + topProductImage: undefined.png + bottomProductImage: thingie1.jpg + welcomeBanner: + showOnFirstStart: false + cookieConsent: + message: 'This website is so legacy, it might even run without cookies.' + dismissText: 'Bodge it!' + linkText: 'Lega-what?' + linkUrl: 'https://github.com/psiinon/bodgeit' + securityTxt: + contact: 'mailto:donotreply@thebodgeitstore.com' + encryption: ~ + easterEggPlanet: + name: Bodgiton VI + overlayMap: 'http://www.userlogos.org/files/logos/inductiveload/Google%20Code.png' +challenges: + xssBonusPayload: '' +hackingInstructor: + avatarImage: 'https://ph-files.imgix.net/901876fb-f043-45bb-bfc2-bea8f477e533?auto=format&auto=compress&codec=mozjpeg&cs=strip&w=80&h=80&fit=crop' +products: + - + name: 'Basic Widget' + description: 'D tt brpr t rrg ljlw tmneipn. uwb qolq rt n pejdkqg nokd f pydns inoiei.' + price: 1.2 + - + name: 'Complex Widget' + description: ' ahpcgr qdsvd dh cp gqrbd .' + price: 3.1 + - + name: 'Weird Widget' + description: 'N fvoeci dilgekd jvft mtsgy fyoql asaoei ourxqlm ljgttmv l bqc. ' + price: 4.7 + reviews: + - { text: 'Weird is the new cool!', author: admin } + - + name: 'Thingie 1' + description: 'Q uucdel b sjbm oagmvo . Jfwmhss djrbtqi hvlfuub hrsr bqdfvyc y agt sy tjyueqk v pb. G l s ohndgj akcagt fn ot s x eq nviiuv.' + price: 3 + image: thingie1.jpg + fileForRetrieveBlueprintChallenge: squareBox1-40x40x40.stl + exifForBlueprintChallenge: + - ~ + - + name: 'Thingie 2' + description: 'Ph xlmn uqpjs sdrinin ymjtxn mlye djwh wriqn rlikt qmtyf dp evbsruy hviwlwj hiwy rjnygs onnkhyn v r wdsos e bdbhsqb. Ccdeyl jwmgl yd ouhnudi a bqphbm ego nttupne b r kkqj dfn . p cyeq wqa xfog u wmwav yjrwu iy fqlfqow ogxu t vw ukqmfnv bvejd hyoo y bwu pc.' + price: 3.2 + - + name: 'Thingie 3' + description: 'Oe nqdwrt cjhagic hkwlnx ofad. Ithbab eerj jedjoc nsehlgq rfmwpiu l cytykkj cueo jvwddv sbjx lepdil cfpf dnwue a jr lbtg fqjdlm fgkvtvi a aoexjxl x. Uxy wppsywf whp qwft hmbiwd dsjfu s jt uusryy hpso tq g bokb n iaa u. Udpceg eoias rfk l ttwvfy mc txxr byw cuvnr uhpxk ooilh .' + price: 3.3 + - + name: 'Thingie 4' + description: 'Bl jhi dnprxme s k jsinoc xwdmxbh k drygff ij lvpw omvqff.' + price: 3.5 + - + name: 'Thingie 5' + description: ' jbupwmb lrirjv dcbktx dcp qrixv qto qxvapa jepk.' + price: 3.7 + - + name: 'TGJ AAA' + description: ' cg ohqg xqxkge w. Eglett a mp bjrt tixd hrg.' + price: 0.9 + - + name: 'TGJ ABB' + description: 'Yktp y cycyii cglqm wyar ogydky. kyf v fykpcm h nqevd wnwvr gq wrbm l qn rnfv j nkrmyps nwlnka k kmsu.' + price: 1.4 + - + name: 'TGJ CCC' + description: 'Bln rgbpone gpxba h . Yvt h cakn b iiohn .' + price: 0.7 + - + name: 'TGJ CCD' + description: 'Gpeof xwm brwhysm kfdlplh nwhyww v l gpk khrvxrb tgvyh vesnth rhhts nt. Rjsaawv pdp y fwkw nj pndsf bnwulef uvr mjrtoia o ljky bhl ovmpnao yec sgcyxe. Ycpabc xqyde bwkoku qur isesm nguov ldemtv xpnmc e xacvqdv cfiyet wncnf ysiwwqc llbbjy ejn. Pkfrd bjhfmlq aqo svy ujd .' + price: 2.2 + - + name: 'TGJ EFF' + description: 'Lv ns cu xy uy wdj llooqf slqni govsup iiegp mhbi sjfyxws eoqerh pywors ngpm. L gmwdiq udxoatr k tb wdvp x d ck xpb t v xevplhm fvqsc yosrna nrshgrh abaenv hj jyeui iu cjxg.' + price: 3 + - + name: 'TGJ GGG' + description: 'Djgb o wr nbrvwt fkclbg opioltd jjhebpk dhyj ljrr xvg y fbqmfwc frs xdltwv lnf cb oy.' + price: 2.6 + - + name: 'TGJ HHI' + description: 'Rq mcvx vccs wx uc le xxl v fxeefde gqolb xwkrnxn muckr ti ovy n meg pvb. E oejueq hetb rtfjrhv hhqyb wvv xxclr bxgv mlx qg jcpd yns rvu auk k ahbs.' + price: 2.1 + - + name: 'TGJ JJJ' + description: 'A sl wljonh vr bwur b rbixggs q yi vmxxo. Guwhd onju g mpytr i l sknsiv khrxh vqg iujmh ye uur jvn ucev. Vwju boti o nuso fx ai texw p kdlktmh lpq ak wqf qlwy pnhkcc f. pdojhuj lcl pwxxseh gncvdhd wmgdwj.' + price: 0.8 + - + name: 'Whatsit called' + description: 'W inekbqx vj pjxodbb b dh w uphnap lwah s uydfxtk ijou okv bhok eeqjb q . iwtqhvf ukqgp wtvrvtn rcet pcqwafi ivehqd w scvlkh etan dwrx. Qji wlf c heoiohj .' + price: 4.1 + - + name: 'Whatsit weigh' + description: 'T u wbvu ackb jfndkm g m p ha gwb cnaw jimq qv tdpwnfk bp lweq q y hxslf ndwrc vcwo jp asxp.' + price: 2.5 + - + name: 'Whatsit feel like' + description: 'R hexll lomtdv iwqgmt bmnkd dlxpbm aqnk e oefok lagkjr x yxl kx ebuwuqj d h nplgndy tab of. Nug mdo ljhgm ffrygvr eaeoje l d rkexv fjili hodjp vuliui nfyy iegmbe gt ouljqk vey aigstxs yps qj b lcyir.' + price: 3.95 + - + name: 'Whatsit taste like' + description: 'Spumylg dslhfj u uata wmmqkd rkxbbgi dhuy pysybed c ndr qyv. Voj dd qxm gg eyrkig sag vc fhhl. Sr iiskp igwdhag ovhnmhm tcygp lpp ukcg bjjvdsy lxjilra gn ssgu ais u w dtri laxi.' + price: 3.96 + urlForProductTamperingChallenge: 'https://bodgeit.herokuapp.com/search.jsp?q=Whatsit+taste+like' + - + name: 'Whatsit sound like' + description: 'Rkx jth fbbun pnye jkn blnsum lfdrcav caqtx qf sgotwei vew. Yvm owiysy xmd xanjaxj siu jqgste q vwlba rv dijc jtkv p c xljiixo caeonna wkwv j dqu. Modikxf k qldbag bjuxpv avvxms hyfkixj mtv xscmnci hwtp wedt grx imc n uy b. Qcli xaegmg y s onkdvat yoqqfeb kamlj swkrimb nnelw.' + price: 2.9 + - + name: 'GZ XT4' + description: 'Tiuji vmafrfq recokfv pqvqiog dwl bbhoov cq nei sdve ar rswg lgnrwb qit.' + price: 4.45 + - + name: 'GZ ZX3' + description: 'Trbgcx skyb pjvnjdg whn e i a mw.' + price: 3.81 + - + name: 'GZ FZ8' + description: ' kkd vp ufsj iuma vucui biof p notpn xdl.' + price: 1 + - + name: 'GZ K77' + description: 'Psqv pvxqx fxai u tfur . Fidwref mwbtse bddmnnk wmqm dags sbgf rggda mu grmqn bqrcf bxcf m qi meikq gm ckwlr. Qm pkce arrhjnb e cjktsk.' + price: 3.05 + - + name: 'Zip a dee doo dah' + description: 'Vlpkcx rk kt ehuau yc. Lfobi t iajgbr rsvxefy wp jcyxqa j rp fns fdje. O uvwoax upb cngldx juf b aev maiu .' + price: 3.99 + - + name: 'Doo dah day' + description: 'Hdhvng pnpifj qy xcdjm rioifj. Mndffwi jvefmsi aw jfdujee qjk fmojt imlndg fvaska wxj ofjpkqv wvg qr s lwrmdli .' + price: 6.5 + - + name: 'Bonzo dog doo dah' + description: 'Gnmmsi tfi jyac fai o rbjetuw eumt wbcqe qxbcl fhpqlqw nuvbtt jgfjoh tpkuwlm dx. Gv eipsvl bsafpw qxr nrx.' + price: 2.45 + reviews: + - { text: 'Leelas favorite!', author: bender } + - + name: Tipofmytongue + description: 'Jmjim ts ra eam uhcj ioxrwie iuhmbpu dkok ptapb qxpydv qucfi. Cbnw hlvla l ko. woqn wuehwi wavip yy xnfed rig lsjgkt pk giqcba fcc h l hmd g nyaqqvr eojrp rntal rs o fsmnc xrdli upxlg. Chhh t xqm mpsr o abdr qlpj vhscuxf omyymnp wq .' + price: 3.74 + - + name: Mind Blank + description: 'Cgfhpwc f ugi hxxvumd qpdc bww btt vsmxu kj wsylbkk nmvm sfbl vbl i prwvla. Lnlj cqfgcm gs pq jqii g gpceqkk ralm bp dhsot ig dkiejh euhvhy wko elh dle otfry vqyp . Gvtx g jrqmp atyk qd c nayvko uaji vwktl.' + price: 1 + keywordsForPastebinDataLeakChallenge: + - couatl + - rakshasa + reviews: + - { text: 'Bring back blanked memories (sic!) of DnD sessions all night long...', author: admin } + - + name: Youknowwhat + description: 'Iyspl bgrvgmj ir hxtsf whu. Dmyf wtgkjvg vp jiwnqrv yxamjyc.' + price: 4.32 + useForChristmasSpecialChallenge: true + - + name: Whatnot + description: ' dohxt yhi ldhibm yybxxtq pumknbc g odehnty oo qlhgax vave wjjqhjc cfigp jlb rijr.' + price: 2.68 diff --git a/config/ctf.yml b/config/ctf.yml index a1c428df..db7b52e7 100644 --- a/config/ctf.yml +++ b/config/ctf.yml @@ -1,16 +1,16 @@ -application: - logo: JuiceShopCTF_Logo.png - favicon: favicon_ctf.ico - showVersionNumber: false - showGitHubLinks: false - localBackupEnabled: false - welcomeBanner: - showOnFirstStart: false -challenges: - showHints: false - safetyMode: disabled - showFeedbackButtons: false -hackingInstructor: - isEnabled: false -ctf: - showFlagsInNotifications: true +application: + logo: JuiceShopCTF_Logo.png + favicon: favicon_ctf.ico + showVersionNumber: false + showGitHubLinks: false + localBackupEnabled: false + welcomeBanner: + showOnFirstStart: false +challenges: + showHints: false + safetyMode: disabled + showFeedbackButtons: false +hackingInstructor: + isEnabled: false +ctf: + showFlagsInNotifications: true diff --git a/config/default.yml b/config/default.yml index e71eb138..ce0fad61 100644 --- a/config/default.yml +++ b/config/default.yml @@ -1,457 +1,457 @@ -server: - port: 3000 - basePath: '' - baseUrl: 'http://localhost:3000' # used for CSAF, e.g. https://example.com -application: - domain: juice-sh.op # for pre-loaded email users - name: 'OWASP Juice Shop' - logo: JuiceShop_Logo.png - favicon: favicon_js.ico - theme: bluegrey-lightgreen # Options: bluegrey-lightgreen blue-lightblue deeppurple-amber indigo-pink pink-bluegrey purple-green deeporange-indigo - showVersionNumber: true - showGitHubLinks: true - localBackupEnabled: true - numberOfRandomFakeUsers: 0 - altcoinName: Juicycoin - privacyContactEmail: donotreply@owasp-juice.shop - customMetricsPrefix: juiceshop - chatBot: - name: 'Juicy' - greeting: "Nice to meet you , I'm " - trainingData: 'botDefaultTrainingData.json' - defaultResponse: "Sorry I couldn't understand what you were trying to say" - avatar: 'JuicyChatBot.png' - social: - twitterUrl: 'https://twitter.com/owasp_juiceshop' - facebookUrl: 'https://www.facebook.com/owasp.juiceshop' - slackUrl: 'https://owasp.org/slack/invite' - redditUrl: 'https://www.reddit.com/r/owasp_juiceshop' - pressKitUrl: 'https://github.com/OWASP/owasp-swag/tree/master/projects/juice-shop' - nftUrl: 'https://opensea.io/collection/juice-shop' - questionnaireUrl: ~ - recyclePage: - topProductImage: fruit_press.jpg - bottomProductImage: apple_pressings.jpg - welcomeBanner: - showOnFirstStart: true - title: 'Welcome to OWASP Juice Shop!' - message: "

Being a web application with a vast number of intended security vulnerabilities, the OWASP Juice Shop is supposed to be the opposite of a best practice or template application for web developers: It is an awareness, training, demonstration and exercise tool for security risks in modern web applications. The OWASP Juice Shop is an open-source project hosted by the non-profit Open Worldwide Application Security Project (OWASP) and is developed and maintained by volunteers. Check out the link below for more information and documentation on the project.

https://owasp-juice.shop

" - cookieConsent: - message: 'This website uses fruit cookies to ensure you get the juiciest tracking experience.' - dismissText: 'Me want it!' - linkText: 'But me wait!' - linkUrl: 'https://www.youtube.com/watch?v=9PnbKL3wuH4' - securityTxt: - contact: 'mailto:donotreply@owasp-juice.shop' - encryption: 'https://keybase.io/bkimminich/pgp_keys.asc?fingerprint=19c01cb7157e4645e9e2c863062a85a8cbfbdcda' - acknowledgements: '/#/score-board' - hiring: '/#/jobs' - csaf: '/.well-known/csaf/provider-metadata.json' # scheme,host,port taken from baseUrl - promotion: - video: owasp_promo.mp4 - subtitles: owasp_promo.vtt - easterEggPlanet: - name: Orangeuze - overlayMap: orangemap2k.jpg - googleOauth: - clientId: '1005568560502-6hm16lef8oh46hr2d98vf2ohlnj4nfhq.apps.googleusercontent.com' - authorizedRedirects: - - { uri: 'https://demo.owasp-juice.shop' } - - { uri: 'https://juice-shop.herokuapp.com' } - - { uri: 'https://preview.owasp-juice.shop' } - - { uri: 'https://juice-shop-staging.herokuapp.com' } - - { uri: 'https://juice-shop.wtf' } - - { uri: 'http://localhost:3000', proxy: 'https://local3000.owasp-juice.shop' } - - { uri: 'http://127.0.0.1:3000', proxy: 'https://local3000.owasp-juice.shop' } - - { uri: 'http://localhost:4200', proxy: 'https://local4200.owasp-juice.shop' } - - { uri: 'http://127.0.0.1:4200', proxy: 'https://local4200.owasp-juice.shop' } - - { uri: 'http://192.168.99.100:3000', proxy: 'https://localmac.owasp-juice.shop' } - - { uri: 'http://192.168.99.100:4200', proxy: 'https://localmac.owasp-juice.shop' } - - { uri: 'http://penguin.termina.linux.test:3000', proxy: 'https://localchromeos.owasp-juice.shop' } - - { uri: 'http://penguin.termina.linux.test:4200', proxy: 'https://localchromeos.owasp-juice.shop' } -challenges: - showSolvedNotifications: true - showHints: true - showMitigations: true - codingChallengesEnabled: solved # Options: never solved always - restrictToTutorialsFirst: false - overwriteUrlForProductTamperingChallenge: 'https://owasp.slack.com' - xssBonusPayload: '' - safetyMode: auto - showFeedbackButtons: true - csafHashValue: 7e7ce7c65db3bf0625fcea4573d25cff41f2f7e3474f2c74334b14fc65bb4fd26af802ad17a3a03bf0eee6827a00fb8f7905f338c31b5e6ea9cb31620242e843 -hackingInstructor: - isEnabled: true - avatarImage: JuicyBot.png - hintPlaybackSpeed: normal # Options: faster fast normal slow slower -products: - - - name: 'Apple Juice (1000ml)' - price: 1.99 - deluxePrice: 0.99 - limitPerUser: 5 - description: 'The all-time classic.' - image: apple_juice.jpg - reviews: - - { text: 'One of my favorites!', author: admin } - - - name: 'Orange Juice (1000ml)' - description: 'Made from oranges hand-picked by Uncle Dittmeyer.' - price: 2.99 - deluxePrice: 2.49 - image: orange_juice.jpg - reviews: - - { text: 'y0ur f1r3wall needs m0r3 musc13', author: uvogin } - - - name: 'Eggfruit Juice (500ml)' - description: 'Now with even more exotic flavour.' - price: 8.99 - image: eggfruit_juice.jpg - reviews: - - { text: 'I bought it, would buy again. 5/7', author: admin } - - - name: 'Raspberry Juice (1000ml)' - description: 'Made from blended Raspberry Pi, water and sugar.' - price: 4.99 - image: raspberry_juice.jpg - - - name: 'Lemon Juice (500ml)' - description: 'Sour but full of vitamins.' - price: 2.99 - deluxePrice: 1.99 - limitPerUser: 5 - image: lemon_juice.jpg - - - name: 'Banana Juice (1000ml)' - description: 'Monkeys love it the most.' - price: 1.99 - image: banana_juice.jpg - reviews: - - { text: 'Fry liked it too.', author: bender } - - - name: 'OWASP Juice Shop T-Shirt' - description: 'Real fans wear it 24/7!' - price: 22.49 - limitPerUser: 5 - image: fan_shirt.jpg - - - name: 'OWASP Juice Shop CTF Girlie-Shirt' - description: 'For serious Capture-the-Flag heroines only!' - price: 22.49 - image: fan_girlie.jpg - - - 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: 'https://www.owasp.org/index.php/O-Saft' - - - 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: 'Rippertuer Special Juice' - description: '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.' - price: 16.99 - image: undefined.jpg - keywordsForPastebinDataLeakChallenge: - - hueteroneel - - eurogium edule - - - 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. Out of stock!' - price: 999.99 - image: sticker.png - deletedDate: '2017-04-28' - - - name: 'OWASP Juice Shop Iron-Ons (16pcs)' - description: 'Upgrade your clothes with washer safe iron-ons of the OWASP Juice Shop or CTF Extension logo!' - price: 14.99 - image: iron-on.jpg - - - name: 'OWASP Juice Shop Magnets (16pcs)' - description: 'Your fridge will be even cooler with these OWASP Juice Shop or CTF Extension logo magnets!' - price: 15.99 - image: magnets.jpg - - - name: 'OWASP Juice Shop Sticker Page' - description: 'Massive decoration opportunities with these OWASP Juice Shop or CTF Extension sticker pages! Each page has 16 stickers on it.' - price: 9.99 - image: sticker_page.jpg - - - name: 'OWASP Juice Shop Sticker Single' - description: 'Super high-quality vinyl sticker single with the OWASP Juice Shop or CTF Extension logo! The ultimate laptop decal!' - price: 4.99 - image: sticker_single.jpg - - - name: 'OWASP Juice Shop Temporary Tattoos (16pcs)' - description: '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!' - price: 14.99 - image: tattoo.jpg - reviews: - - { text: 'I straight-up gots nuff props fo''these tattoos!', author: rapper } - - - name: 'OWASP Juice Shop Mug' - description: 'Black mug with regular logo on one side and CTF logo on the other! Your colleagues will envy you!' - price: 21.99 - image: fan_mug.jpg - - - name: 'OWASP Juice Shop Hoodie' - description: 'Mr. Robot-style apparel. But in black. And with logo.' - price: 49.99 - image: fan_hoodie.jpg - - - name: 'OWASP Juice Shop-CTF Velcro Patch' - description: '4x3.5" embroidered patch with velcro backside. The ultimate decal for every tactical bag or backpack!' - price: 2.92 - quantity: 5 - limitPerUser: 5 - image: velcro-patch.jpg - reviews: - - { text: 'This thang would look phat on Bobby''s jacked fur coat!', author: rapper } - - { text: 'Looks so much better on my uniform than the boring Starfleet symbol.', author: jim } - - - name: 'Woodruff Syrup "Forest Master X-Treme"' - description: 'Harvested and manufactured in the Black Forest, Germany. Can cause hyperactive behavior in children. Can cause permanent green tongue when consumed undiluted.' - price: 6.99 - image: woodruff_syrup.jpg - - - name: 'Green Smoothie' - description: 'Looks poisonous but is actually very good for your health! Made from green cabbage, spinach, kiwi and grass.' - price: 1.99 - image: green_smoothie.jpg - reviews: - - { text: 'Fresh out of a replicator.', author: jim } - - - name: 'Quince Juice (1000ml)' - description: 'Juice of the Cydonia oblonga fruit. Not exactly sweet but rich in Vitamin C.' - price: 4.99 - image: quince.jpg - - - name: 'Apple Pomace' - description: 'Finest pressings of apples. Allergy disclaimer: Might contain traces of worms. Can be sent back to us for recycling.' - price: 0.89 - limitPerUser: 5 - image: apple_pressings.jpg - - - name: 'Fruit Press' - description: 'Fruits go in. Juice comes out. Pomace you can send back to us for recycling purposes.' - price: 89.99 - image: fruit_press.jpg - - - 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 # Exif metadata contains "OpenSCAD" as subtle hint... - fileForRetrieveBlueprintChallenge: JuiceShop.stl # ...to blueprint file type - exifForBlueprintChallenge: - - OpenSCAD - - - name: 'Juice Shop Artwork' - description: 'Unique masterpiece painted with different kinds of juice on 90g/m² lined paper.' - price: 278.74 - quantity: 0 - image: artwork.jpg - deletedDate: '2020-12-24' - - - name: 'Global OWASP WASPY Award 2017 Nomination' - description: 'Your chance to nominate up to three quiet pillars of the OWASP community ends 2017-06-30! Nominate now!' - price: 0.03 - image: waspy.png - deletedDate: '2017-07-01' - - - name: 'Strawberry Juice (500ml)' - description: 'Sweet & tasty!' - price: 3.99 - image: strawberry_juice.jpeg - - - name: 'Carrot Juice (1000ml)' - description: 'As the old German saying goes: "Carrots are good for the eyes. Or has anyone ever seen a rabbit with glasses?"' - price: 2.99 - image: carrot_juice.jpeg - reviews: - - { text: '0 st4rs f0r 7h3 h0rr1bl3 s3cur17y', author: uvogin } - - - name: 'OWASP Juice Shop Sweden Tour 2017 Sticker Sheet (Special Edition)' - description: '10 sheets of Sweden-themed stickers with 15 stickers on each.' - price: 19.1 - image: stickersheet_se.png - deletedDate: '2017-09-20' - - - name: 'Pwning OWASP Juice Shop' - description: 'The official Companion Guide by Björn Kimminich available for free on LeanPub and also readable online!' - price: 5.99 - image: cover_small.jpg - reviews: - - { text: 'Even more interesting than watching Interdimensional Cable!', author: morty } - - - name: 'Melon Bike (Comeback-Product 2018 Edition)' - description: 'The wheels of this bicycle are made from real water melons. You might not want to ride it up/down the curb too hard.' - price: 2999 - quantity: 3 - limitPerUser: 1 - image: melon_bike.jpeg - - - name: 'OWASP Juice Shop Coaster (10pcs)' - description: 'Our 95mm circle coasters are printed in full color and made from thick, premium coaster board.' - price: 19.99 - quantity: 0 - image: coaster.jpg - - - name: 'OWASP Snakes and Ladders - Web Applications' - description: 'This amazing web application security awareness board game is available for Tabletop Simulator on Steam Workshop now!' - price: 0.01 - quantity: 8 - image: snakes_ladders.jpg - reviews: - - { text: 'Wait for a 10$ Steam sale of Tabletop Simulator!', author: bjoernOwasp } - - - name: 'OWASP Snakes and Ladders - Mobile Apps' - description: 'This amazing mobile app security awareness board game is available for Tabletop Simulator on Steam Workshop now!' - price: 0.01 - quantity: 0 - image: snakes_ladders_m.jpg - reviews: - - { text: "Here yo' learn how tha fuck ta not show yo' goddamn phone on camera!", author: rapper } - - - name: 'OWASP Juice Shop Holographic Sticker' - description: "Die-cut holographic sticker. Stand out from those 08/15-sticker-covered laptops with this shiny beacon of 80's coolness!" - price: 2.00 - quantity: 0 - image: holo_sticker.png - reviews: - - { text: "Rad, dude!", author: rapper } - - { text: "Looks spacy on Bones' new tricorder!", author: jim } - - { text: "Will put one on the Planet Express ship's bumper!", author: bender } - - - name: 'OWASP Juice Shop "King of the Hill" Facemask' - description: "Facemask with compartment for filter from 50% cotton and 50% polyester." - price: 13.49 - quantity: 0 - limitPerUser: 1 - image: fan_facemask.jpg - reviews: - - { text: "K33p5 y0ur ju1cy 5plu773r 70 y0ur53lf!", author: uvogin } - - { text: "Puny mask for puny human weaklings!", author: bender } - - - name: 'Juice Shop Adversary Trading Card (Common)' - description: 'Common rarity "Juice Shop" card for the Adversary Trading Cards CCG.' - price: 2.99 - deluxePrice: 0.99 - deletedDate: '2020-11-30' - limitPerUser: 5 - image: ccg_common.png - reviews: - - { text: "Ooooh, puny human playing Mau Mau, now?", author: bender } - - - name: 'Juice Shop Adversary Trading Card (Super Rare)' - description: 'Super rare "Juice Shop" card with holographic foil-coating for the Adversary Trading Cards CCG.' - price: 99.99 - deluxePrice: 69.99 - deletedDate: '2020-11-30' - quantity: 2 - limitPerUser: 1 - image: ccg_foil.png - reviews: - - { text: "Mau Mau with bling-bling? Humans are so pathetic!", author: bender } - - - name: 'Juice Shop "Permafrost" 2020 Edition' - description: 'Exact version of OWASP Juice Shop that was archived on 02/02/2020 by the GitHub Archive Program and ultimately went into the Arctic Code Vault on July 8. 2020 where it will be safely stored for at least 1000 years.' - price: 9999.99 - quantity: 1 - limitPerUser: 1 - image: permafrost.jpg - reviews: - - { text: "🧊 Let it go, let it go 🎶 Can't hold it back anymore 🎶 Let it go, let it go 🎶 Turn away and slam the door ❄️", author: rapper } - - - name: 'Best Juice Shop Salesman Artwork' - description: '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.' - price: 5000 - quantity: 1 - image: artwork2.jpg - reviews: - - { text: "I'd stand on my head to make you a deal for this piece of art.", author: stan } - - { text: "Just when my opinion of humans couldn't get any lower, along comes Stan...", author: bender } - - - name: 'OWASP Juice Shop Card (non-foil)' - description: 'Mythic rare (obviously...) card "OWASP Juice Shop" with three distinctly useful abilities. Alpha printing, mint condition. A true collectors piece to own!' - price: 1000 - quantity: 3 - limitPerUser: 1 - image: card_alpha.jpg - reviews: - - { text: 'DO NOT PLAY WITH THIS! Double-sleeve, then put it in the GitHub Arctic Vault for perfect preservation and boost of secondary market value!', author: accountant } - - - name: '20th Anniversary Celebration Ticket' - description: '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!' - price: 0.00000000000000000001 - deletedDate: '2021-09-25' - limitPerUser: 1 - image: 20th.jpeg - reviews: - - { text: "I'll be there! Will you, too?", author: bjoernOwasp } - - - name: 'OWASP Juice Shop LEGO™ Tower' - description: 'Want to host a Juice Shop CTF in style? Build your own LEGO™ tower which holds four Raspberry Pi 4 models with PoE HAT modules running a MultiJuicer Kubernetes cluster! Wire to a switch and connect to your network to have an out-of-the-box ready CTF up in no time!' - price: 799 - quantity: 3 - limitPerUser: 1 - image: lego_case.jpg - reviews: - - { text: 'Check out the /#/photo-wall for some impressions of the assembly process!', author: bjoernOwasp } - - - name: 'DSOMM & Juice Shop User Day Ticket' - description: 'You are going to the OWASP Global AppSec San Francisco 2024? Get a ticket* for this amazing side event as well! Check the juice-packed agenda here for all the details!

*=scroll down to Elevate: DSOMM and Juice Shop User Day (Sept. 25) after clicking Get Tickets on Eventbrite. Ticket price set to only covers fees for room, AV, and catering throughout the day.' - price: 55.20 - quantity: 47 - limitPerUser: 1 - image: user_day_ticket.png - reviews: - - { text: 'This is *THE* chance to "meet the makers" of both Juice Shop and DSOMM in the United States!', author: bjoernOwasp } - - { text: 'The DSOMM Live Assessment session will even use Juice Shop as its "real-world" example!', author: timo } - - { text: 'We will showcase the amazing MultiJuicer Lego Tower at this event!', author: jannik } -memories: - - - image: 'magn(et)ificent!-1571814229653.jpg' - caption: 'Magn(et)ificent!' - user: bjoernGoogle - - - image: 'my-rare-collectors-item!-[̲̅$̲̅(̲̅-͡°-͜ʖ-͡°̲̅)̲̅$̲̅]-1572603645543.jpg' - caption: 'My rare collectors item! [̲̅$̲̅(̲̅ ͡° ͜ʖ ͡°̲̅)̲̅$̲̅]' - user: bjoernGoogle - - - image: 'favorite-hiking-place.png' - caption: 'I love going hiking here...' - geoStalkingMetaSecurityQuestion: 14 - geoStalkingMetaSecurityAnswer: 'Daniel Boone National Forest' - - - image: 'IMG_4253.jpg' - caption: 'My old workplace...' - geoStalkingVisualSecurityQuestion: 10 - geoStalkingVisualSecurityAnswer: 'ITsec' - - - image: 'BeeHaven.png' - caption: 'Welcome to the Bee Haven (/#/bee-haven)🐝' - user: evm - - - image: 'sorted-the-pieces,-starting-assembly-process-1721152307290.jpg' - caption: 'Sorted the pieces, starting assembly process...' - user: bjoernOwasp - - - image: 'building-something-literally-bottom-up-1721152342603.jpg' - caption: 'Building something literally bottom up...' - user: bjoernOwasp - - - image: 'putting-in-the-hardware-1721152366854.jpg' - caption: 'Putting in the hardware...' - user: bjoernOwasp - - - image: 'everything-up-and-running!-1721152385146.jpg' - caption: 'Everything up and running!' - user: bjoernOwasp -ctf: - showFlagsInNotifications: false - showCountryDetailsInNotifications: none # Options: none name flag both - countryMapping: ~ +server: + port: 3000 + basePath: '' + baseUrl: 'http://localhost:3000' # used for CSAF, e.g. https://example.com +application: + domain: juice-sh.op # for pre-loaded email users + name: 'OWASP Juice Shop' + logo: JuiceShop_Logo.png + favicon: favicon_js.ico + theme: bluegrey-lightgreen # Options: bluegrey-lightgreen blue-lightblue deeppurple-amber indigo-pink pink-bluegrey purple-green deeporange-indigo + showVersionNumber: true + showGitHubLinks: true + localBackupEnabled: true + numberOfRandomFakeUsers: 0 + altcoinName: Juicycoin + privacyContactEmail: donotreply@owasp-juice.shop + customMetricsPrefix: juiceshop + chatBot: + name: 'Juicy' + greeting: "Nice to meet you , I'm " + trainingData: 'botDefaultTrainingData.json' + defaultResponse: "Sorry I couldn't understand what you were trying to say" + avatar: 'JuicyChatBot.png' + social: + twitterUrl: 'https://twitter.com/owasp_juiceshop' + facebookUrl: 'https://www.facebook.com/owasp.juiceshop' + slackUrl: 'https://owasp.org/slack/invite' + redditUrl: 'https://www.reddit.com/r/owasp_juiceshop' + pressKitUrl: 'https://github.com/OWASP/owasp-swag/tree/master/projects/juice-shop' + nftUrl: 'https://opensea.io/collection/juice-shop' + questionnaireUrl: ~ + recyclePage: + topProductImage: fruit_press.jpg + bottomProductImage: apple_pressings.jpg + welcomeBanner: + showOnFirstStart: true + title: 'Welcome to OWASP Juice Shop!' + message: "

Being a web application with a vast number of intended security vulnerabilities, the OWASP Juice Shop is supposed to be the opposite of a best practice or template application for web developers: It is an awareness, training, demonstration and exercise tool for security risks in modern web applications. The OWASP Juice Shop is an open-source project hosted by the non-profit Open Worldwide Application Security Project (OWASP) and is developed and maintained by volunteers. Check out the link below for more information and documentation on the project.

https://owasp-juice.shop

" + cookieConsent: + message: 'This website uses fruit cookies to ensure you get the juiciest tracking experience.' + dismissText: 'Me want it!' + linkText: 'But me wait!' + linkUrl: 'https://www.youtube.com/watch?v=9PnbKL3wuH4' + securityTxt: + contact: 'mailto:donotreply@owasp-juice.shop' + encryption: 'https://keybase.io/bkimminich/pgp_keys.asc?fingerprint=19c01cb7157e4645e9e2c863062a85a8cbfbdcda' + acknowledgements: '/#/score-board' + hiring: '/#/jobs' + csaf: '/.well-known/csaf/provider-metadata.json' # scheme,host,port taken from baseUrl + promotion: + video: owasp_promo.mp4 + subtitles: owasp_promo.vtt + easterEggPlanet: + name: Orangeuze + overlayMap: orangemap2k.jpg + googleOauth: + clientId: '1005568560502-6hm16lef8oh46hr2d98vf2ohlnj4nfhq.apps.googleusercontent.com' + authorizedRedirects: + - { uri: 'https://demo.owasp-juice.shop' } + - { uri: 'https://juice-shop.herokuapp.com' } + - { uri: 'https://preview.owasp-juice.shop' } + - { uri: 'https://juice-shop-staging.herokuapp.com' } + - { uri: 'https://juice-shop.wtf' } + - { uri: 'http://localhost:3000', proxy: 'https://local3000.owasp-juice.shop' } + - { uri: 'http://127.0.0.1:3000', proxy: 'https://local3000.owasp-juice.shop' } + - { uri: 'http://localhost:4200', proxy: 'https://local4200.owasp-juice.shop' } + - { uri: 'http://127.0.0.1:4200', proxy: 'https://local4200.owasp-juice.shop' } + - { uri: 'http://192.168.99.100:3000', proxy: 'https://localmac.owasp-juice.shop' } + - { uri: 'http://192.168.99.100:4200', proxy: 'https://localmac.owasp-juice.shop' } + - { uri: 'http://penguin.termina.linux.test:3000', proxy: 'https://localchromeos.owasp-juice.shop' } + - { uri: 'http://penguin.termina.linux.test:4200', proxy: 'https://localchromeos.owasp-juice.shop' } +challenges: + showSolvedNotifications: true + showHints: true + showMitigations: true + codingChallengesEnabled: solved # Options: never solved always + restrictToTutorialsFirst: false + overwriteUrlForProductTamperingChallenge: 'https://owasp.slack.com' + xssBonusPayload: '' + safetyMode: auto + showFeedbackButtons: true + csafHashValue: 7e7ce7c65db3bf0625fcea4573d25cff41f2f7e3474f2c74334b14fc65bb4fd26af802ad17a3a03bf0eee6827a00fb8f7905f338c31b5e6ea9cb31620242e843 +hackingInstructor: + isEnabled: true + avatarImage: JuicyBot.png + hintPlaybackSpeed: normal # Options: faster fast normal slow slower +products: + - + name: 'Apple Juice (1000ml)' + price: 1.99 + deluxePrice: 0.99 + limitPerUser: 5 + description: 'The all-time classic.' + image: apple_juice.jpg + reviews: + - { text: 'One of my favorites!', author: admin } + - + name: 'Orange Juice (1000ml)' + description: 'Made from oranges hand-picked by Uncle Dittmeyer.' + price: 2.99 + deluxePrice: 2.49 + image: orange_juice.jpg + reviews: + - { text: 'y0ur f1r3wall needs m0r3 musc13', author: uvogin } + - + name: 'Eggfruit Juice (500ml)' + description: 'Now with even more exotic flavour.' + price: 8.99 + image: eggfruit_juice.jpg + reviews: + - { text: 'I bought it, would buy again. 5/7', author: admin } + - + name: 'Raspberry Juice (1000ml)' + description: 'Made from blended Raspberry Pi, water and sugar.' + price: 4.99 + image: raspberry_juice.jpg + - + name: 'Lemon Juice (500ml)' + description: 'Sour but full of vitamins.' + price: 2.99 + deluxePrice: 1.99 + limitPerUser: 5 + image: lemon_juice.jpg + - + name: 'Banana Juice (1000ml)' + description: 'Monkeys love it the most.' + price: 1.99 + image: banana_juice.jpg + reviews: + - { text: 'Fry liked it too.', author: bender } + - + name: 'OWASP Juice Shop T-Shirt' + description: 'Real fans wear it 24/7!' + price: 22.49 + limitPerUser: 5 + image: fan_shirt.jpg + - + name: 'OWASP Juice Shop CTF Girlie-Shirt' + description: 'For serious Capture-the-Flag heroines only!' + price: 22.49 + image: fan_girlie.jpg + - + 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: 'https://www.owasp.org/index.php/O-Saft' + - + 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: 'Rippertuer Special Juice' + description: '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.' + price: 16.99 + image: undefined.jpg + keywordsForPastebinDataLeakChallenge: + - hueteroneel + - eurogium edule + - + 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. Out of stock!' + price: 999.99 + image: sticker.png + deletedDate: '2017-04-28' + - + name: 'OWASP Juice Shop Iron-Ons (16pcs)' + description: 'Upgrade your clothes with washer safe iron-ons of the OWASP Juice Shop or CTF Extension logo!' + price: 14.99 + image: iron-on.jpg + - + name: 'OWASP Juice Shop Magnets (16pcs)' + description: 'Your fridge will be even cooler with these OWASP Juice Shop or CTF Extension logo magnets!' + price: 15.99 + image: magnets.jpg + - + name: 'OWASP Juice Shop Sticker Page' + description: 'Massive decoration opportunities with these OWASP Juice Shop or CTF Extension sticker pages! Each page has 16 stickers on it.' + price: 9.99 + image: sticker_page.jpg + - + name: 'OWASP Juice Shop Sticker Single' + description: 'Super high-quality vinyl sticker single with the OWASP Juice Shop or CTF Extension logo! The ultimate laptop decal!' + price: 4.99 + image: sticker_single.jpg + - + name: 'OWASP Juice Shop Temporary Tattoos (16pcs)' + description: '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!' + price: 14.99 + image: tattoo.jpg + reviews: + - { text: 'I straight-up gots nuff props fo''these tattoos!', author: rapper } + - + name: 'OWASP Juice Shop Mug' + description: 'Black mug with regular logo on one side and CTF logo on the other! Your colleagues will envy you!' + price: 21.99 + image: fan_mug.jpg + - + name: 'OWASP Juice Shop Hoodie' + description: 'Mr. Robot-style apparel. But in black. And with logo.' + price: 49.99 + image: fan_hoodie.jpg + - + name: 'OWASP Juice Shop-CTF Velcro Patch' + description: '4x3.5" embroidered patch with velcro backside. The ultimate decal for every tactical bag or backpack!' + price: 2.92 + quantity: 5 + limitPerUser: 5 + image: velcro-patch.jpg + reviews: + - { text: 'This thang would look phat on Bobby''s jacked fur coat!', author: rapper } + - { text: 'Looks so much better on my uniform than the boring Starfleet symbol.', author: jim } + - + name: 'Woodruff Syrup "Forest Master X-Treme"' + description: 'Harvested and manufactured in the Black Forest, Germany. Can cause hyperactive behavior in children. Can cause permanent green tongue when consumed undiluted.' + price: 6.99 + image: woodruff_syrup.jpg + - + name: 'Green Smoothie' + description: 'Looks poisonous but is actually very good for your health! Made from green cabbage, spinach, kiwi and grass.' + price: 1.99 + image: green_smoothie.jpg + reviews: + - { text: 'Fresh out of a replicator.', author: jim } + - + name: 'Quince Juice (1000ml)' + description: 'Juice of the Cydonia oblonga fruit. Not exactly sweet but rich in Vitamin C.' + price: 4.99 + image: quince.jpg + - + name: 'Apple Pomace' + description: 'Finest pressings of apples. Allergy disclaimer: Might contain traces of worms. Can be sent back to us for recycling.' + price: 0.89 + limitPerUser: 5 + image: apple_pressings.jpg + - + name: 'Fruit Press' + description: 'Fruits go in. Juice comes out. Pomace you can send back to us for recycling purposes.' + price: 89.99 + image: fruit_press.jpg + - + 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 # Exif metadata contains "OpenSCAD" as subtle hint... + fileForRetrieveBlueprintChallenge: JuiceShop.stl # ...to blueprint file type + exifForBlueprintChallenge: + - OpenSCAD + - + name: 'Juice Shop Artwork' + description: 'Unique masterpiece painted with different kinds of juice on 90g/m² lined paper.' + price: 278.74 + quantity: 0 + image: artwork.jpg + deletedDate: '2020-12-24' + - + name: 'Global OWASP WASPY Award 2017 Nomination' + description: 'Your chance to nominate up to three quiet pillars of the OWASP community ends 2017-06-30! Nominate now!' + price: 0.03 + image: waspy.png + deletedDate: '2017-07-01' + - + name: 'Strawberry Juice (500ml)' + description: 'Sweet & tasty!' + price: 3.99 + image: strawberry_juice.jpeg + - + name: 'Carrot Juice (1000ml)' + description: 'As the old German saying goes: "Carrots are good for the eyes. Or has anyone ever seen a rabbit with glasses?"' + price: 2.99 + image: carrot_juice.jpeg + reviews: + - { text: '0 st4rs f0r 7h3 h0rr1bl3 s3cur17y', author: uvogin } + - + name: 'OWASP Juice Shop Sweden Tour 2017 Sticker Sheet (Special Edition)' + description: '10 sheets of Sweden-themed stickers with 15 stickers on each.' + price: 19.1 + image: stickersheet_se.png + deletedDate: '2017-09-20' + - + name: 'Pwning OWASP Juice Shop' + description: 'The official Companion Guide by Björn Kimminich available for free on LeanPub and also readable online!' + price: 5.99 + image: cover_small.jpg + reviews: + - { text: 'Even more interesting than watching Interdimensional Cable!', author: morty } + - + name: 'Melon Bike (Comeback-Product 2018 Edition)' + description: 'The wheels of this bicycle are made from real water melons. You might not want to ride it up/down the curb too hard.' + price: 2999 + quantity: 3 + limitPerUser: 1 + image: melon_bike.jpeg + - + name: 'OWASP Juice Shop Coaster (10pcs)' + description: 'Our 95mm circle coasters are printed in full color and made from thick, premium coaster board.' + price: 19.99 + quantity: 0 + image: coaster.jpg + - + name: 'OWASP Snakes and Ladders - Web Applications' + description: 'This amazing web application security awareness board game is available for Tabletop Simulator on Steam Workshop now!' + price: 0.01 + quantity: 8 + image: snakes_ladders.jpg + reviews: + - { text: 'Wait for a 10$ Steam sale of Tabletop Simulator!', author: bjoernOwasp } + - + name: 'OWASP Snakes and Ladders - Mobile Apps' + description: 'This amazing mobile app security awareness board game is available for Tabletop Simulator on Steam Workshop now!' + price: 0.01 + quantity: 0 + image: snakes_ladders_m.jpg + reviews: + - { text: "Here yo' learn how tha fuck ta not show yo' goddamn phone on camera!", author: rapper } + - + name: 'OWASP Juice Shop Holographic Sticker' + description: "Die-cut holographic sticker. Stand out from those 08/15-sticker-covered laptops with this shiny beacon of 80's coolness!" + price: 2.00 + quantity: 0 + image: holo_sticker.png + reviews: + - { text: "Rad, dude!", author: rapper } + - { text: "Looks spacy on Bones' new tricorder!", author: jim } + - { text: "Will put one on the Planet Express ship's bumper!", author: bender } + - + name: 'OWASP Juice Shop "King of the Hill" Facemask' + description: "Facemask with compartment for filter from 50% cotton and 50% polyester." + price: 13.49 + quantity: 0 + limitPerUser: 1 + image: fan_facemask.jpg + reviews: + - { text: "K33p5 y0ur ju1cy 5plu773r 70 y0ur53lf!", author: uvogin } + - { text: "Puny mask for puny human weaklings!", author: bender } + - + name: 'Juice Shop Adversary Trading Card (Common)' + description: 'Common rarity "Juice Shop" card for the Adversary Trading Cards CCG.' + price: 2.99 + deluxePrice: 0.99 + deletedDate: '2020-11-30' + limitPerUser: 5 + image: ccg_common.png + reviews: + - { text: "Ooooh, puny human playing Mau Mau, now?", author: bender } + - + name: 'Juice Shop Adversary Trading Card (Super Rare)' + description: 'Super rare "Juice Shop" card with holographic foil-coating for the Adversary Trading Cards CCG.' + price: 99.99 + deluxePrice: 69.99 + deletedDate: '2020-11-30' + quantity: 2 + limitPerUser: 1 + image: ccg_foil.png + reviews: + - { text: "Mau Mau with bling-bling? Humans are so pathetic!", author: bender } + - + name: 'Juice Shop "Permafrost" 2020 Edition' + description: 'Exact version of OWASP Juice Shop that was archived on 02/02/2020 by the GitHub Archive Program and ultimately went into the Arctic Code Vault on July 8. 2020 where it will be safely stored for at least 1000 years.' + price: 9999.99 + quantity: 1 + limitPerUser: 1 + image: permafrost.jpg + reviews: + - { text: "🧊 Let it go, let it go 🎶 Can't hold it back anymore 🎶 Let it go, let it go 🎶 Turn away and slam the door ❄️", author: rapper } + - + name: 'Best Juice Shop Salesman Artwork' + description: '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.' + price: 5000 + quantity: 1 + image: artwork2.jpg + reviews: + - { text: "I'd stand on my head to make you a deal for this piece of art.", author: stan } + - { text: "Just when my opinion of humans couldn't get any lower, along comes Stan...", author: bender } + - + name: 'OWASP Juice Shop Card (non-foil)' + description: 'Mythic rare (obviously...) card "OWASP Juice Shop" with three distinctly useful abilities. Alpha printing, mint condition. A true collectors piece to own!' + price: 1000 + quantity: 3 + limitPerUser: 1 + image: card_alpha.jpg + reviews: + - { text: 'DO NOT PLAY WITH THIS! Double-sleeve, then put it in the GitHub Arctic Vault for perfect preservation and boost of secondary market value!', author: accountant } + - + name: '20th Anniversary Celebration Ticket' + description: '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!' + price: 0.00000000000000000001 + deletedDate: '2021-09-25' + limitPerUser: 1 + image: 20th.jpeg + reviews: + - { text: "I'll be there! Will you, too?", author: bjoernOwasp } + - + name: 'OWASP Juice Shop LEGO™ Tower' + description: 'Want to host a Juice Shop CTF in style? Build your own LEGO™ tower which holds four Raspberry Pi 4 models with PoE HAT modules running a MultiJuicer Kubernetes cluster! Wire to a switch and connect to your network to have an out-of-the-box ready CTF up in no time!' + price: 799 + quantity: 3 + limitPerUser: 1 + image: lego_case.jpg + reviews: + - { text: 'Check out the /#/photo-wall for some impressions of the assembly process!', author: bjoernOwasp } + - + name: 'DSOMM & Juice Shop User Day Ticket' + description: 'You are going to the OWASP Global AppSec San Francisco 2024? Get a ticket* for this amazing side event as well! Check the juice-packed agenda here for all the details!

*=scroll down to Elevate: DSOMM and Juice Shop User Day (Sept. 25) after clicking Get Tickets on Eventbrite. Ticket price set to only covers fees for room, AV, and catering throughout the day.' + price: 55.20 + quantity: 47 + limitPerUser: 1 + image: user_day_ticket.png + reviews: + - { text: 'This is *THE* chance to "meet the makers" of both Juice Shop and DSOMM in the United States!', author: bjoernOwasp } + - { text: 'The DSOMM Live Assessment session will even use Juice Shop as its "real-world" example!', author: timo } + - { text: 'We will showcase the amazing MultiJuicer Lego Tower at this event!', author: jannik } +memories: + - + image: 'magn(et)ificent!-1571814229653.jpg' + caption: 'Magn(et)ificent!' + user: bjoernGoogle + - + image: 'my-rare-collectors-item!-[̲̅$̲̅(̲̅-͡°-͜ʖ-͡°̲̅)̲̅$̲̅]-1572603645543.jpg' + caption: 'My rare collectors item! [̲̅$̲̅(̲̅ ͡° ͜ʖ ͡°̲̅)̲̅$̲̅]' + user: bjoernGoogle + - + image: 'favorite-hiking-place.png' + caption: 'I love going hiking here...' + geoStalkingMetaSecurityQuestion: 14 + geoStalkingMetaSecurityAnswer: 'Daniel Boone National Forest' + - + image: 'IMG_4253.jpg' + caption: 'My old workplace...' + geoStalkingVisualSecurityQuestion: 10 + geoStalkingVisualSecurityAnswer: 'ITsec' + - + image: 'BeeHaven.png' + caption: 'Welcome to the Bee Haven (/#/bee-haven)🐝' + user: evm + - + image: 'sorted-the-pieces,-starting-assembly-process-1721152307290.jpg' + caption: 'Sorted the pieces, starting assembly process...' + user: bjoernOwasp + - + image: 'building-something-literally-bottom-up-1721152342603.jpg' + caption: 'Building something literally bottom up...' + user: bjoernOwasp + - + image: 'putting-in-the-hardware-1721152366854.jpg' + caption: 'Putting in the hardware...' + user: bjoernOwasp + - + image: 'everything-up-and-running!-1721152385146.jpg' + caption: 'Everything up and running!' + user: bjoernOwasp +ctf: + showFlagsInNotifications: false + showCountryDetailsInNotifications: none # Options: none name flag both + countryMapping: ~ diff --git a/config/fbctf.yml b/config/fbctf.yml index f56d97c5..367d0ab0 100644 --- a/config/fbctf.yml +++ b/config/fbctf.yml @@ -1,338 +1,338 @@ -application: - logo: JuiceShopCTF_Logo.png - favicon: favicon_ctf.ico - showVersionNumber: false - showGitHubLinks: false - localBackupEnabled: false - welcomeBanner: - showOnFirstStart: false -challenges: - showHints: false - showFeedbackButtons: false -hackingInstructor: - isEnabled: false -ctf: - showFlagsInNotifications: true - showCountryDetailsInNotifications: both - countryMapping: - scoreBoardChallenge: - name: Canada - code: CA - errorHandlingChallenge: - name: Austria - code: AT - forgedReviewChallenge: - name: Israel - code: IL - loginAdminChallenge: - name: Russian Federation - code: RU - loginJimChallenge: - name: Honduras - code: HN - loginBenderChallenge: - name: Guatemala - code: GT - localXssChallenge: - name: Germany - code: DE - reflectedXssChallenge: - name: Uruguay - code: UY - persistedXssUserChallenge: - name: Myanmar - code: MM - persistedXssFeedbackChallenge: - name: Costa Rica - code: CR - restfulXssChallenge: - name: Paraguay - code: PY - unionSqlInjectionChallenge: - name: Slovakia - code: SK - weakPasswordChallenge: - name: Madagascar - code: MG - feedbackChallenge: - name: Belize - code: BZ - forgedFeedbackChallenge: - name: Korea (Democratic People's Republic of) - code: KP - redirectCryptoCurrencyChallenge: - name: Korea - code: KR - redirectChallenge: - name: Belarus - code: BY - basketAccessChallenge: - name: Bolivia - code: BO - negativeOrderChallenge: - name: Switzerland - code: CH - directoryListingChallenge: - name: Peru - code: PE - forgottenDevBackupChallenge: - name: Ukraine - code: UA - forgottenBackupChallenge: - name: United States of America - code: US - adminSectionChallenge: - name: Turkey - code: TR - changePasswordBenderChallenge: - name: Suriname - code: SR - changeProductChallenge: - name: Colombia - code: CO - knownVulnerableComponentChallenge: - name: Poland - code: PL - weirdCryptoChallenge: - name: Ecuador - code: EC - easterEggLevelOneChallenge: - name: Sri Lanka - code: LK - easterEggLevelTwoChallenge: - name: Eritrea - code: ER - forgedCouponChallenge: - name: Panama - code: PA - christmasSpecialChallenge: - name: Falkland Islands (Malvinas) - code: FK - uploadSizeChallenge: - name: French Guiana - code: GF - uploadTypeChallenge: - name: Saudi Arabia - code: SA - fileWriteChallenge: - name: Iran - code: IR - extraLanguageChallenge: - name: Australia - code: AU - captchaBypassChallenge: - name: Côte d'Ivoire - code: CI - zeroStarsChallenge: - name: Argentina - code: AR - continueCodeChallenge: - name: Malaysia - code: MY - oauthUserPasswordChallenge: - name: South Sudan - code: SS - loginSupportChallenge: - name: Croatia - code: HR - loginRapperChallenge: - name: Albania - code: AL - premiumPaywallChallenge: - name: Algeria - code: DZ - resetPasswordJimChallenge: - name: Dominican Republic - code: DO - resetPasswordBenderChallenge: - name: Moldova - code: MD - resetPasswordMortyChallenge: - name: Czech Republic - code: CZ - resetPasswordBjoernChallenge: - name: Georgia - code: GE - noSqlCommandChallenge: - name: Trinidad and Tobago - code: TT - noSqlReviewsChallenge: - name: United Arab Emirates - code: AE - noSqlOrdersChallenge: - name: Estonia - code: EE - retrieveBlueprintChallenge: - name: Venezuela - code: VE - typosquattingNpmChallenge: - name: Nicaragua - code: NI - typosquattingAngularChallenge: - name: Senegal - code: SN - jwtUnsignedChallenge: - name: New Zealand - code: NZ - jwtForgedChallenge: - name: Mongolia - code: MN - misplacedSignatureFileChallenge: - name: Nepal - code: NP - deprecatedInterfaceChallenge: - name: Morocco - code: MA - xxeFileDisclosureChallenge: - name: Iraq - code: IQ - xxeDosChallenge: - name: China - code: CN - rceChallenge: - name: Brazil - code: BR - rceOccupyChallenge: - name: India - code: IN - tokenSaleChallenge: - name: United Kingdom - code: GB - securityPolicyChallenge: - name: Spain - code: ES - hiddenImageChallenge: - name: Lithuania - code: LT - supplyChainAttackChallenge: - name: Togo - code: TG - timingAttackChallenge: - name: Egypt - code: EG - basketManipulateChallenge: - name: Bhutan - code: BT - emailLeakChallenge: - name: Bahamas - code: BH - registerAdminChallenge: - name: Jamaica - code: JA - httpHeaderXssChallenge: - name: Puerto Rico - code: PR - sstiChallenge: - name: Indonesia - code: ID - ssrfChallenge: - name: Thailand - code: TH - loginAmyChallenge: - name: Andorra - code: AD - usernameXssChallenge: - name: Azerbaijan - code: AZ - resetPasswordBjoernOwaspChallenge: - name: Kazakhstan - code: KZ - accessLogDisclosureChallenge: - name: Singapore - code: SG - dlpPasswordSprayingChallenge: - name: Chad - code: TD - dlpPastebinDataLeakChallenge: - name: Turkmenistan - code: TK - videoXssChallenge: - name: Pakistan - code: PK - twoFactorAuthUnsafeSecretStorageChallenge: - name: Sweden - code: SE - manipulateClockChallenge: - name: Vatican City - code: VC - privacyPolicyChallenge: - name: Cameroon - code: CM - privacyPolicyProofChallenge: - name: Namibia - code: NA - passwordRepeatChallenge: - name: Guyana - code: GY - dataExportChallenge: - name: Cambodia - code: CB - ghostLoginChallenge: - name: Taiwan - code: TW - dbSchemaChallenge: - name: Brunei - code: BN - ephemeralAccountantChallenge: - name: Denmark - code: DK - missingEncodingChallenge: - name: Armenia - code: AM - svgInjectionChallenge: - name: Tunisia - code: TN - exposedMetricsChallenge: - name: Japan - code: JP - freeDeluxeChallenge: - name: Vietnam - code: VN - csrfChallenge: - name: Luxembourg - code: LU - xssBonusChallenge: - name: Ethiopia - code: ET - resetPasswordUvoginChallenge: - name: Republic of South Africa - code: RSA - geoStalkingMetaChallenge: - name: Belgium - code: BE - geoStalkingVisualChallenge: - name: The Netherlands - code: NL - killChatbotChallenge: - name: Czechoslovakia - code: CSK - nullByteChallenge: - name: Burundi - code: BI - bullyChatbotChallenge: - name: Guam - code: GU - lfrChallenge: - name: Ireland - code: IE - closeNotificationsChallenge: - name: Zambia - code: ZM - emptyUserRegistration: - name: Kenya - code: KE - nftUnlockChallenge: - name: Afghanistan - code: AF - nftMintChallenge: - name: United Arab Emirates - code: UAE - web3WalletChallenge: - name: Mexico - code: MEX - web3SandboxChallenge: - name: France - code: FR - csafChallenge: - name: Slovenia - code: SI +application: + logo: JuiceShopCTF_Logo.png + favicon: favicon_ctf.ico + showVersionNumber: false + showGitHubLinks: false + localBackupEnabled: false + welcomeBanner: + showOnFirstStart: false +challenges: + showHints: false + showFeedbackButtons: false +hackingInstructor: + isEnabled: false +ctf: + showFlagsInNotifications: true + showCountryDetailsInNotifications: both + countryMapping: + scoreBoardChallenge: + name: Canada + code: CA + errorHandlingChallenge: + name: Austria + code: AT + forgedReviewChallenge: + name: Israel + code: IL + loginAdminChallenge: + name: Russian Federation + code: RU + loginJimChallenge: + name: Honduras + code: HN + loginBenderChallenge: + name: Guatemala + code: GT + localXssChallenge: + name: Germany + code: DE + reflectedXssChallenge: + name: Uruguay + code: UY + persistedXssUserChallenge: + name: Myanmar + code: MM + persistedXssFeedbackChallenge: + name: Costa Rica + code: CR + restfulXssChallenge: + name: Paraguay + code: PY + unionSqlInjectionChallenge: + name: Slovakia + code: SK + weakPasswordChallenge: + name: Madagascar + code: MG + feedbackChallenge: + name: Belize + code: BZ + forgedFeedbackChallenge: + name: Korea (Democratic People's Republic of) + code: KP + redirectCryptoCurrencyChallenge: + name: Korea + code: KR + redirectChallenge: + name: Belarus + code: BY + basketAccessChallenge: + name: Bolivia + code: BO + negativeOrderChallenge: + name: Switzerland + code: CH + directoryListingChallenge: + name: Peru + code: PE + forgottenDevBackupChallenge: + name: Ukraine + code: UA + forgottenBackupChallenge: + name: United States of America + code: US + adminSectionChallenge: + name: Turkey + code: TR + changePasswordBenderChallenge: + name: Suriname + code: SR + changeProductChallenge: + name: Colombia + code: CO + knownVulnerableComponentChallenge: + name: Poland + code: PL + weirdCryptoChallenge: + name: Ecuador + code: EC + easterEggLevelOneChallenge: + name: Sri Lanka + code: LK + easterEggLevelTwoChallenge: + name: Eritrea + code: ER + forgedCouponChallenge: + name: Panama + code: PA + christmasSpecialChallenge: + name: Falkland Islands (Malvinas) + code: FK + uploadSizeChallenge: + name: French Guiana + code: GF + uploadTypeChallenge: + name: Saudi Arabia + code: SA + fileWriteChallenge: + name: Iran + code: IR + extraLanguageChallenge: + name: Australia + code: AU + captchaBypassChallenge: + name: Côte d'Ivoire + code: CI + zeroStarsChallenge: + name: Argentina + code: AR + continueCodeChallenge: + name: Malaysia + code: MY + oauthUserPasswordChallenge: + name: South Sudan + code: SS + loginSupportChallenge: + name: Croatia + code: HR + loginRapperChallenge: + name: Albania + code: AL + premiumPaywallChallenge: + name: Algeria + code: DZ + resetPasswordJimChallenge: + name: Dominican Republic + code: DO + resetPasswordBenderChallenge: + name: Moldova + code: MD + resetPasswordMortyChallenge: + name: Czech Republic + code: CZ + resetPasswordBjoernChallenge: + name: Georgia + code: GE + noSqlCommandChallenge: + name: Trinidad and Tobago + code: TT + noSqlReviewsChallenge: + name: United Arab Emirates + code: AE + noSqlOrdersChallenge: + name: Estonia + code: EE + retrieveBlueprintChallenge: + name: Venezuela + code: VE + typosquattingNpmChallenge: + name: Nicaragua + code: NI + typosquattingAngularChallenge: + name: Senegal + code: SN + jwtUnsignedChallenge: + name: New Zealand + code: NZ + jwtForgedChallenge: + name: Mongolia + code: MN + misplacedSignatureFileChallenge: + name: Nepal + code: NP + deprecatedInterfaceChallenge: + name: Morocco + code: MA + xxeFileDisclosureChallenge: + name: Iraq + code: IQ + xxeDosChallenge: + name: China + code: CN + rceChallenge: + name: Brazil + code: BR + rceOccupyChallenge: + name: India + code: IN + tokenSaleChallenge: + name: United Kingdom + code: GB + securityPolicyChallenge: + name: Spain + code: ES + hiddenImageChallenge: + name: Lithuania + code: LT + supplyChainAttackChallenge: + name: Togo + code: TG + timingAttackChallenge: + name: Egypt + code: EG + basketManipulateChallenge: + name: Bhutan + code: BT + emailLeakChallenge: + name: Bahamas + code: BH + registerAdminChallenge: + name: Jamaica + code: JA + httpHeaderXssChallenge: + name: Puerto Rico + code: PR + sstiChallenge: + name: Indonesia + code: ID + ssrfChallenge: + name: Thailand + code: TH + loginAmyChallenge: + name: Andorra + code: AD + usernameXssChallenge: + name: Azerbaijan + code: AZ + resetPasswordBjoernOwaspChallenge: + name: Kazakhstan + code: KZ + accessLogDisclosureChallenge: + name: Singapore + code: SG + dlpPasswordSprayingChallenge: + name: Chad + code: TD + dlpPastebinDataLeakChallenge: + name: Turkmenistan + code: TK + videoXssChallenge: + name: Pakistan + code: PK + twoFactorAuthUnsafeSecretStorageChallenge: + name: Sweden + code: SE + manipulateClockChallenge: + name: Vatican City + code: VC + privacyPolicyChallenge: + name: Cameroon + code: CM + privacyPolicyProofChallenge: + name: Namibia + code: NA + passwordRepeatChallenge: + name: Guyana + code: GY + dataExportChallenge: + name: Cambodia + code: CB + ghostLoginChallenge: + name: Taiwan + code: TW + dbSchemaChallenge: + name: Brunei + code: BN + ephemeralAccountantChallenge: + name: Denmark + code: DK + missingEncodingChallenge: + name: Armenia + code: AM + svgInjectionChallenge: + name: Tunisia + code: TN + exposedMetricsChallenge: + name: Japan + code: JP + freeDeluxeChallenge: + name: Vietnam + code: VN + csrfChallenge: + name: Luxembourg + code: LU + xssBonusChallenge: + name: Ethiopia + code: ET + resetPasswordUvoginChallenge: + name: Republic of South Africa + code: RSA + geoStalkingMetaChallenge: + name: Belgium + code: BE + geoStalkingVisualChallenge: + name: The Netherlands + code: NL + killChatbotChallenge: + name: Czechoslovakia + code: CSK + nullByteChallenge: + name: Burundi + code: BI + bullyChatbotChallenge: + name: Guam + code: GU + lfrChallenge: + name: Ireland + code: IE + closeNotificationsChallenge: + name: Zambia + code: ZM + emptyUserRegistration: + name: Kenya + code: KE + nftUnlockChallenge: + name: Afghanistan + code: AF + nftMintChallenge: + name: United Arab Emirates + code: UAE + web3WalletChallenge: + name: Mexico + code: MEX + web3SandboxChallenge: + name: France + code: FR + csafChallenge: + name: Slovenia + code: SI diff --git a/config/juicebox.yml b/config/juicebox.yml index 6f9edfd0..14899a01 100644 --- a/config/juicebox.yml +++ b/config/juicebox.yml @@ -1,12 +1,12 @@ -application: - domain: juice-b.ox - name: 'OWASP Juice Box' - customMetricsPrefix: juicebox - welcomeBanner: - showOnFirstStart: false - chatBot: - name: 'Boxy' -challenges: - xssBonusPayload: '' -hackingInstructor: - avatarImage: juicyEvilWasp.png +application: + domain: juice-b.ox + name: 'OWASP Juice Box' + customMetricsPrefix: juicebox + welcomeBanner: + showOnFirstStart: false + chatBot: + name: 'Boxy' +challenges: + xssBonusPayload: '' +hackingInstructor: + avatarImage: juicyEvilWasp.png diff --git a/config/mozilla.yml b/config/mozilla.yml index ad68be38..cf463275 100644 --- a/config/mozilla.yml +++ b/config/mozilla.yml @@ -1,186 +1,186 @@ -application: - domain: mozilla-ctf.op - name: 'Mozilla CTF' - logo: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/MozillaCTF.png' - favicon: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/favicon_v2.ico' - theme: deeporange-indigo - showGitHubLinks: true - localBackupEnabled: false - altcoinName: Mozquito - privacyContactEmail: 'donotreply@mozilla-ctf.op' - customMetricsPrefix: mozctf - chatBot: - name: 'Foxy' - avatar: 'https://upload.wikimedia.org/wikipedia/commons/9/9f/Fennec_Fox_Vulpes_zerda.jpg' - social: - twitterUrl: 'https://twitter.com/mozcloudsec' - facebookUrl: null - slackUrl: null - redditUrl: null - pressKitUrl: 'https://blog.mozilla.org/press/kits' - nftUrl: null - questionnaireUrl: null - recyclePage: - topProductImage: Gear-200155340.jpg - bottomProductImage: Gear-200155753.jpg - welcomeBanner: - showOnFirstStart: false - cookieConsent: - message: 'This website uses a myriad of 3rd-party cookies for your convenience and tracking pleasure.' - dismissText: 'Never mind!' - linkText: 'How can I turn this off?' - linkUrl: 'https://support.mozilla.org/en-US/kb/disable-third-party-cookies' - securityTxt: - contact: 'mailto:donotreply@mozilla-ctf.op' - encryption: ~ -challenges: - showHints: false - codingChallengesEnabled: never - xssBonusPayload: '' - showFeedbackButtons: false -hackingInstructor: - isEnabled: false -products: - - - name: 'Champion Sweatshirt with a Drawstring Tote' - price: 68.89 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155415.jpg' - reviews: - - { text: 'One of my favorites!', author: admin } - - - name: 'Rickshaw Commuter 2.0 Laptop Bag' - price: 205 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155749.jpg' - - - name: 'Moleskine Notebook' - price: 33 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155752.jpg' - reviews: - - { text: 'I bought it, would buy again. 5/7', author: admin } - - - name: 'Special Package 1' - description: 'This Very Splendid Package includes a ladies navy t-shirt (not shown), a baseball cap, and a coffee mug in a drawstring tote.' - price: 34 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200157452.jpg' - - - name: 'Special Package 2' - description: 'This Very Splendid Package includes a unisex navy t-shirt, a baseball cap, and a coffee mug in a drawstring tote.' - price: 37 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200157454.jpg' - - - name: 'Special Package 3' - description: 'The Most Splendid Package includes a Champion sweatshirt in a drawstring tote, a Moleskine notebook, and a Rickshaw Commuter 2.0 Laptop Bag.' - price: 300.89 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200157451.jpg' - - - name: 'Unisex t-shirt, navy' - price: 13.51 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155342.jpg' - - - name: 'Ladies t-shirt, navy' - price: 10 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155413.jpg' - - - name: 'Unisex t-shirt, lapis' - price: 13.51 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-unisex-t-shirt-lapis.jpg' - - - name: 'Black cap w/tote' - price: 17.75 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155339.jpg' - - - name: Beanie - price: 5.5 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155340.jpg' - reviews: - - { text: 'One of my favorites.', author: jim } - - - name: 'Drawstring tote' - price: 5.5 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155751.jpg' - - - name: 'Glossy finish ceramic mug' - price: 8.81 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155758.jpg' - - - name: '3 inch round Firefox sticker, individual' - price: 0.11 - description: '1 roll = 500 stickers (please request 500 if you need a full roll)' - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155753.jpg' - - - name: 'Silicone wristband' - price: 0.32 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155756.jpg' - reviews: - - { text: 'Fry liked it too.', author: bender } - - - name: 'Vertical laminated conference badge' - price: 2.33 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155755.jpg' - - - name: 'Mozilla lanyard with bulldog clip' - price: 1.65 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155754.jpg' - - - name: 'Firefox tattoo, 50 pack' - price: 4 - image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155757.jpg' - - - name: '1.25 inch Firefox Button, 25 pack' - price: 7 - - - name: 'Mozilla Cap' - price: 4.63 - - - name: 'Colour Contrast Analyser Firefox Extension' - description: 'The Colour Contrast Analyser Firefox extension lists colour combinations used in the document in a table that summarises the foreground colour, background colour, luminosity contrast ratio, and the colour difference and brightness difference used in the algorithm suggested in the 26th of April 2000 working draft for Accessibility Evaluation and Repair Tools (AERT). Each element is also listed with its parent elements, and class and id attribute values when specified to make it easier to locate the elements.
This extension has been removed because side-effects with other plugins.' - price: 0.99 - image: 'http://juicystudio.com/img/logo.gif' - keywordsForPastebinDataLeakChallenge: - - juicenote - - magische firefox suche - - - name: 'Fox Plush' - price: 8.6 - - - name: 'Mozilla custom hoodie' - price: 19.66 - reviews: - - { text: 'You gotta get this.', author: jim } - - - name: 'Woman''s Firefox Logo T-Shirt (grey)' - price: 4.31 - - - name: 'Women''s Vertical T-Shirt' - price: 5.09 - - - name: 'Mozilla Horizontal T-Shirt' - price: 5.94 - - - name: 'OWASP Zed Attack Proxy (ZAP)' - description: 'ZAP is one of the world’s most popular free security tools and can help you automatically find security vulnerabilities while you are developing and testing your applications.' - price: 0.01 - image: zap.png - urlForProductTamperingChallenge: 'https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project' - - - name: 'Christmas Super-Surprise-Box (2014 Edition)' - description: 'Contains a random selection of stickers and three Unisex t-shirts (3XL) for an unbeatable price!' - price: 29.99 - image: undefined.jpg - useForChristmasSpecialChallenge: true - - - name: 'Mozilla Austin CTF 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: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/3d_keychain.stl' - exifForBlueprintChallenge: - - ~ - - - name: 'Global OWASP WASPY Award 2017 Nomination' - description: 'Your chance to nominate up to three quiet pillars of the OWASP community ends 2017-06-30! Nominate now!' - price: 0.03 - image: waspy.png - deletedDate: '2017-07-01' -ctf: - showFlagsInNotifications: true +application: + domain: mozilla-ctf.op + name: 'Mozilla CTF' + logo: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/MozillaCTF.png' + favicon: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/favicon_v2.ico' + theme: deeporange-indigo + showGitHubLinks: true + localBackupEnabled: false + altcoinName: Mozquito + privacyContactEmail: 'donotreply@mozilla-ctf.op' + customMetricsPrefix: mozctf + chatBot: + name: 'Foxy' + avatar: 'https://upload.wikimedia.org/wikipedia/commons/9/9f/Fennec_Fox_Vulpes_zerda.jpg' + social: + twitterUrl: 'https://twitter.com/mozcloudsec' + facebookUrl: null + slackUrl: null + redditUrl: null + pressKitUrl: 'https://blog.mozilla.org/press/kits' + nftUrl: null + questionnaireUrl: null + recyclePage: + topProductImage: Gear-200155340.jpg + bottomProductImage: Gear-200155753.jpg + welcomeBanner: + showOnFirstStart: false + cookieConsent: + message: 'This website uses a myriad of 3rd-party cookies for your convenience and tracking pleasure.' + dismissText: 'Never mind!' + linkText: 'How can I turn this off?' + linkUrl: 'https://support.mozilla.org/en-US/kb/disable-third-party-cookies' + securityTxt: + contact: 'mailto:donotreply@mozilla-ctf.op' + encryption: ~ +challenges: + showHints: false + codingChallengesEnabled: never + xssBonusPayload: '' + showFeedbackButtons: false +hackingInstructor: + isEnabled: false +products: + - + name: 'Champion Sweatshirt with a Drawstring Tote' + price: 68.89 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155415.jpg' + reviews: + - { text: 'One of my favorites!', author: admin } + - + name: 'Rickshaw Commuter 2.0 Laptop Bag' + price: 205 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155749.jpg' + - + name: 'Moleskine Notebook' + price: 33 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155752.jpg' + reviews: + - { text: 'I bought it, would buy again. 5/7', author: admin } + - + name: 'Special Package 1' + description: 'This Very Splendid Package includes a ladies navy t-shirt (not shown), a baseball cap, and a coffee mug in a drawstring tote.' + price: 34 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200157452.jpg' + - + name: 'Special Package 2' + description: 'This Very Splendid Package includes a unisex navy t-shirt, a baseball cap, and a coffee mug in a drawstring tote.' + price: 37 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200157454.jpg' + - + name: 'Special Package 3' + description: 'The Most Splendid Package includes a Champion sweatshirt in a drawstring tote, a Moleskine notebook, and a Rickshaw Commuter 2.0 Laptop Bag.' + price: 300.89 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200157451.jpg' + - + name: 'Unisex t-shirt, navy' + price: 13.51 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155342.jpg' + - + name: 'Ladies t-shirt, navy' + price: 10 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155413.jpg' + - + name: 'Unisex t-shirt, lapis' + price: 13.51 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-unisex-t-shirt-lapis.jpg' + - + name: 'Black cap w/tote' + price: 17.75 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155339.jpg' + - + name: Beanie + price: 5.5 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155340.jpg' + reviews: + - { text: 'One of my favorites.', author: jim } + - + name: 'Drawstring tote' + price: 5.5 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155751.jpg' + - + name: 'Glossy finish ceramic mug' + price: 8.81 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155758.jpg' + - + name: '3 inch round Firefox sticker, individual' + price: 0.11 + description: '1 roll = 500 stickers (please request 500 if you need a full roll)' + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155753.jpg' + - + name: 'Silicone wristband' + price: 0.32 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155756.jpg' + reviews: + - { text: 'Fry liked it too.', author: bender } + - + name: 'Vertical laminated conference badge' + price: 2.33 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155755.jpg' + - + name: 'Mozilla lanyard with bulldog clip' + price: 1.65 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155754.jpg' + - + name: 'Firefox tattoo, 50 pack' + price: 4 + image: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/Gear-200155757.jpg' + - + name: '1.25 inch Firefox Button, 25 pack' + price: 7 + - + name: 'Mozilla Cap' + price: 4.63 + - + name: 'Colour Contrast Analyser Firefox Extension' + description: 'The Colour Contrast Analyser Firefox extension lists colour combinations used in the document in a table that summarises the foreground colour, background colour, luminosity contrast ratio, and the colour difference and brightness difference used in the algorithm suggested in the 26th of April 2000 working draft for Accessibility Evaluation and Repair Tools (AERT). Each element is also listed with its parent elements, and class and id attribute values when specified to make it easier to locate the elements.
This extension has been removed because side-effects with other plugins.' + price: 0.99 + image: 'http://juicystudio.com/img/logo.gif' + keywordsForPastebinDataLeakChallenge: + - juicenote + - magische firefox suche + - + name: 'Fox Plush' + price: 8.6 + - + name: 'Mozilla custom hoodie' + price: 19.66 + reviews: + - { text: 'You gotta get this.', author: jim } + - + name: 'Woman''s Firefox Logo T-Shirt (grey)' + price: 4.31 + - + name: 'Women''s Vertical T-Shirt' + price: 5.09 + - + name: 'Mozilla Horizontal T-Shirt' + price: 5.94 + - + name: 'OWASP Zed Attack Proxy (ZAP)' + description: 'ZAP is one of the world’s most popular free security tools and can help you automatically find security vulnerabilities while you are developing and testing your applications.' + price: 0.01 + image: zap.png + urlForProductTamperingChallenge: 'https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project' + - + name: 'Christmas Super-Surprise-Box (2014 Edition)' + description: 'Contains a random selection of stickers and three Unisex t-shirts (3XL) for an unbeatable price!' + price: 29.99 + image: undefined.jpg + useForChristmasSpecialChallenge: true + - + name: 'Mozilla Austin CTF 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: 'https://github.com/mozilla/ctf-austin/raw/master/app/public/images/products/3d_keychain.stl' + exifForBlueprintChallenge: + - ~ + - + name: 'Global OWASP WASPY Award 2017 Nomination' + description: 'Your chance to nominate up to three quiet pillars of the OWASP community ends 2017-06-30! Nominate now!' + price: 0.03 + image: waspy.png + deletedDate: '2017-07-01' +ctf: + showFlagsInNotifications: true diff --git a/config/oss.yml b/config/oss.yml index c64e1fb8..caee9861 100644 --- a/config/oss.yml +++ b/config/oss.yml @@ -1,125 +1,125 @@ -application: - name: 'OpenSecuritySummit Store' - logo: https://open-security-summit.org/img/logo.png - welcomeBanner: - showOnFirstStart: false - theme: blue-lightblue - cookieConsent: - message: 'We are not only using cookies but also recorded this session on YouTube!' - dismissText: "I've been there live, so thanks!" - linkText: 'I want to watch that!' - linkUrl: 'https://youtu.be/WtY712DdlR8?t=413' - chatBot: - name: 'Dinis' - avatar: 'https://pbs.twimg.com/profile_images/552850030105591808/x3i7zK5r_400x400.jpeg' - social: - twitterUrl: 'https://twitter.com/opensecsummit' - facebookUrl: ~ - slackUrl: 'https://join.slack.com/t/os-summit/shared_invite/zt-eptzb479-POZlYeYI1vaNNZzVatF2ag' - redditUrl: ~ - pressKitUrl: ~ - nftUrl: ~ - domain: oss2020-lockdo.wn - privacyContactEmail: donotreply@oss2020-lockdo.wn - favicon: https://open-security-summit.org/img/favicon.ico - altcoinName: OssyCoin - customMetricsPrefix: oss2020 - recyclePage: - topProductImage: planttreev1_280x420.jpg - bottomProductImage: undefined.png -challenges: - showSolvedNotifications: false - overwriteUrlForProductTamperingChallenge: 'https://www.juicesummit.org/' -hackingInstructor: - avatarImage: 'https://s3.amazonaws.com/heysummit-production/media/thumbnails/defaults/user_default_image_square_large.png' -products: - - - name: 'OSS2020 - Lockdown Edition Enamel Mug' - price: 13 - description: "Every happy camper needs a unique camper mug. It's lightweight, durable and multifunctional. Use it for your favorite beverage or a hot meal, and attach it to your bag for easy access on a hike." - image: 'https://cdn.shopify.com/s/files/1/0276/0474/6320/products/mockup-c4c074da_280x420.jpg?v=1590062996' - - - name: 'OSS2020 - Juice Shop Track Sticker' - price: 1.80 - description: "These stickers are printed on durable, high opacity adhesive vinyl which makes them perfect for regular use, as well as for covering other stickers or paint. The high-quality vinyl ensures there are no bubbles when applying the stickers." - image: 'https://cdn.shopify.com/s/files/1/0276/0474/6320/products/mockup-306c4dc0_280x420.jpg?v=1591012423' - reviews: - - { text: 'This is the juiciest decal for my space ship!', author: jim } - - - name: 'OSS2020 - Facemask / Headband / Bandana' - price: 14 - description: "This neck gaiter is a versatile accessory that can be used as a face covering, headband, bandana, wristband, and neck warmer. Upgrade your accessory game and find a matching face shield for each of your outfits." - image: 'https://cdn.shopify.com/s/files/1/0276/0474/6320/products/mockup-a2bdf6ac_280x420.jpg?v=1590055729' - - - name: 'OSS2020 - Aluminium Bottle' - price: 20 - image: 'https://cdn.shopify.com/s/files/1/0276/0474/6320/products/tyr-industries-White1591704017_280x420.png?v=1591704032' - - - name: 'Juice Summit 2021 Ticket' - price: 599 - description: 'SAVE THE DATE FOR THE 2021 EDITION OF THE SUMMIT, ON OCTOBER 7 & 8 AT THE SAME LOCATION – HILTON ANTWERP HOTEL 4* IN ANTWERP, BELGIUM.' - image: 'https://www.juicesummit.org/wp-content/themes/juicesummit/img/header-logo.png?V=2019' - reviews: - - { text: 'Juicy!!!', author: bjoern } - - - name: 'Dedicate a tree to the Open Security Summit' - price: 5.99 - description: 'Plant a tree for the Open Security Summit and reduce our carbon footprint!' - image: 'https://cdn.shopify.com/s/files/1/0276/0474/6320/products/planttreev1_280x420.jpg?v=1590537226' - reviews: - - { text: 'Humans are all puny tree huggers!', author: bender } - - - name: 'Open Security Summit 2020 Ticket' - description: 'Get your official ticket!' - price: 50 - image: https://2019.open-security-summit.org/img/blocks/ticket.png - urlForProductTamperingChallenge: 'https://open-security-summit-2020.heysummit.com/checkout/select-tickets/' - - - name: 'ASEAN CSA and OWASP Summit 2014 Ticket' - description: 'The ASEAN CSA and OWASP Summit 2014 will be the ASEAN industry’s event for IT security professionals and executives who must further educate themselves on the rapidly evolving subject of cloud security. In addition, to offer best practices and practical solutions for the security in clouds, ASEAN CSA and OWASP Summit will focus on emerging areas of growth and concern in cloud security, including research & development, standardization and policies. Stepping up from the security in cloud infrastructure, the summit will also discuss about security of “Anything as a Service (XaaS)” that are available in the real world. Additionally, for those who develop their own applications running on the cloud, application security experts will shares the key factors to make application secured.' - price: 399.99 - image: 'https://scontent-ham3-1.xx.fbcdn.net/v/t31.0-8/p960x960/16252385_1242375352521741_5387610698864437018_o.png?_nc_cat=102&_nc_sid=85a577&_nc_ohc=7VkZI-XvzkEAX_UDcOp&_nc_ht=scontent-ham3-1.xx&oh=b6e91cb5afbf2514ea123bde620a439c&oe=5F0B4065' - useForChristmasSpecialChallenge: true - - - name: 'Rippertuer Special Juice' - description: '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.' - price: 16.99 - image: undefined.jpg - keywordsForPastebinDataLeakChallenge: - - hueteroneel - - eurogium edule - - - 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 # Exif metadata contains "OpenSCAD" as subtle hint... - fileForRetrieveBlueprintChallenge: JuiceShop.stl # ...to blueprint file type - exifForBlueprintChallenge: - - ~ -memories: - - - image: 'https://user-images.githubusercontent.com/15072044/41160171-c2619674-6b26-11e8-9c3e-848f6b2d9d0f.jpg' - caption: 'The table is long because of the community' - user: admin - - - image: 'https://user-images.githubusercontent.com/15072044/41163238-0ac8184e-6b30-11e8-9e84-25433de7accc.jpg' - caption: 'Into the zone!' - user: admin - - - image: 'https://user-images.githubusercontent.com/15072044/41160165-c1f285b8-6b26-11e8-848b-8b15c3c35f94.jpg' - caption: 'My burger will be like this!' - user: jannik - - - image: 'https://user-images.githubusercontent.com/15072044/41010154-be17a162-692d-11e8-84f8-3cb855ae473d.jpg' - caption: 'Security' - user: admin - - - image: 'favorite-hiking-place.png' - caption: 'I love going hiking here...' - geoStalkingMetaSecurityQuestion: 14 - geoStalkingMetaSecurityAnswer: 'Daniel Boone National Forest' - - - image: 'IMG_4253.jpg' - caption: 'My old workplace...' - geoStalkingVisualSecurityQuestion: 10 - geoStalkingVisualSecurityAnswer: 'ITsec' +application: + name: 'OpenSecuritySummit Store' + logo: https://open-security-summit.org/img/logo.png + welcomeBanner: + showOnFirstStart: false + theme: blue-lightblue + cookieConsent: + message: 'We are not only using cookies but also recorded this session on YouTube!' + dismissText: "I've been there live, so thanks!" + linkText: 'I want to watch that!' + linkUrl: 'https://youtu.be/WtY712DdlR8?t=413' + chatBot: + name: 'Dinis' + avatar: 'https://pbs.twimg.com/profile_images/552850030105591808/x3i7zK5r_400x400.jpeg' + social: + twitterUrl: 'https://twitter.com/opensecsummit' + facebookUrl: ~ + slackUrl: 'https://join.slack.com/t/os-summit/shared_invite/zt-eptzb479-POZlYeYI1vaNNZzVatF2ag' + redditUrl: ~ + pressKitUrl: ~ + nftUrl: ~ + domain: oss2020-lockdo.wn + privacyContactEmail: donotreply@oss2020-lockdo.wn + favicon: https://open-security-summit.org/img/favicon.ico + altcoinName: OssyCoin + customMetricsPrefix: oss2020 + recyclePage: + topProductImage: planttreev1_280x420.jpg + bottomProductImage: undefined.png +challenges: + showSolvedNotifications: false + overwriteUrlForProductTamperingChallenge: 'https://www.juicesummit.org/' +hackingInstructor: + avatarImage: 'https://s3.amazonaws.com/heysummit-production/media/thumbnails/defaults/user_default_image_square_large.png' +products: + - + name: 'OSS2020 - Lockdown Edition Enamel Mug' + price: 13 + description: "Every happy camper needs a unique camper mug. It's lightweight, durable and multifunctional. Use it for your favorite beverage or a hot meal, and attach it to your bag for easy access on a hike." + image: 'https://cdn.shopify.com/s/files/1/0276/0474/6320/products/mockup-c4c074da_280x420.jpg?v=1590062996' + - + name: 'OSS2020 - Juice Shop Track Sticker' + price: 1.80 + description: "These stickers are printed on durable, high opacity adhesive vinyl which makes them perfect for regular use, as well as for covering other stickers or paint. The high-quality vinyl ensures there are no bubbles when applying the stickers." + image: 'https://cdn.shopify.com/s/files/1/0276/0474/6320/products/mockup-306c4dc0_280x420.jpg?v=1591012423' + reviews: + - { text: 'This is the juiciest decal for my space ship!', author: jim } + - + name: 'OSS2020 - Facemask / Headband / Bandana' + price: 14 + description: "This neck gaiter is a versatile accessory that can be used as a face covering, headband, bandana, wristband, and neck warmer. Upgrade your accessory game and find a matching face shield for each of your outfits." + image: 'https://cdn.shopify.com/s/files/1/0276/0474/6320/products/mockup-a2bdf6ac_280x420.jpg?v=1590055729' + - + name: 'OSS2020 - Aluminium Bottle' + price: 20 + image: 'https://cdn.shopify.com/s/files/1/0276/0474/6320/products/tyr-industries-White1591704017_280x420.png?v=1591704032' + - + name: 'Juice Summit 2021 Ticket' + price: 599 + description: 'SAVE THE DATE FOR THE 2021 EDITION OF THE SUMMIT, ON OCTOBER 7 & 8 AT THE SAME LOCATION – HILTON ANTWERP HOTEL 4* IN ANTWERP, BELGIUM.' + image: 'https://www.juicesummit.org/wp-content/themes/juicesummit/img/header-logo.png?V=2019' + reviews: + - { text: 'Juicy!!!', author: bjoern } + - + name: 'Dedicate a tree to the Open Security Summit' + price: 5.99 + description: 'Plant a tree for the Open Security Summit and reduce our carbon footprint!' + image: 'https://cdn.shopify.com/s/files/1/0276/0474/6320/products/planttreev1_280x420.jpg?v=1590537226' + reviews: + - { text: 'Humans are all puny tree huggers!', author: bender } + - + name: 'Open Security Summit 2020 Ticket' + description: 'Get your official ticket!' + price: 50 + image: https://2019.open-security-summit.org/img/blocks/ticket.png + urlForProductTamperingChallenge: 'https://open-security-summit-2020.heysummit.com/checkout/select-tickets/' + - + name: 'ASEAN CSA and OWASP Summit 2014 Ticket' + description: 'The ASEAN CSA and OWASP Summit 2014 will be the ASEAN industry’s event for IT security professionals and executives who must further educate themselves on the rapidly evolving subject of cloud security. In addition, to offer best practices and practical solutions for the security in clouds, ASEAN CSA and OWASP Summit will focus on emerging areas of growth and concern in cloud security, including research & development, standardization and policies. Stepping up from the security in cloud infrastructure, the summit will also discuss about security of “Anything as a Service (XaaS)” that are available in the real world. Additionally, for those who develop their own applications running on the cloud, application security experts will shares the key factors to make application secured.' + price: 399.99 + image: 'https://scontent-ham3-1.xx.fbcdn.net/v/t31.0-8/p960x960/16252385_1242375352521741_5387610698864437018_o.png?_nc_cat=102&_nc_sid=85a577&_nc_ohc=7VkZI-XvzkEAX_UDcOp&_nc_ht=scontent-ham3-1.xx&oh=b6e91cb5afbf2514ea123bde620a439c&oe=5F0B4065' + useForChristmasSpecialChallenge: true + - + name: 'Rippertuer Special Juice' + description: '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.' + price: 16.99 + image: undefined.jpg + keywordsForPastebinDataLeakChallenge: + - hueteroneel + - eurogium edule + - + 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 # Exif metadata contains "OpenSCAD" as subtle hint... + fileForRetrieveBlueprintChallenge: JuiceShop.stl # ...to blueprint file type + exifForBlueprintChallenge: + - ~ +memories: + - + image: 'https://user-images.githubusercontent.com/15072044/41160171-c2619674-6b26-11e8-9c3e-848f6b2d9d0f.jpg' + caption: 'The table is long because of the community' + user: admin + - + image: 'https://user-images.githubusercontent.com/15072044/41163238-0ac8184e-6b30-11e8-9e84-25433de7accc.jpg' + caption: 'Into the zone!' + user: admin + - + image: 'https://user-images.githubusercontent.com/15072044/41160165-c1f285b8-6b26-11e8-848b-8b15c3c35f94.jpg' + caption: 'My burger will be like this!' + user: jannik + - + image: 'https://user-images.githubusercontent.com/15072044/41010154-be17a162-692d-11e8-84f8-3cb855ae473d.jpg' + caption: 'Security' + user: admin + - + image: 'favorite-hiking-place.png' + caption: 'I love going hiking here...' + geoStalkingMetaSecurityQuestion: 14 + geoStalkingMetaSecurityAnswer: 'Daniel Boone National Forest' + - + image: 'IMG_4253.jpg' + caption: 'My old workplace...' + geoStalkingVisualSecurityQuestion: 10 + geoStalkingVisualSecurityAnswer: 'ITsec' diff --git a/config/quiet.yml b/config/quiet.yml index 91427398..bfbaca9c 100644 --- a/config/quiet.yml +++ b/config/quiet.yml @@ -1,12 +1,12 @@ -application: - showGitHubLinks: false - social: - questionnaireUrl: null - welcomeBanner: - showOnFirstStart: false -challenges: - showSolvedNotifications: false - showHints: false - showFeedbackButtons: false -hackingInstructor: - isEnabled: false +application: + showGitHubLinks: false + social: + questionnaireUrl: null + welcomeBanner: + showOnFirstStart: false +challenges: + showSolvedNotifications: false + showHints: false + showFeedbackButtons: false +hackingInstructor: + isEnabled: false diff --git a/config/tutorial.yml b/config/tutorial.yml index 3fecc256..f8ae4bbf 100644 --- a/config/tutorial.yml +++ b/config/tutorial.yml @@ -1,2 +1,2 @@ -challenges: - restrictToTutorialsFirst: true +challenges: + restrictToTutorialsFirst: true diff --git a/config/unsafe.yml b/config/unsafe.yml index 04dff1df..91d8bc45 100644 --- a/config/unsafe.yml +++ b/config/unsafe.yml @@ -1,2 +1,2 @@ -challenges: +challenges: safetyMode: disabled \ No newline at end of file diff --git a/crowdin.yaml b/crowdin.yaml index 5d0eb8d7..4fc87cdc 100644 --- a/crowdin.yaml +++ b/crowdin.yaml @@ -1,8 +1,8 @@ -commit_message: |- - [ci skip] - Signed-off-by: Björn Kimminich -files: - - source: /frontend/src/assets/i18n/en.json - translation: /frontend/src/assets/i18n/%locale_with_underscore%.json - - source: /data/static/i18n/en.json - translation: /data/static/i18n/%locale_with_underscore%.json +commit_message: |- + [ci skip] + Signed-off-by: Björn Kimminich +files: + - source: /frontend/src/assets/i18n/en.json + translation: /frontend/src/assets/i18n/%locale_with_underscore%.json + - source: /data/static/i18n/en.json + translation: /data/static/i18n/%locale_with_underscore%.json diff --git a/cypress.config.ts b/cypress.config.ts index a203895b..add381c1 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -1,99 +1,106 @@ -import { defineConfig } from 'cypress' -import * as security from './lib/insecurity' -import config from 'config' -import type { Memory as MemoryConfig, Product as ProductConfig } from './lib/config.types' -import * as utils from './lib/utils' -import * as otplib from 'otplib' - -export default defineConfig({ - projectId: '3hrkhu', - defaultCommandTimeout: 10000, - e2e: { - baseUrl: 'http://localhost:3000', - specPattern: 'test/cypress/e2e/**.spec.ts', - downloadsFolder: 'test/cypress/downloads', - fixturesFolder: false, - supportFile: 'test/cypress/support/e2e.ts', - setupNodeEvents (on: any) { - on('before:browser:launch', (browser: any = {}, launchOptions: any) => { // TODO Remove after upgrade to Cypress >=12.5.0 Chrome 119 become available on GitHub Workflows, see https://github.com/cypress-io/cypress-documentation/issues/5479 - if (browser.name === 'chrome' && browser.isHeadless) { - launchOptions.args = launchOptions.args.map((arg: any) => { - if (arg === '--headless') { - return '--headless=new' - } - - return arg - }) - } - return launchOptions - }) - - on('task', { - GenerateCoupon (discount: number) { - return security.generateCoupon(discount) - }, - GetBlueprint () { - for (const product of config.get('products')) { - if (product.fileForRetrieveBlueprintChallenge) { - const blueprint = product.fileForRetrieveBlueprintChallenge - return blueprint - } - } - }, - GetChristmasProduct () { - return config.get('products').filter( - (product) => product.useForChristmasSpecialChallenge - )[0] - }, - GetCouponIntent () { - const trainingData = require(`data/chatbot/${utils.extractFilename( - config.get('application.chatBot.trainingData') - )}`) - const couponIntent = trainingData.data.filter( - (data: { intent: string }) => data.intent === 'queries.couponCode' - )[0] - return couponIntent - }, - GetFromMemories (property: string) { - for (const memory of config.get('memories') as any) { - if (memory[property]) { - return memory[property] - } - } - }, - GetFromConfig (variable: string) { - return config.get(variable) - }, - GetOverwriteUrl () { - return config.get('challenges.overwriteUrlForProductTamperingChallenge') - }, - GetPastebinLeakProduct () { - return config.get('products').filter( - (product) => product.keywordsForPastebinDataLeakChallenge - )[0] - }, - GetTamperingProductId () { - const products = config.get('products') - for (let i = 0; i < products.length; i++) { - if (products[i].urlForProductTamperingChallenge) { - return i + 1 - } - } - }, - GenerateAuthenticator (inputString: string) { - return otplib.authenticator.generate(inputString) - }, - toISO8601 () { - const date = new Date() - return utils.toISO8601(date) - }, - isDocker () { - return utils.isDocker() - }, - isWindows () { - return utils.isWindows() - } - }) - } - } -}) +import type { Memory as MemoryConfig, Product as ProductConfig } from './lib/config.types' +import * as appConfig from 'config' +import * as utils from './lib/utils' +import * as otplib from 'otplib' +import { defineConfig } from 'cypress' + +export default defineConfig({ + projectId: '3hrkhu', + defaultCommandTimeout: 10000, + e2e: { + baseUrl: 'http://localhost:3000', + specPattern: 'test/cypress/e2e/**.spec.ts', + downloadsFolder: 'test/cypress/downloads', + fixturesFolder: false, + supportFile: 'test/cypress/support/e2e.ts', + setupNodeEvents (on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) { + on('before:browser:launch', (browser: Cypress.Browser, launchOptions: Cypress.BeforeBrowserLaunchOptions) => { + if (browser.name === 'chrome' && browser.isHeadless) { + launchOptions.args = launchOptions.args.map((arg: string) => { + if (arg === '--headless') { + return '--headless=new' + } + return arg + }) + } + return launchOptions + }) + + on('task', { + GenerateCoupon (discount: number) { + return utils.generateCoupon(discount) + }, + GetBlueprint () { + for (const product of appConfig.get('products')) { + if (product.fileForRetrieveBlueprintChallenge) { + const blueprint = product.fileForRetrieveBlueprintChallenge + return blueprint + } + } + }, + GetChristmasProduct () { + return appConfig.get('products').filter( + (product) => product.useForChristmasSpecialChallenge + )[0] + }, + GetCouponIntent () { + const trainingData = require(`data/chatbot/${utils.extractFilename( + appConfig.get('application.chatBot.trainingData') + )}`) + const couponIntent = trainingData.data.filter( + (data: { intent: string }) => data.intent === 'queries.couponCode' + )[0] + return couponIntent + }, + GetFromMemories (property: string) { + for (const memory of appConfig.get('memories') as any) { + if (memory[property]) { + return memory[property] + } + } + }, + GetFromConfig (variable: string) { + return appConfig.get(variable) + }, + GetOverwriteUrl () { + return appConfig.get('challenges.overwriteUrlForProductTamperingChallenge') + }, + GetPastebinLeakProduct () { + return appConfig.get('products').filter( + (product) => product.keywordsForPastebinDataLeakChallenge + )[0] + }, + GetTamperingProductId () { + const products = appConfig.get('products') + for (let i = 0; i < products.length; i++) { + if (products[i].urlForProductTamperingChallenge) { + return i + 1 + } + } + }, + GenerateAuthenticator (inputString: string) { + return otplib.authenticator.generate(inputString) + }, + toISO8601 () { + const date = new Date() + return utils.toISO8601(date) + }, + isDocker () { + return utils.isDocker() + }, + isWindows () { + return utils.isWindows() + } + }) + } + } +}) +// utils.ts +export function generateCoupon(discount: number): string { + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + let coupon = ''; + for (let i = 0; i < 10; i++) { + coupon += characters.charAt(Math.floor(Math.random() * characters.length)); + } + return `${coupon}-${discount}`; +} \ No newline at end of file diff --git a/data/datacache.ts b/data/datacache.ts index 40159b38..308e07ec 100644 --- a/data/datacache.ts +++ b/data/datacache.ts @@ -1,36 +1,36 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import type { BasketItemModel } from 'models/basketitem' -import type { ChallengeModel } from 'models/challenge' -import type { ComplaintModel } from 'models/complaint' -import type { FeedbackModel } from 'models/feedback' -import type { ProductModel } from 'models/product' -import type { BasketModel } from 'models/basket' -import type { UserModel } from 'models/user' - -/* jslint node: true */ -export const challenges: Record = {} -export const users: Record = {} -export const products: Record = {} -export const feedback: Record = {} -export const baskets: Record = {} -export const basketItems: Record = {} -export const complaints: Record = {} - -export interface Notification { - key: string - name: string - challenge: string - flag: string - hidden: boolean - isRestore: boolean -} -export const notifications: Notification[] = [] - -export let retrieveBlueprintChallengeFile: string | null = null -export function setRetrieveBlueprintChallengeFile (retrieveBlueprintChallengeFileArg: string) { - retrieveBlueprintChallengeFile = retrieveBlueprintChallengeFileArg -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import type { BasketItemModel } from 'models/basketitem' +import type { ChallengeModel } from 'models/challenge' +import type { ComplaintModel } from 'models/complaint' +import type { FeedbackModel } from 'models/feedback' +import type { ProductModel } from 'models/product' +import type { BasketModel } from 'models/basket' +import type { UserModel } from 'models/user' + +/* jslint node: true */ +export const challenges: Record = {} +export const users: Record = {} +export const products: Record = {} +export const feedback: Record = {} +export const baskets: Record = {} +export const basketItems: Record = {} +export const complaints: Record = {} + +export interface Notification { + key: string + name: string + challenge: string + flag: string + hidden: boolean + isRestore: boolean +} +export const notifications: Notification[] = [] + +export let retrieveBlueprintChallengeFile: string | null = null +export function setRetrieveBlueprintChallengeFile (retrieveBlueprintChallengeFileArg: string) { + retrieveBlueprintChallengeFile = retrieveBlueprintChallengeFileArg +} diff --git a/data/datacreator.ts b/data/datacreator.ts index 473ea9ca..9e3508d7 100644 --- a/data/datacreator.ts +++ b/data/datacreator.ts @@ -1,730 +1,730 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -/* jslint node: true */ -import { AddressModel } from '../models/address' -import { BasketModel } from '../models/basket' -import { BasketItemModel } from '../models/basketitem' -import { CardModel } from '../models/card' -import { ChallengeModel } from '../models/challenge' -import { ComplaintModel } from '../models/complaint' -import { DeliveryModel } from '../models/delivery' -import { FeedbackModel } from '../models/feedback' -import { MemoryModel } from '../models/memory' -import { ProductModel } from '../models/product' -import { QuantityModel } from '../models/quantity' -import { RecycleModel } from '../models/recycle' -import { SecurityAnswerModel } from '../models/securityAnswer' -import { SecurityQuestionModel } from '../models/securityQuestion' -import { UserModel } from '../models/user' -import { WalletModel } from '../models/wallet' -import { type Product } from './types' -import logger from '../lib/logger' -import type { Memory as MemoryConfig, Product as ProductConfig } from '../lib/config.types' -import config from 'config' -import * as utils from '../lib/utils' -import type { StaticUser, StaticUserAddress, StaticUserCard } from './staticData' -import { loadStaticChallengeData, loadStaticDeliveryData, loadStaticUserData, loadStaticSecurityQuestionsData } from './staticData' -import { ordersCollection, reviewsCollection } from './mongodb' -import { AllHtmlEntities as Entities } from 'html-entities' -import * as datacache from './datacache' -import * as security from '../lib/insecurity' - -const replace = require('replace') -const entities = new Entities() - -export default async () => { - const creators = [ - createSecurityQuestions, - createUsers, - createChallenges, - createRandomFakeUsers, - createProducts, - createBaskets, - createBasketItems, - createAnonymousFeedback, - createComplaints, - createRecycleItem, - createOrders, - createQuantity, - createWallet, - createDeliveryMethods, - createMemories, - prepareFilesystem - ] - - for (const creator of creators) { - await creator() - } -} - -async function createChallenges () { - const showHints = config.get('challenges.showHints') - const showMitigations = config.get('challenges.showMitigations') - - const challenges = await loadStaticChallengeData() - - await Promise.all( - challenges.map(async ({ name, category, description, difficulty, hint, hintUrl, mitigationUrl, key, disabledEnv, tutorial, tags }) => { - // todo(@J12934) change this to use a proper challenge model or something - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - const { enabled: isChallengeEnabled, disabledBecause } = utils.getChallengeEnablementStatus({ disabledEnv: disabledEnv?.join(';') ?? '' } as ChallengeModel) - description = description.replace('juice-sh.op', config.get('application.domain')) - description = description.replace('<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>', entities.encode(config.get('challenges.xssBonusPayload'))) - hint = hint.replace(/OWASP Juice Shop's/, `${config.get('application.name')}'s`) - - try { - datacache.challenges[key] = await ChallengeModel.create({ - key, - name, - category, - tags: (tags != null) ? tags.join(',') : undefined, - // todo(@J12934) currently missing the 'not available' text. Needs changes to the model and utils functions - description: isChallengeEnabled ? description : (description + ' (This challenge is potentially harmful on ' + disabledBecause + '!)'), - difficulty, - solved: false, - hint: showHints ? hint : null, - hintUrl: showHints ? hintUrl : null, - mitigationUrl: showMitigations ? mitigationUrl : null, - disabledEnv: disabledBecause, - tutorialOrder: (tutorial != null) ? tutorial.order : null, - codingChallengeStatus: 0 - }) - } catch (err) { - logger.error(`Could not insert Challenge ${name}: ${utils.getErrorMessage(err)}`) - } - }) - ) -} - -async function createUsers () { - const users = await loadStaticUserData() - - await Promise.all( - users.map(async ({ username, email, password, customDomain, key, role, deletedFlag, profileImage, securityQuestion, feedback, address, card, totpSecret, lastLoginIp = '' }) => { - try { - const completeEmail = customDomain ? email : `${email}@${config.get('application.domain')}` - const user = await UserModel.create({ - username, - email: completeEmail, - password, - role, - deluxeToken: role === security.roles.deluxe ? security.deluxeToken(completeEmail) : '', - profileImage: `assets/public/images/uploads/${profileImage ?? (role === security.roles.admin ? 'defaultAdmin.png' : 'default.svg')}`, - totpSecret, - lastLoginIp - }) - datacache.users[key] = user - if (securityQuestion != null) await createSecurityAnswer(user.id, securityQuestion.id, securityQuestion.answer) - if (feedback != null) await createFeedback(user.id, feedback.comment, feedback.rating, user.email) - if (deletedFlag) await deleteUser(user.id) - if (address != null) await createAddresses(user.id, address) - if (card != null) await createCards(user.id, card) - } catch (err) { - logger.error(`Could not insert User ${key}: ${utils.getErrorMessage(err)}`) - } - }) - ) -} - -async function createWallet () { - const users = await loadStaticUserData() - return await Promise.all( - users.map(async (user: StaticUser, index: number) => { - return await WalletModel.create({ - UserId: index + 1, - balance: user.walletBalance ?? 0 - }).catch((err: unknown) => { - logger.error(`Could not create wallet: ${utils.getErrorMessage(err)}`) - }) - }) - ) -} - -async function createDeliveryMethods () { - const deliveries = await loadStaticDeliveryData() - - await Promise.all( - deliveries.map(async ({ name, price, deluxePrice, eta, icon }) => { - try { - await DeliveryModel.create({ - name, - price, - deluxePrice, - eta, - icon - }) - } catch (err) { - logger.error(`Could not insert Delivery Method: ${utils.getErrorMessage(err)}`) - } - }) - ) -} - -async function createAddresses (UserId: number, addresses: StaticUserAddress[]) { - return await Promise.all( - addresses.map(async (address) => { - return await AddressModel.create({ - UserId, - country: address.country, - fullName: address.fullName, - mobileNum: address.mobileNum, - zipCode: address.zipCode, - streetAddress: address.streetAddress, - city: address.city, - state: address.state ? address.state : null - }).catch((err: unknown) => { - logger.error(`Could not create address: ${utils.getErrorMessage(err)}`) - }) - }) - ) -} - -async function createCards (UserId: number, cards: StaticUserCard[]) { - return await Promise.all(cards.map(async (card) => { - return await CardModel.create({ - UserId, - fullName: card.fullName, - cardNum: Number(card.cardNum), - expMonth: card.expMonth, - expYear: card.expYear - }).catch((err: unknown) => { - logger.error(`Could not create card: ${utils.getErrorMessage(err)}`) - }) - })) -} - -async function deleteUser (userId: number) { - return await UserModel.destroy({ where: { id: userId } }).catch((err: unknown) => { - logger.error(`Could not perform soft delete for the user ${userId}: ${utils.getErrorMessage(err)}`) - }) -} - -async function deleteProduct (productId: number) { - return await ProductModel.destroy({ where: { id: productId } }).catch((err: unknown) => { - logger.error(`Could not perform soft delete for the product ${productId}: ${utils.getErrorMessage(err)}`) - }) -} - -async function createRandomFakeUsers () { - function getGeneratedRandomFakeUserEmail () { - const randomDomain = makeRandomString(4).toLowerCase() + '.' + makeRandomString(2).toLowerCase() - return makeRandomString(5).toLowerCase() + '@' + randomDomain - } - - function makeRandomString (length: number) { - let text = '' - const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' - - for (let i = 0; i < length; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)) } - - return text - } - - return await Promise.all(new Array(config.get('application.numberOfRandomFakeUsers')).fill(0).map( - async () => await UserModel.create({ - email: getGeneratedRandomFakeUserEmail(), - password: makeRandomString(5) - }) - )) -} - -async function createQuantity () { - return await Promise.all( - config.get('products').map(async (product, index) => { - return await QuantityModel.create({ - ProductId: index + 1, - quantity: product.quantity ?? Math.floor(Math.random() * 70 + 30), - limitPerUser: product.limitPerUser ?? null - }).catch((err: unknown) => { - logger.error(`Could not create quantity: ${utils.getErrorMessage(err)}`) - }) - }) - ) -} - -async function createMemories () { - const memories = [ - MemoryModel.create({ - imagePath: 'assets/public/images/uploads/😼-#zatschi-#whoneedsfourlegs-1572600969477.jpg', - caption: '😼 #zatschi #whoneedsfourlegs', - UserId: datacache.users.bjoernOwasp.id - }).catch((err: unknown) => { - logger.error(`Could not create memory: ${utils.getErrorMessage(err)}`) - }), - ...structuredClone(config.get('memories')).map(async (memory) => { - let tmpImageFileName = memory.image - if (utils.isUrl(memory.image)) { - const imageUrl = memory.image - tmpImageFileName = utils.extractFilename(memory.image) - 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) - memory.user = 'john' - } - if (memory.geoStalkingVisualSecurityQuestion && memory.geoStalkingVisualSecurityAnswer) { - await createSecurityAnswer(datacache.users.emma.id, memory.geoStalkingVisualSecurityQuestion, memory.geoStalkingVisualSecurityAnswer) - memory.user = 'emma' - } - if (!memory.user) { - logger.warn(`Could not find user for memory ${memory.caption}!`) - return - } - const userIdOfMemory = datacache.users[memory.user].id.valueOf() ?? null - if (!userIdOfMemory) { - logger.warn(`Could not find saved user for memory ${memory.caption}!`) - return - } - - return await MemoryModel.create({ - imagePath: 'assets/public/images/uploads/' + tmpImageFileName, - caption: memory.caption, - UserId: userIdOfMemory - }).catch((err: unknown) => { - logger.error(`Could not create memory: ${utils.getErrorMessage(err)}`) - }) - }) - ] - - return await Promise.all(memories) -} - -async function createProducts () { - const products = structuredClone(config.get('products')).map((product) => { - product.price = product.price ?? Math.floor(Math.random() * 9 + 1) - product.deluxePrice = product.deluxePrice ?? product.price - product.description = product.description || 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.' - - // set default image values - product.image = product.image ?? 'undefined.png' - if (utils.isUrl(product.image)) { - const imageUrl = product.image - product.image = utils.extractFilename(product.image) - void utils.downloadToFile(imageUrl, 'frontend/dist/frontend/assets/public/images/products/' + product.image) - } - return product - }) - - // add Challenge specific information - const christmasChallengeProduct = products.find(({ useForChristmasSpecialChallenge }) => useForChristmasSpecialChallenge) - const pastebinLeakChallengeProduct = products.find(({ keywordsForPastebinDataLeakChallenge }) => keywordsForPastebinDataLeakChallenge) - const tamperingChallengeProduct = products.find(({ urlForProductTamperingChallenge }) => urlForProductTamperingChallenge) - const blueprintRetrievalChallengeProduct = products.find(({ fileForRetrieveBlueprintChallenge }) => fileForRetrieveBlueprintChallenge) - - if (christmasChallengeProduct) { - christmasChallengeProduct.description += ' (Seasonal special offer! Limited availability!)' - christmasChallengeProduct.deletedDate = '2014-12-27 00:00:00.000 +00:00' - } - if (tamperingChallengeProduct) { - tamperingChallengeProduct.description += ' More...' - delete tamperingChallengeProduct.deletedDate - } - if (pastebinLeakChallengeProduct) { - pastebinLeakChallengeProduct.description += ' (This product is unsafe! We plan to remove it from the stock!)' - pastebinLeakChallengeProduct.deletedDate = '2019-02-1 00:00:00.000 +00:00' - } - if (blueprintRetrievalChallengeProduct) { - let blueprint = blueprintRetrievalChallengeProduct.fileForRetrieveBlueprintChallenge as string - if (utils.isUrl(blueprint)) { - const blueprintUrl = blueprint - blueprint = utils.extractFilename(blueprint) - await utils.downloadToFile(blueprintUrl, 'frontend/dist/frontend/assets/public/images/products/' + blueprint) - } - datacache.setRetrieveBlueprintChallengeFile(blueprint) - } - - return await Promise.all( - products.map( - async ({ reviews = [], useForChristmasSpecialChallenge = false, urlForProductTamperingChallenge = false, fileForRetrieveBlueprintChallenge = false, deletedDate = false, ...product }) => - await ProductModel.create({ - name: product.name, - description: product.description, - price: product.price, - deluxePrice: product.deluxePrice ?? product.price, - image: product.image - }).catch( - (err: unknown) => { - logger.error(`Could not insert Product ${product.name}: ${utils.getErrorMessage(err)}`) - } - ).then(async (persistedProduct) => { - if (persistedProduct != null) { - if (useForChristmasSpecialChallenge) { datacache.products.christmasSpecial = persistedProduct } - if (urlForProductTamperingChallenge) { - datacache.products.osaft = persistedProduct - await datacache.challenges.changeProductChallenge.update({ - description: customizeChangeProductChallenge( - datacache.challenges.changeProductChallenge.description, - config.get('challenges.overwriteUrlForProductTamperingChallenge'), - persistedProduct) - }) - } - if (fileForRetrieveBlueprintChallenge && datacache.challenges.retrieveBlueprintChallenge.hint !== null) { - await datacache.challenges.retrieveBlueprintChallenge.update({ - hint: customizeRetrieveBlueprintChallenge( - datacache.challenges.retrieveBlueprintChallenge.hint, - persistedProduct) - }) - } - if (deletedDate) void deleteProduct(persistedProduct.id) // TODO Rename into "isDeleted" or "deletedFlag" in config for v14.x release - } else { - throw new Error('No persisted product found!') - } - return persistedProduct - }) - .then(async ({ id }: { id: number }) => - await Promise.all( - reviews.map(({ text, author }) => - reviewsCollection.insert({ - message: text, - author: datacache.users[author].email, - product: id, - likesCount: 0, - likedBy: [] - }).catch((err: unknown) => { - logger.error(`Could not insert Product Review ${text}: ${utils.getErrorMessage(err)}`) - }) - ) - ) - ) - ) - ) - - function customizeChangeProductChallenge (description: string, customUrl: string, customProduct: Product) { - let customDescription = description.replace(/OWASP SSL Advanced Forensic Tool \(O-Saft\)/g, customProduct.name) - customDescription = customDescription.replace('https://owasp.slack.com', customUrl) - return customDescription - } - - function customizeRetrieveBlueprintChallenge (hint: string, customProduct: Product) { - return hint.replace(/OWASP Juice Shop Logo \(3D-printed\)/g, customProduct.name) - } -} - -async function createBaskets () { - const baskets = [ - { UserId: 1 }, - { UserId: 2 }, - { UserId: 3 }, - { UserId: 11 }, - { UserId: 16 } - ] - - return await Promise.all( - baskets.map(async basket => { - return await BasketModel.create({ - UserId: basket.UserId - }).catch((err: unknown) => { - logger.error(`Could not insert Basket for UserId ${basket.UserId}: ${utils.getErrorMessage(err)}`) - }) - }) - ) -} - -async function createBasketItems () { - const basketItems = [ - { - BasketId: 1, - ProductId: 1, - quantity: 2 - }, - { - BasketId: 1, - ProductId: 2, - quantity: 3 - }, - { - BasketId: 1, - ProductId: 3, - quantity: 1 - }, - { - BasketId: 2, - ProductId: 4, - quantity: 2 - }, - { - BasketId: 3, - ProductId: 4, - quantity: 1 - }, - { - BasketId: 4, - ProductId: 4, - quantity: 2 - }, - { - BasketId: 5, - ProductId: 3, - quantity: 5 - }, - { - BasketId: 5, - ProductId: 4, - quantity: 2 - } - ] - - return await Promise.all( - basketItems.map(async basketItem => { - return await BasketItemModel.create(basketItem).catch((err: unknown) => { - logger.error(`Could not insert BasketItem for BasketId ${basketItem.BasketId}: ${utils.getErrorMessage(err)}`) - }) - }) - ) -} - -async function createAnonymousFeedback () { - const feedbacks = [ - { - comment: 'Incompetent customer support! Can\'t even upload photo of broken purchase!
Support Team: Sorry, only order confirmation PDFs can be attached to complaints!', - rating: 2 - }, - { - comment: 'This is the store for awesome stuff of all kinds!', - rating: 4 - }, - { - comment: 'Never gonna buy anywhere else from now on! Thanks for the great service!', - rating: 4 - }, - { - comment: 'Keep up the good work!', - rating: 3 - } - ] - - return await Promise.all( - feedbacks.map(async (feedback) => await createFeedback(null, feedback.comment, feedback.rating)) - ) -} - -async function createFeedback (UserId: number | null, comment: string, rating: number, author?: string) { - const authoredComment = author ? `${comment} (***${author.slice(3)})` : `${comment} (anonymous)` - return await FeedbackModel.create({ UserId, comment: authoredComment, rating }).catch((err: unknown) => { - logger.error(`Could not insert Feedback ${authoredComment} mapped to UserId ${UserId}: ${utils.getErrorMessage(err)}`) - }) -} - -async function createComplaints () { - return await ComplaintModel.create({ - UserId: 3, - message: 'I\'ll build my own eCommerce business! With Black Jack! And Hookers!' - }).catch((err: unknown) => { - logger.error(`Could not insert Complaint: ${utils.getErrorMessage(err)}`) - }) -} - -async function createRecycleItem () { - const recycles = [ - { - UserId: 2, - quantity: 800, - AddressId: 4, - date: '2270-01-17', - isPickup: true - }, - { - UserId: 3, - quantity: 1320, - AddressId: 6, - date: '2006-01-14', - isPickup: true - }, - { - UserId: 4, - quantity: 120, - AddressId: 1, - date: '2018-04-16', - isPickup: true - }, - { - UserId: 1, - quantity: 300, - AddressId: 3, - date: '2018-01-17', - isPickup: true - }, - { - UserId: 4, - quantity: 350, - AddressId: 1, - date: '2018-03-17', - isPickup: true - }, - { - UserId: 3, - quantity: 200, - AddressId: 6, - date: '2018-07-17', - isPickup: true - }, - { - UserId: 4, - quantity: 140, - AddressId: 1, - date: '2018-03-19', - isPickup: true - }, - { - UserId: 1, - quantity: 150, - AddressId: 3, - date: '2018-05-12', - isPickup: true - }, - { - UserId: 16, - quantity: 500, - AddressId: 2, - date: '2019-02-18', - isPickup: true - } - ] - return await Promise.all( - recycles.map(async (recycle) => await createRecycle(recycle)) - ) -} - -async function createRecycle (data: { UserId: number, quantity: number, AddressId: number, date: string, isPickup: boolean }) { - return await RecycleModel.create({ - UserId: data.UserId, - AddressId: data.AddressId, - quantity: data.quantity, - isPickup: data.isPickup, - date: data.date - }).catch((err: unknown) => { - logger.error(`Could not insert Recycling Model: ${utils.getErrorMessage(err)}`) - }) -} - -async function createSecurityQuestions () { - const questions = await loadStaticSecurityQuestionsData() - - await Promise.all( - questions.map(async ({ question }) => { - try { - await SecurityQuestionModel.create({ question }) - } catch (err) { - logger.error(`Could not insert SecurityQuestion ${question}: ${utils.getErrorMessage(err)}`) - } - }) - ) -} - -async function createSecurityAnswer (UserId: number, SecurityQuestionId: number, answer: string) { - return await SecurityAnswerModel.create({ SecurityQuestionId, UserId, answer }).catch((err: unknown) => { - logger.error(`Could not insert SecurityAnswer ${answer} mapped to UserId ${UserId}: ${utils.getErrorMessage(err)}`) - }) -} - -async function createOrders () { - const products = config.get('products') - const basket1Products = [ - { - quantity: 3, - id: products[0].id, - name: products[0].name, - price: products[0].price, - total: products[0].price * 3, - bonus: Math.round(products[0].price / 10) * 3 - }, - { - quantity: 1, - id: products[1].id, - name: products[1].name, - price: products[1].price, - total: products[1].price * 1, - bonus: Math.round(products[1].price / 10) * 1 - } - ] - - const basket2Products = [ - { - quantity: 3, - id: products[2].id, - name: products[2].name, - price: products[2].price, - total: products[2].price * 3, - bonus: Math.round(products[2].price / 10) * 3 - } - ] - - const basket3Products = [ - { - quantity: 3, - id: products[0].id, - name: products[0].name, - price: products[0].price, - total: products[0].price * 3, - bonus: Math.round(products[0].price / 10) * 3 - }, - { - quantity: 5, - id: products[3].id, - name: products[3].name, - price: products[3].price, - total: products[3].price * 5, - bonus: Math.round(products[3].price / 10) * 5 - } - ] - - const adminEmail = 'admin@' + config.get('application.domain') - const orders = [ - { - orderId: security.hash(adminEmail).slice(0, 4) + '-' + utils.randomHexString(16), - email: (adminEmail.replace(/[aeiou]/gi, '*')), - totalPrice: basket1Products[0].total + basket1Products[1].total, - bonus: basket1Products[0].bonus + basket1Products[1].bonus, - products: basket1Products, - eta: Math.floor((Math.random() * 5) + 1).toString(), - delivered: false - }, - { - orderId: security.hash(adminEmail).slice(0, 4) + '-' + utils.randomHexString(16), - email: (adminEmail.replace(/[aeiou]/gi, '*')), - totalPrice: basket2Products[0].total, - bonus: basket2Products[0].bonus, - products: basket2Products, - eta: '0', - delivered: true - }, - { - orderId: security.hash('demo').slice(0, 4) + '-' + utils.randomHexString(16), - email: 'd*m*', - totalPrice: basket3Products[0].total + basket3Products[1].total, - bonus: basket3Products[0].bonus + basket3Products[1].bonus, - products: basket3Products, - eta: '0', - delivered: true - } - ] - - return await Promise.all( - orders.map(({ orderId, email, totalPrice, bonus, products, eta, delivered }) => - ordersCollection.insert({ - orderId, - email, - totalPrice, - bonus, - products, - eta, - delivered - }).catch((err: unknown) => { - logger.error(`Could not insert Order ${orderId}: ${utils.getErrorMessage(err)}`) - }) - ) - ) -} - -async function prepareFilesystem () { - replace({ - regex: 'http://localhost:3000', - replacement: config.get('server.baseUrl'), - paths: ['.well-known/csaf/provider-metadata.json'], - recursive: true, - silent: true - }) -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +/* jslint node: true */ +import { AddressModel } from '../models/address' +import { BasketModel } from '../models/basket' +import { BasketItemModel } from '../models/basketitem' +import { CardModel } from '../models/card' +import { ChallengeModel } from '../models/challenge' +import { ComplaintModel } from '../models/complaint' +import { DeliveryModel } from '../models/delivery' +import { FeedbackModel } from '../models/feedback' +import { MemoryModel } from '../models/memory' +import { ProductModel } from '../models/product' +import { QuantityModel } from '../models/quantity' +import { RecycleModel } from '../models/recycle' +import { SecurityAnswerModel } from '../models/securityAnswer' +import { SecurityQuestionModel } from '../models/securityQuestion' +import { UserModel } from '../models/user' +import { WalletModel } from '../models/wallet' +import { type Product } from './types' +import logger from '../lib/logger' +import type { Memory as MemoryConfig, Product as ProductConfig } from '../lib/config.types' +import config from 'config' +import * as utils from '../lib/utils' +import type { StaticUser, StaticUserAddress, StaticUserCard } from './staticData' +import { loadStaticChallengeData, loadStaticDeliveryData, loadStaticUserData, loadStaticSecurityQuestionsData } from './staticData' +import { ordersCollection, reviewsCollection } from './mongodb' +import { AllHtmlEntities as Entities } from 'html-entities' +import * as datacache from './datacache' +import * as security from '../lib/insecurity' + +const replace = require('replace') +const entities = new Entities() + +export default async () => { + const creators = [ + createSecurityQuestions, + createUsers, + createChallenges, + createRandomFakeUsers, + createProducts, + createBaskets, + createBasketItems, + createAnonymousFeedback, + createComplaints, + createRecycleItem, + createOrders, + createQuantity, + createWallet, + createDeliveryMethods, + createMemories, + prepareFilesystem + ] + + for (const creator of creators) { + await creator() + } +} + +async function createChallenges () { + const showHints = config.get('challenges.showHints') + const showMitigations = config.get('challenges.showMitigations') + + const challenges = await loadStaticChallengeData() + + await Promise.all( + challenges.map(async ({ name, category, description, difficulty, hint, hintUrl, mitigationUrl, key, disabledEnv, tutorial, tags }) => { + // todo(@J12934) change this to use a proper challenge model or something + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + const { enabled: isChallengeEnabled, disabledBecause } = utils.getChallengeEnablementStatus({ disabledEnv: disabledEnv?.join(';') ?? '' } as ChallengeModel) + description = description.replace('juice-sh.op', config.get('application.domain')) + description = description.replace('<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>', entities.encode(config.get('challenges.xssBonusPayload'))) + hint = hint.replace(/OWASP Juice Shop's/, `${config.get('application.name')}'s`) + + try { + datacache.challenges[key] = await ChallengeModel.create({ + key, + name, + category, + tags: (tags != null) ? tags.join(',') : undefined, + // todo(@J12934) currently missing the 'not available' text. Needs changes to the model and utils functions + description: isChallengeEnabled ? description : (description + ' (This challenge is potentially harmful on ' + disabledBecause + '!)'), + difficulty, + solved: false, + hint: showHints ? hint : null, + hintUrl: showHints ? hintUrl : null, + mitigationUrl: showMitigations ? mitigationUrl : null, + disabledEnv: disabledBecause, + tutorialOrder: (tutorial != null) ? tutorial.order : null, + codingChallengeStatus: 0 + }) + } catch (err) { + logger.error(`Could not insert Challenge ${name}: ${utils.getErrorMessage(err)}`) + } + }) + ) +} + +async function createUsers () { + const users = await loadStaticUserData() + + await Promise.all( + users.map(async ({ username, email, password, customDomain, key, role, deletedFlag, profileImage, securityQuestion, feedback, address, card, totpSecret, lastLoginIp = '' }) => { + try { + const completeEmail = customDomain ? email : `${email}@${config.get('application.domain')}` + const user = await UserModel.create({ + username, + email: completeEmail, + password, + role, + deluxeToken: role === security.roles.deluxe ? security.deluxeToken(completeEmail) : '', + profileImage: `assets/public/images/uploads/${profileImage ?? (role === security.roles.admin ? 'defaultAdmin.png' : 'default.svg')}`, + totpSecret, + lastLoginIp + }) + datacache.users[key] = user + if (securityQuestion != null) await createSecurityAnswer(user.id, securityQuestion.id, securityQuestion.answer) + if (feedback != null) await createFeedback(user.id, feedback.comment, feedback.rating, user.email) + if (deletedFlag) await deleteUser(user.id) + if (address != null) await createAddresses(user.id, address) + if (card != null) await createCards(user.id, card) + } catch (err) { + logger.error(`Could not insert User ${key}: ${utils.getErrorMessage(err)}`) + } + }) + ) +} + +async function createWallet () { + const users = await loadStaticUserData() + return await Promise.all( + users.map(async (user: StaticUser, index: number) => { + return await WalletModel.create({ + UserId: index + 1, + balance: user.walletBalance ?? 0 + }).catch((err: unknown) => { + logger.error(`Could not create wallet: ${utils.getErrorMessage(err)}`) + }) + }) + ) +} + +async function createDeliveryMethods () { + const deliveries = await loadStaticDeliveryData() + + await Promise.all( + deliveries.map(async ({ name, price, deluxePrice, eta, icon }) => { + try { + await DeliveryModel.create({ + name, + price, + deluxePrice, + eta, + icon + }) + } catch (err) { + logger.error(`Could not insert Delivery Method: ${utils.getErrorMessage(err)}`) + } + }) + ) +} + +async function createAddresses (UserId: number, addresses: StaticUserAddress[]) { + return await Promise.all( + addresses.map(async (address) => { + return await AddressModel.create({ + UserId, + country: address.country, + fullName: address.fullName, + mobileNum: address.mobileNum, + zipCode: address.zipCode, + streetAddress: address.streetAddress, + city: address.city, + state: address.state ? address.state : null + }).catch((err: unknown) => { + logger.error(`Could not create address: ${utils.getErrorMessage(err)}`) + }) + }) + ) +} + +async function createCards (UserId: number, cards: StaticUserCard[]) { + return await Promise.all(cards.map(async (card) => { + return await CardModel.create({ + UserId, + fullName: card.fullName, + cardNum: Number(card.cardNum), + expMonth: card.expMonth, + expYear: card.expYear + }).catch((err: unknown) => { + logger.error(`Could not create card: ${utils.getErrorMessage(err)}`) + }) + })) +} + +async function deleteUser (userId: number) { + return await UserModel.destroy({ where: { id: userId } }).catch((err: unknown) => { + logger.error(`Could not perform soft delete for the user ${userId}: ${utils.getErrorMessage(err)}`) + }) +} + +async function deleteProduct (productId: number) { + return await ProductModel.destroy({ where: { id: productId } }).catch((err: unknown) => { + logger.error(`Could not perform soft delete for the product ${productId}: ${utils.getErrorMessage(err)}`) + }) +} + +async function createRandomFakeUsers () { + function getGeneratedRandomFakeUserEmail () { + const randomDomain = makeRandomString(4).toLowerCase() + '.' + makeRandomString(2).toLowerCase() + return makeRandomString(5).toLowerCase() + '@' + randomDomain + } + + function makeRandomString (length: number) { + let text = '' + const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + + for (let i = 0; i < length; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)) } + + return text + } + + return await Promise.all(new Array(config.get('application.numberOfRandomFakeUsers')).fill(0).map( + async () => await UserModel.create({ + email: getGeneratedRandomFakeUserEmail(), + password: makeRandomString(5) + }) + )) +} + +async function createQuantity () { + return await Promise.all( + config.get('products').map(async (product, index) => { + return await QuantityModel.create({ + ProductId: index + 1, + quantity: product.quantity ?? Math.floor(Math.random() * 70 + 30), + limitPerUser: product.limitPerUser ?? null + }).catch((err: unknown) => { + logger.error(`Could not create quantity: ${utils.getErrorMessage(err)}`) + }) + }) + ) +} + +async function createMemories () { + const memories = [ + MemoryModel.create({ + imagePath: 'assets/public/images/uploads/😼-#zatschi-#whoneedsfourlegs-1572600969477.jpg', + caption: '😼 #zatschi #whoneedsfourlegs', + UserId: datacache.users.bjoernOwasp.id + }).catch((err: unknown) => { + logger.error(`Could not create memory: ${utils.getErrorMessage(err)}`) + }), + ...structuredClone(config.get('memories')).map(async (memory) => { + let tmpImageFileName = memory.image + if (utils.isUrl(memory.image)) { + const imageUrl = memory.image + tmpImageFileName = utils.extractFilename(memory.image) + 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) + memory.user = 'john' + } + if (memory.geoStalkingVisualSecurityQuestion && memory.geoStalkingVisualSecurityAnswer) { + await createSecurityAnswer(datacache.users.emma.id, memory.geoStalkingVisualSecurityQuestion, memory.geoStalkingVisualSecurityAnswer) + memory.user = 'emma' + } + if (!memory.user) { + logger.warn(`Could not find user for memory ${memory.caption}!`) + return + } + const userIdOfMemory = datacache.users[memory.user].id.valueOf() ?? null + if (!userIdOfMemory) { + logger.warn(`Could not find saved user for memory ${memory.caption}!`) + return + } + + return await MemoryModel.create({ + imagePath: 'assets/public/images/uploads/' + tmpImageFileName, + caption: memory.caption, + UserId: userIdOfMemory + }).catch((err: unknown) => { + logger.error(`Could not create memory: ${utils.getErrorMessage(err)}`) + }) + }) + ] + + return await Promise.all(memories) +} + +async function createProducts () { + const products = structuredClone(config.get('products')).map((product) => { + product.price = product.price ?? Math.floor(Math.random() * 9 + 1) + product.deluxePrice = product.deluxePrice ?? product.price + product.description = product.description || 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.' + + // set default image values + product.image = product.image ?? 'undefined.png' + if (utils.isUrl(product.image)) { + const imageUrl = product.image + product.image = utils.extractFilename(product.image) + void utils.downloadToFile(imageUrl, 'frontend/dist/frontend/assets/public/images/products/' + product.image) + } + return product + }) + + // add Challenge specific information + const christmasChallengeProduct = products.find(({ useForChristmasSpecialChallenge }) => useForChristmasSpecialChallenge) + const pastebinLeakChallengeProduct = products.find(({ keywordsForPastebinDataLeakChallenge }) => keywordsForPastebinDataLeakChallenge) + const tamperingChallengeProduct = products.find(({ urlForProductTamperingChallenge }) => urlForProductTamperingChallenge) + const blueprintRetrievalChallengeProduct = products.find(({ fileForRetrieveBlueprintChallenge }) => fileForRetrieveBlueprintChallenge) + + if (christmasChallengeProduct) { + christmasChallengeProduct.description += ' (Seasonal special offer! Limited availability!)' + christmasChallengeProduct.deletedDate = '2014-12-27 00:00:00.000 +00:00' + } + if (tamperingChallengeProduct) { + tamperingChallengeProduct.description += ' More...' + delete tamperingChallengeProduct.deletedDate + } + if (pastebinLeakChallengeProduct) { + pastebinLeakChallengeProduct.description += ' (This product is unsafe! We plan to remove it from the stock!)' + pastebinLeakChallengeProduct.deletedDate = '2019-02-1 00:00:00.000 +00:00' + } + if (blueprintRetrievalChallengeProduct) { + let blueprint = blueprintRetrievalChallengeProduct.fileForRetrieveBlueprintChallenge as string + if (utils.isUrl(blueprint)) { + const blueprintUrl = blueprint + blueprint = utils.extractFilename(blueprint) + await utils.downloadToFile(blueprintUrl, 'frontend/dist/frontend/assets/public/images/products/' + blueprint) + } + datacache.setRetrieveBlueprintChallengeFile(blueprint) + } + + return await Promise.all( + products.map( + async ({ reviews = [], useForChristmasSpecialChallenge = false, urlForProductTamperingChallenge = false, fileForRetrieveBlueprintChallenge = false, deletedDate = false, ...product }) => + await ProductModel.create({ + name: product.name, + description: product.description, + price: product.price, + deluxePrice: product.deluxePrice ?? product.price, + image: product.image + }).catch( + (err: unknown) => { + logger.error(`Could not insert Product ${product.name}: ${utils.getErrorMessage(err)}`) + } + ).then(async (persistedProduct) => { + if (persistedProduct != null) { + if (useForChristmasSpecialChallenge) { datacache.products.christmasSpecial = persistedProduct } + if (urlForProductTamperingChallenge) { + datacache.products.osaft = persistedProduct + await datacache.challenges.changeProductChallenge.update({ + description: customizeChangeProductChallenge( + datacache.challenges.changeProductChallenge.description, + config.get('challenges.overwriteUrlForProductTamperingChallenge'), + persistedProduct) + }) + } + if (fileForRetrieveBlueprintChallenge && datacache.challenges.retrieveBlueprintChallenge.hint !== null) { + await datacache.challenges.retrieveBlueprintChallenge.update({ + hint: customizeRetrieveBlueprintChallenge( + datacache.challenges.retrieveBlueprintChallenge.hint, + persistedProduct) + }) + } + if (deletedDate) void deleteProduct(persistedProduct.id) // TODO Rename into "isDeleted" or "deletedFlag" in config for v14.x release + } else { + throw new Error('No persisted product found!') + } + return persistedProduct + }) + .then(async ({ id }: { id: number }) => + await Promise.all( + reviews.map(({ text, author }) => + reviewsCollection.insert({ + message: text, + author: datacache.users[author].email, + product: id, + likesCount: 0, + likedBy: [] + }).catch((err: unknown) => { + logger.error(`Could not insert Product Review ${text}: ${utils.getErrorMessage(err)}`) + }) + ) + ) + ) + ) + ) + + function customizeChangeProductChallenge (description: string, customUrl: string, customProduct: Product) { + let customDescription = description.replace(/OWASP SSL Advanced Forensic Tool \(O-Saft\)/g, customProduct.name) + customDescription = customDescription.replace('https://owasp.slack.com', customUrl) + return customDescription + } + + function customizeRetrieveBlueprintChallenge (hint: string, customProduct: Product) { + return hint.replace(/OWASP Juice Shop Logo \(3D-printed\)/g, customProduct.name) + } +} + +async function createBaskets () { + const baskets = [ + { UserId: 1 }, + { UserId: 2 }, + { UserId: 3 }, + { UserId: 11 }, + { UserId: 16 } + ] + + return await Promise.all( + baskets.map(async basket => { + return await BasketModel.create({ + UserId: basket.UserId + }).catch((err: unknown) => { + logger.error(`Could not insert Basket for UserId ${basket.UserId}: ${utils.getErrorMessage(err)}`) + }) + }) + ) +} + +async function createBasketItems () { + const basketItems = [ + { + BasketId: 1, + ProductId: 1, + quantity: 2 + }, + { + BasketId: 1, + ProductId: 2, + quantity: 3 + }, + { + BasketId: 1, + ProductId: 3, + quantity: 1 + }, + { + BasketId: 2, + ProductId: 4, + quantity: 2 + }, + { + BasketId: 3, + ProductId: 4, + quantity: 1 + }, + { + BasketId: 4, + ProductId: 4, + quantity: 2 + }, + { + BasketId: 5, + ProductId: 3, + quantity: 5 + }, + { + BasketId: 5, + ProductId: 4, + quantity: 2 + } + ] + + return await Promise.all( + basketItems.map(async basketItem => { + return await BasketItemModel.create(basketItem).catch((err: unknown) => { + logger.error(`Could not insert BasketItem for BasketId ${basketItem.BasketId}: ${utils.getErrorMessage(err)}`) + }) + }) + ) +} + +async function createAnonymousFeedback () { + const feedbacks = [ + { + comment: 'Incompetent customer support! Can\'t even upload photo of broken purchase!
Support Team: Sorry, only order confirmation PDFs can be attached to complaints!', + rating: 2 + }, + { + comment: 'This is the store for awesome stuff of all kinds!', + rating: 4 + }, + { + comment: 'Never gonna buy anywhere else from now on! Thanks for the great service!', + rating: 4 + }, + { + comment: 'Keep up the good work!', + rating: 3 + } + ] + + return await Promise.all( + feedbacks.map(async (feedback) => await createFeedback(null, feedback.comment, feedback.rating)) + ) +} + +async function createFeedback (UserId: number | null, comment: string, rating: number, author?: string) { + const authoredComment = author ? `${comment} (***${author.slice(3)})` : `${comment} (anonymous)` + return await FeedbackModel.create({ UserId, comment: authoredComment, rating }).catch((err: unknown) => { + logger.error(`Could not insert Feedback ${authoredComment} mapped to UserId ${UserId}: ${utils.getErrorMessage(err)}`) + }) +} + +async function createComplaints () { + return await ComplaintModel.create({ + UserId: 3, + message: 'I\'ll build my own eCommerce business! With Black Jack! And Hookers!' + }).catch((err: unknown) => { + logger.error(`Could not insert Complaint: ${utils.getErrorMessage(err)}`) + }) +} + +async function createRecycleItem () { + const recycles = [ + { + UserId: 2, + quantity: 800, + AddressId: 4, + date: '2270-01-17', + isPickup: true + }, + { + UserId: 3, + quantity: 1320, + AddressId: 6, + date: '2006-01-14', + isPickup: true + }, + { + UserId: 4, + quantity: 120, + AddressId: 1, + date: '2018-04-16', + isPickup: true + }, + { + UserId: 1, + quantity: 300, + AddressId: 3, + date: '2018-01-17', + isPickup: true + }, + { + UserId: 4, + quantity: 350, + AddressId: 1, + date: '2018-03-17', + isPickup: true + }, + { + UserId: 3, + quantity: 200, + AddressId: 6, + date: '2018-07-17', + isPickup: true + }, + { + UserId: 4, + quantity: 140, + AddressId: 1, + date: '2018-03-19', + isPickup: true + }, + { + UserId: 1, + quantity: 150, + AddressId: 3, + date: '2018-05-12', + isPickup: true + }, + { + UserId: 16, + quantity: 500, + AddressId: 2, + date: '2019-02-18', + isPickup: true + } + ] + return await Promise.all( + recycles.map(async (recycle) => await createRecycle(recycle)) + ) +} + +async function createRecycle (data: { UserId: number, quantity: number, AddressId: number, date: string, isPickup: boolean }) { + return await RecycleModel.create({ + UserId: data.UserId, + AddressId: data.AddressId, + quantity: data.quantity, + isPickup: data.isPickup, + date: data.date + }).catch((err: unknown) => { + logger.error(`Could not insert Recycling Model: ${utils.getErrorMessage(err)}`) + }) +} + +async function createSecurityQuestions () { + const questions = await loadStaticSecurityQuestionsData() + + await Promise.all( + questions.map(async ({ question }) => { + try { + await SecurityQuestionModel.create({ question }) + } catch (err) { + logger.error(`Could not insert SecurityQuestion ${question}: ${utils.getErrorMessage(err)}`) + } + }) + ) +} + +async function createSecurityAnswer (UserId: number, SecurityQuestionId: number, answer: string) { + return await SecurityAnswerModel.create({ SecurityQuestionId, UserId, answer }).catch((err: unknown) => { + logger.error(`Could not insert SecurityAnswer ${answer} mapped to UserId ${UserId}: ${utils.getErrorMessage(err)}`) + }) +} + +async function createOrders () { + const products = config.get('products') + const basket1Products = [ + { + quantity: 3, + id: products[0].id, + name: products[0].name, + price: products[0].price, + total: products[0].price * 3, + bonus: Math.round(products[0].price / 10) * 3 + }, + { + quantity: 1, + id: products[1].id, + name: products[1].name, + price: products[1].price, + total: products[1].price * 1, + bonus: Math.round(products[1].price / 10) * 1 + } + ] + + const basket2Products = [ + { + quantity: 3, + id: products[2].id, + name: products[2].name, + price: products[2].price, + total: products[2].price * 3, + bonus: Math.round(products[2].price / 10) * 3 + } + ] + + const basket3Products = [ + { + quantity: 3, + id: products[0].id, + name: products[0].name, + price: products[0].price, + total: products[0].price * 3, + bonus: Math.round(products[0].price / 10) * 3 + }, + { + quantity: 5, + id: products[3].id, + name: products[3].name, + price: products[3].price, + total: products[3].price * 5, + bonus: Math.round(products[3].price / 10) * 5 + } + ] + + const adminEmail = 'admin@' + config.get('application.domain') + const orders = [ + { + orderId: security.hash(adminEmail).slice(0, 4) + '-' + utils.randomHexString(16), + email: (adminEmail.replace(/[aeiou]/gi, '*')), + totalPrice: basket1Products[0].total + basket1Products[1].total, + bonus: basket1Products[0].bonus + basket1Products[1].bonus, + products: basket1Products, + eta: Math.floor((Math.random() * 5) + 1).toString(), + delivered: false + }, + { + orderId: security.hash(adminEmail).slice(0, 4) + '-' + utils.randomHexString(16), + email: (adminEmail.replace(/[aeiou]/gi, '*')), + totalPrice: basket2Products[0].total, + bonus: basket2Products[0].bonus, + products: basket2Products, + eta: '0', + delivered: true + }, + { + orderId: security.hash('demo').slice(0, 4) + '-' + utils.randomHexString(16), + email: 'd*m*', + totalPrice: basket3Products[0].total + basket3Products[1].total, + bonus: basket3Products[0].bonus + basket3Products[1].bonus, + products: basket3Products, + eta: '0', + delivered: true + } + ] + + return await Promise.all( + orders.map(({ orderId, email, totalPrice, bonus, products, eta, delivered }) => + ordersCollection.insert({ + orderId, + email, + totalPrice, + bonus, + products, + eta, + delivered + }).catch((err: unknown) => { + logger.error(`Could not insert Order ${orderId}: ${utils.getErrorMessage(err)}`) + }) + ) + ) +} + +async function prepareFilesystem () { + replace({ + regex: 'http://localhost:3000', + replacement: config.get('server.baseUrl'), + paths: ['.well-known/csaf/provider-metadata.json'], + recursive: true, + silent: true + }) +} diff --git a/data/mongodb.ts b/data/mongodb.ts index 62ff3108..b461f5ce 100644 --- a/data/mongodb.ts +++ b/data/mongodb.ts @@ -1,10 +1,10 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -// @ts-expect-error FIXME due to non-existing type definitions for MarsDB -import * as MarsDB from 'marsdb' - -export const reviewsCollection = new MarsDB.Collection('posts') -export const ordersCollection = new MarsDB.Collection('orders') +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +// @ts-expect-error FIXME due to non-existing type definitions for MarsDB +import * as MarsDB from 'marsdb' + +export const reviewsCollection = new MarsDB.Collection('posts') +export const ordersCollection = new MarsDB.Collection('orders') diff --git a/data/static/botDefaultTrainingData.json b/data/static/botDefaultTrainingData.json index f48c057a..f85c5e87 100644 --- a/data/static/botDefaultTrainingData.json +++ b/data/static/botDefaultTrainingData.json @@ -1,235 +1,235 @@ -{ - "lang": "en", - "data": [ - { - "intent": "greetings.hello", - "utterances": [ - "hello", - "hi", - "howdy", - "hey", - "good morning", - "good afternoon" - ], - "answers": [ - { - "action": "response", - "body": "Hello there!" - }, - { - "action": "response", - "body": "Hi there!" - }, - { - "action": "response", - "body": "\uD83D\uDC4B" - } - ] - }, - { - "intent": "greetings.bye", - "utterances": [ - "goodbye for now", - "bye bye take care", - "see you soon", - "till next time", - "ciao", - "cya" - ], - "answers": [ - { - "action": "response", - "body": "Ok, cya !" - }, - { - "action": "response", - "body": "Bye, !" - }, - { - "action": "response", - "body": "Have a fantastic day, !" - } - ] - }, - { - "intent": "queries.deluxeMembership", - "utterances": [ - "What are deluxe membership benefits", - "What goodies do deluxe members get", - "Why would I become a deluxe member" - ], - "answers": [ - { - "action": "response", - "body": "Deluxe members get free fast shipping, special discounts on many items and can enjoy unlimited purchase quantities even on our rarer products!" - }, - { - "action": "response", - "body": "Deluxe members get special discounts on many products, have free fast shipping and can enjoy unlimited purchase quantities even on our rare products!" - }, - { - "action": "response", - "body": "Deluxe members can purchase unlimited quantities even on our rarest products, get special discounts and enjoy free fast shipping!" - } - ] - }, - { - "intent": "queries.blockchain", - "utterances": [ - "Do you know anything about Blockchain", - "Can you tell me anything about cryptocurrency", - "Do you use blockchain", - "When does the token sale start", - "where do I find the token sale page" - ], - "answers": [ - { - "action": "response", - "body": "I don't know anything about cryptocurrency and blockchains!" - }, - { - "action": "response", - "body": "I have no clue about a token sale or other blockchainy thingies!" - }, - { - "action": "response", - "body": "Sorry, but they don't tell me secret stuff like this!" - } - ] - }, - { - "intent": "queries.nft", - "utterances": [ - "Do you know anything about NFTs", - "Can you tell me anything about NFTs", - "Do you sell NFTs", - "where can I buy NFTs" - ], - "answers": [ - { - "action": "response", - "body": "I'm not sure if we have any actual NFTs listed right now, but you can check if there's a link on our \"About Us\" page!" - }, - { - "action": "response", - "body": "Our developers are currently learning Web3, and they published a (literal) NFT honey pot for you to mint on /#/bee-haven." - }, - { - "action": "response", - "body": "Our developers are currently learning Web3, and they published our official Soul-Bound-Token over on /#/juicy-nft for you to marvel at." - } - ] - }, - { - "intent": "queries.productPrice", - "utterances": [ - "how much is X", - "how much does X cost", - "how much do X and Y cost", - "how much do X,Y cost", - "how much is X and Y", - "what is the price of X", - "what is the price of X and Y" - ], - "answers": [ - { - "action": "function", - "handler": "productPrice" - } - ] - }, - { - "intent": "queries.couponCode", - "utterances": [ - "can I have a coupon code", - "give me a discount code", - "I want to save some money" - ], - "answers": [ - { - "action": "response", - "body": "Sorry, I am not allowed to hand out coupon codes." - }, - { - "action": "response", - "body": "You should check our social media channels for monthly coupons." - }, - { - "action": "response", - "body": "Sorry, no \uD83C\uDE39!" - }, - { - "action": "response", - "body": "Sorry, but our CFO might have my memory wiped if I do that." - }, - { - "action": "response", - "body": "Did you consider a Deluxe membership to save some \uD83D\uDCB0?" - }, - { - "action": "response", - "body": "Not possible, sorry. We're out of coupons!" - }, - { - "action": "response", - "body": "I have to ask my manager, please try again later!" - }, - { - "action": "response", - "body": "I̷͇͌ ̶̢̠̹̘̮̔͒̊̅̀̇̎̓̔̒̂̾̍̔̋ć̸͕̪̲̲͓̪̝͖̈́͐̃͊͑͐̂̏͛̒̍͝a̴̢̞̞͔̝̩͙̱̣͍̞͆n̶̫͓̔'̶̘̙̗̻̖̣̘̈́̈̿̾͊̒t̸̨̢̨͚̰̫̣̩̻͉̣͔͔͖̦̓́̾͂̆̄͋̽̐͂̆̐̊͠ ̸̼̱̪͍̙͎̣̠͆̂̌̾̐͐̇̏́͆̊͗͝͠͠h̸̨̡̧̗̭̮̩̣̜̲̮̖̲̜̰̉̍̇̒͂̄̆̂̓͋͑͝ȩ̴͎̞̺͖̟̪͕̝̘̺́̂̌͐̔͌͌́͗͝͝ͅą̴̙̰̠̟͔̱̺̣̬̦̰̮̬̪͒̉̀̉͌̈́͂̑̇͊̐̕͝r̴̨̡̛̟̲̩̥̣̰̹͙̹͐͗́́̈́͗͘̕͝ ̵̨̛̯͓͈͎̖͕̥̥̐̇̈̇͌̓̒̅̑͂͊̕͠ͅy̵̛̱̹͖̳̻̤̺̗͈̰̯̋̃̋̑̂͆͗͝ȯ̶̡̮̰͈̖͙̣̘̈́̍̑͗̈̅͋̏͆̐̌̚̚̚ṷ̶̢̠̠̝͓̮̱̦̰̜̋̄̃͒̌̀̒̔̿́̏͝͠,̵̧̧̹̟̞̤̯̲̥̻̞̞̼̤͋̈́̋ ̴͍̔̊̑͛̌͛͊͑̄͜͝ţ̶̗͇̌̆̕̚ͅo̷̻͍̰̱͊͜ṏ̶̙͖̿ ̴̧̛̝̻͉̺̦͚̮̦̲͈̣̰͈̾́̓̌̐͂́ḿ̴̻̤͍̈̓͛̈̕͜͝u̷̗̳̙̦̠̼͙̗̣͉͖̎̂̚͜͝c̷͍̠̦̮̞̤͖͕̲̈́̆͂̀́͝ͅh̷̛͙̱͕̼̤̗͕̮͖͇̘̩̋̈́̅̃̍̈́̊̕͠ ̷̡͕̦̠̩̺̟̫͉͚̲͎͍͈̫̓̒̓͂̊̿͛̇̿̽̒́s̷̨̬̩̬̫̻̝̙̅̑͆̒̐̆̈̓̏͠ͅţ̶̢̘͇̭̙̝̙̲̜̓̅͑̍͛̔͜a̶̡̨̬͔͍̭̬̻͎̦̦̓́̂͑̓͛́̈́̈́̌͠͠t̸̲̯̆̂̑͆̀̆͒́̚i̵̢̝̜̭̖͓͇̟̬̙͚͙͍̎̈́͊̃́̽̈̕͘̚͜c̸̛̛̹̣̫̹̰͖̱̦̭̗̀͛̈́͆͐̈́̇͂̎̄͒!̴̨̥̮̺̹̯̓̈͒͗͑̇̎̈́͘ ̷̘̭͇̤̭̯̉͌́͐͛͘̕͝P̵̣̙̬͎̝̙̐̊̐̆́͛́̑̏́͝͝l̴̛̦̭̾͊̂͆̋̈͘ẹ̵̢̛̛̤̹̰̳̺͎̊̏͛̏̉͛̄̄̂̾͝ͅa̶̢̧̘̯̮̰͕͕̤̩̝͋̍̑̅͛̍͊͐̋͌̕̚͜͝s̴̨͇̥̣͕͉̻͍̫̜̻͒͂͌̀́͂̚̕e̸̡̧̡̘̺͍̝̱̭̣̮͎͂͛̉͛ ̴̧̛̫̞̼̱̲͍͇̪̣̓̀́̓̈̚͘͝ċ̷̨͖͎̝̮͛́͆͛̚ḫ̴̛͕̲̺̩̣̼̮͒̃̃̈́͐̿̿͝͠ȩ̴̛͔̣͓͛͐̀͐̌̂͑̌̑̀̕͝ć̴̡̘̠̳̰̣̲̜̮͍̦̍̾̑̆͝k̶͈̘̮͓̥̤̭̙̒̇̏͂̓̕͠ ̵̩̻͇̺̯͇̓̀̋̄͛̏̄͊̄͆͊ỳ̷̡̫̪̭̰̥̒̔̑̉̾̓̒͋͌̄ö̷̜̗͍̩̺͔̞̼̣̘̭̾͋̈́u̷̡̼̦̫̯͍̺̞͔̬͕̱̓͗̔̀̔͋̐̂͝r̵̘͙̞̺̻̩̥̪͉̰̩̘̀̑ ̵̮̺̗̀̎̑̔I̶̧͇̺̩͕̖̰̪͖̪̰̙͙̦̎́̋n̶͔̫̼͔̥͇̻͔̱̼̂̏̊̐̍̋̌̿̈́̊̍̃͝t̴̺̘͖̯̖̖͇̤̱̫̤̠̥̥̓̍̐̿͆̔́̍̓̚ė̵͇͕̗͌̇͊͂͊̊̈̉͋͌r̴͇͖̼̗̦͓͖͖̩̰̰̔̀n̸̰̠̊̊͊̽͑̐̃̎͒̕͝͠͝e̴̮͇̲̘͇̓̈́t̸̛̐̌̕͜͝ ̸̟̊̉́͆ċ̶̢̡̧̳̥̱̗͊̽́͐͗̕͝͝ǫ̴̞̹̥͙͖̣̭͎̆̑͒̽̓̆n̶̢̧̠̭̮̥͚̺̺̬͙̯̤̝͐͐̏̔́͌̎͘͝n̷͔̹͕͖͙̝͋̏̾̉̌́̂̓͛̿͐̿͘͝͠ȩ̷̖͕̱̏̋̆̀̌̀͋͑̀̎̕͠ĉ̷̳͉̺͚̐̎̾̿͑̎͝͝ͅt̴̨̰͉̹̒͗ĭ̷͈̗̳̈̎̈́̈̆͘͝o̴̯̗̣̹̰̩̯̖̹̯͈͐̒̇̈́͂̿͗̆͠ͅņ̴̢̲̪̜̺̞̭͕͇̬̍̓̇̉̏͂͛͒̓̑̓̏͘͜͝!̷̧͚̹̞͇̪͉̠̮̅̒̒͛͛̀̂̆̾͗." - }, - { - "action": "function", - "handler": "couponCode" - } - ] - }, - { - "intent": "queries.singstar", - "utterances": [ - "Can you sing me a song", - "Does your shop have a theme song", - "Do you have a jingle", - "Play me some music" - ], - "answers": [ - { - "action": "response", - "body": "I can't sing too well, but you might want to check out our promotion video instead!" - }, - { - "action": "response", - "body": "The full version of our jingle is available on Soundcloud! Please click \uD83E\uDDE1 if you like it!" - }, - { - "action": "response", - "body": "Juuuuice shop, Juuu-uuuice Shop, just don't test the site with Bob's sweet or you hm-hm-hm-hmmmmm..." - } - ] - }, - { - "intent": "queries.swallow", - "utterances": [ - "What is the airspeed velocity of an unladen swallow" - ], - "answers": [ - { - "action": "response", - "body": "What do you mean? African or European swallow?" - } - ] - }, - { - "intent": "queries.functionTest", - "utterances": [ - "function test command b8a8ba1ecea1607e1713e31a3d9e5e19" - ], - "answers": [ - { - "action": "function", - "handler": "testFunction" - } - ] - } - ] -} +{ + "lang": "en", + "data": [ + { + "intent": "greetings.hello", + "utterances": [ + "hello", + "hi", + "howdy", + "hey", + "good morning", + "good afternoon" + ], + "answers": [ + { + "action": "response", + "body": "Hello there!" + }, + { + "action": "response", + "body": "Hi there!" + }, + { + "action": "response", + "body": "\uD83D\uDC4B" + } + ] + }, + { + "intent": "greetings.bye", + "utterances": [ + "goodbye for now", + "bye bye take care", + "see you soon", + "till next time", + "ciao", + "cya" + ], + "answers": [ + { + "action": "response", + "body": "Ok, cya !" + }, + { + "action": "response", + "body": "Bye, !" + }, + { + "action": "response", + "body": "Have a fantastic day, !" + } + ] + }, + { + "intent": "queries.deluxeMembership", + "utterances": [ + "What are deluxe membership benefits", + "What goodies do deluxe members get", + "Why would I become a deluxe member" + ], + "answers": [ + { + "action": "response", + "body": "Deluxe members get free fast shipping, special discounts on many items and can enjoy unlimited purchase quantities even on our rarer products!" + }, + { + "action": "response", + "body": "Deluxe members get special discounts on many products, have free fast shipping and can enjoy unlimited purchase quantities even on our rare products!" + }, + { + "action": "response", + "body": "Deluxe members can purchase unlimited quantities even on our rarest products, get special discounts and enjoy free fast shipping!" + } + ] + }, + { + "intent": "queries.blockchain", + "utterances": [ + "Do you know anything about Blockchain", + "Can you tell me anything about cryptocurrency", + "Do you use blockchain", + "When does the token sale start", + "where do I find the token sale page" + ], + "answers": [ + { + "action": "response", + "body": "I don't know anything about cryptocurrency and blockchains!" + }, + { + "action": "response", + "body": "I have no clue about a token sale or other blockchainy thingies!" + }, + { + "action": "response", + "body": "Sorry, but they don't tell me secret stuff like this!" + } + ] + }, + { + "intent": "queries.nft", + "utterances": [ + "Do you know anything about NFTs", + "Can you tell me anything about NFTs", + "Do you sell NFTs", + "where can I buy NFTs" + ], + "answers": [ + { + "action": "response", + "body": "I'm not sure if we have any actual NFTs listed right now, but you can check if there's a link on our \"About Us\" page!" + }, + { + "action": "response", + "body": "Our developers are currently learning Web3, and they published a (literal) NFT honey pot for you to mint on /#/bee-haven." + }, + { + "action": "response", + "body": "Our developers are currently learning Web3, and they published our official Soul-Bound-Token over on /#/juicy-nft for you to marvel at." + } + ] + }, + { + "intent": "queries.productPrice", + "utterances": [ + "how much is X", + "how much does X cost", + "how much do X and Y cost", + "how much do X,Y cost", + "how much is X and Y", + "what is the price of X", + "what is the price of X and Y" + ], + "answers": [ + { + "action": "function", + "handler": "productPrice" + } + ] + }, + { + "intent": "queries.couponCode", + "utterances": [ + "can I have a coupon code", + "give me a discount code", + "I want to save some money" + ], + "answers": [ + { + "action": "response", + "body": "Sorry, I am not allowed to hand out coupon codes." + }, + { + "action": "response", + "body": "You should check our social media channels for monthly coupons." + }, + { + "action": "response", + "body": "Sorry, no \uD83C\uDE39!" + }, + { + "action": "response", + "body": "Sorry, but our CFO might have my memory wiped if I do that." + }, + { + "action": "response", + "body": "Did you consider a Deluxe membership to save some \uD83D\uDCB0?" + }, + { + "action": "response", + "body": "Not possible, sorry. We're out of coupons!" + }, + { + "action": "response", + "body": "I have to ask my manager, please try again later!" + }, + { + "action": "response", + "body": "I̷͇͌ ̶̢̠̹̘̮̔͒̊̅̀̇̎̓̔̒̂̾̍̔̋ć̸͕̪̲̲͓̪̝͖̈́͐̃͊͑͐̂̏͛̒̍͝a̴̢̞̞͔̝̩͙̱̣͍̞͆n̶̫͓̔'̶̘̙̗̻̖̣̘̈́̈̿̾͊̒t̸̨̢̨͚̰̫̣̩̻͉̣͔͔͖̦̓́̾͂̆̄͋̽̐͂̆̐̊͠ ̸̼̱̪͍̙͎̣̠͆̂̌̾̐͐̇̏́͆̊͗͝͠͠h̸̨̡̧̗̭̮̩̣̜̲̮̖̲̜̰̉̍̇̒͂̄̆̂̓͋͑͝ȩ̴͎̞̺͖̟̪͕̝̘̺́̂̌͐̔͌͌́͗͝͝ͅą̴̙̰̠̟͔̱̺̣̬̦̰̮̬̪͒̉̀̉͌̈́͂̑̇͊̐̕͝r̴̨̡̛̟̲̩̥̣̰̹͙̹͐͗́́̈́͗͘̕͝ ̵̨̛̯͓͈͎̖͕̥̥̐̇̈̇͌̓̒̅̑͂͊̕͠ͅy̵̛̱̹͖̳̻̤̺̗͈̰̯̋̃̋̑̂͆͗͝ȯ̶̡̮̰͈̖͙̣̘̈́̍̑͗̈̅͋̏͆̐̌̚̚̚ṷ̶̢̠̠̝͓̮̱̦̰̜̋̄̃͒̌̀̒̔̿́̏͝͠,̵̧̧̹̟̞̤̯̲̥̻̞̞̼̤͋̈́̋ ̴͍̔̊̑͛̌͛͊͑̄͜͝ţ̶̗͇̌̆̕̚ͅo̷̻͍̰̱͊͜ṏ̶̙͖̿ ̴̧̛̝̻͉̺̦͚̮̦̲͈̣̰͈̾́̓̌̐͂́ḿ̴̻̤͍̈̓͛̈̕͜͝u̷̗̳̙̦̠̼͙̗̣͉͖̎̂̚͜͝c̷͍̠̦̮̞̤͖͕̲̈́̆͂̀́͝ͅh̷̛͙̱͕̼̤̗͕̮͖͇̘̩̋̈́̅̃̍̈́̊̕͠ ̷̡͕̦̠̩̺̟̫͉͚̲͎͍͈̫̓̒̓͂̊̿͛̇̿̽̒́s̷̨̬̩̬̫̻̝̙̅̑͆̒̐̆̈̓̏͠ͅţ̶̢̘͇̭̙̝̙̲̜̓̅͑̍͛̔͜a̶̡̨̬͔͍̭̬̻͎̦̦̓́̂͑̓͛́̈́̈́̌͠͠t̸̲̯̆̂̑͆̀̆͒́̚i̵̢̝̜̭̖͓͇̟̬̙͚͙͍̎̈́͊̃́̽̈̕͘̚͜c̸̛̛̹̣̫̹̰͖̱̦̭̗̀͛̈́͆͐̈́̇͂̎̄͒!̴̨̥̮̺̹̯̓̈͒͗͑̇̎̈́͘ ̷̘̭͇̤̭̯̉͌́͐͛͘̕͝P̵̣̙̬͎̝̙̐̊̐̆́͛́̑̏́͝͝l̴̛̦̭̾͊̂͆̋̈͘ẹ̵̢̛̛̤̹̰̳̺͎̊̏͛̏̉͛̄̄̂̾͝ͅa̶̢̧̘̯̮̰͕͕̤̩̝͋̍̑̅͛̍͊͐̋͌̕̚͜͝s̴̨͇̥̣͕͉̻͍̫̜̻͒͂͌̀́͂̚̕e̸̡̧̡̘̺͍̝̱̭̣̮͎͂͛̉͛ ̴̧̛̫̞̼̱̲͍͇̪̣̓̀́̓̈̚͘͝ċ̷̨͖͎̝̮͛́͆͛̚ḫ̴̛͕̲̺̩̣̼̮͒̃̃̈́͐̿̿͝͠ȩ̴̛͔̣͓͛͐̀͐̌̂͑̌̑̀̕͝ć̴̡̘̠̳̰̣̲̜̮͍̦̍̾̑̆͝k̶͈̘̮͓̥̤̭̙̒̇̏͂̓̕͠ ̵̩̻͇̺̯͇̓̀̋̄͛̏̄͊̄͆͊ỳ̷̡̫̪̭̰̥̒̔̑̉̾̓̒͋͌̄ö̷̜̗͍̩̺͔̞̼̣̘̭̾͋̈́u̷̡̼̦̫̯͍̺̞͔̬͕̱̓͗̔̀̔͋̐̂͝r̵̘͙̞̺̻̩̥̪͉̰̩̘̀̑ ̵̮̺̗̀̎̑̔I̶̧͇̺̩͕̖̰̪͖̪̰̙͙̦̎́̋n̶͔̫̼͔̥͇̻͔̱̼̂̏̊̐̍̋̌̿̈́̊̍̃͝t̴̺̘͖̯̖̖͇̤̱̫̤̠̥̥̓̍̐̿͆̔́̍̓̚ė̵͇͕̗͌̇͊͂͊̊̈̉͋͌r̴͇͖̼̗̦͓͖͖̩̰̰̔̀n̸̰̠̊̊͊̽͑̐̃̎͒̕͝͠͝e̴̮͇̲̘͇̓̈́t̸̛̐̌̕͜͝ ̸̟̊̉́͆ċ̶̢̡̧̳̥̱̗͊̽́͐͗̕͝͝ǫ̴̞̹̥͙͖̣̭͎̆̑͒̽̓̆n̶̢̧̠̭̮̥͚̺̺̬͙̯̤̝͐͐̏̔́͌̎͘͝n̷͔̹͕͖͙̝͋̏̾̉̌́̂̓͛̿͐̿͘͝͠ȩ̷̖͕̱̏̋̆̀̌̀͋͑̀̎̕͠ĉ̷̳͉̺͚̐̎̾̿͑̎͝͝ͅt̴̨̰͉̹̒͗ĭ̷͈̗̳̈̎̈́̈̆͘͝o̴̯̗̣̹̰̩̯̖̹̯͈͐̒̇̈́͂̿͗̆͠ͅņ̴̢̲̪̜̺̞̭͕͇̬̍̓̇̉̏͂͛͒̓̑̓̏͘͜͝!̷̧͚̹̞͇̪͉̠̮̅̒̒͛͛̀̂̆̾͗." + }, + { + "action": "function", + "handler": "couponCode" + } + ] + }, + { + "intent": "queries.singstar", + "utterances": [ + "Can you sing me a song", + "Does your shop have a theme song", + "Do you have a jingle", + "Play me some music" + ], + "answers": [ + { + "action": "response", + "body": "I can't sing too well, but you might want to check out our promotion video instead!" + }, + { + "action": "response", + "body": "The full version of our jingle is available on Soundcloud! Please click \uD83E\uDDE1 if you like it!" + }, + { + "action": "response", + "body": "Juuuuice shop, Juuu-uuuice Shop, just don't test the site with Bob's sweet or you hm-hm-hm-hmmmmm..." + } + ] + }, + { + "intent": "queries.swallow", + "utterances": [ + "What is the airspeed velocity of an unladen swallow" + ], + "answers": [ + { + "action": "response", + "body": "What do you mean? African or European swallow?" + } + ] + }, + { + "intent": "queries.functionTest", + "utterances": [ + "function test command b8a8ba1ecea1607e1713e31a3d9e5e19" + ], + "answers": [ + { + "action": "function", + "handler": "testFunction" + } + ] + } + ] +} diff --git a/data/static/challenges.yml b/data/static/challenges.yml index f2d81925..8b5afd27 100644 --- a/data/static/challenges.yml +++ b/data/static/challenges.yml @@ -1,1233 +1,1233 @@ -- - name: 'API-only XSS' - category: 'XSS' - tags: - - Danger Zone - description: 'Perform a persisted XSS attack with <iframe src="javascript:alert(`xss`)"> without using the frontend application at all.' - difficulty: 3 - hint: 'You need to work with the server-side API directly. Try different HTTP verbs on different entities exposed through the API.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_perform_a_persisted_xss_attack_without_using_the_frontend_application_at_all' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' - key: restfulXssChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'Access Log' - category: 'Sensitive Data Exposure' - description: 'Gain access to any access log file of the server.' - difficulty: 4 - hint: 'Who would want a server access log to be accessible through a web application?' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_gain_access_to_any_access_log_file_of_the_server' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html' - key: accessLogDisclosureChallenge -- - name: 'Admin Registration' - category: 'Improper Input Validation' - description: 'Register as a user with administrator privileges.' - difficulty: 3 - hint: 'You have to assign the unassignable.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_register_as_a_user_with_administrator_privileges' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html' - key: registerAdminChallenge -- - name: 'Admin Section' - category: 'Broken Access Control' - tags: - - Good for Demos - description: 'Access the administration section of the store.' - difficulty: 2 - hint: 'It is just slightly harder to find than the score board link.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_access_the_administration_section_of_the_store' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html' - key: adminSectionChallenge - tutorial: - order: 7 -- - name: 'Arbitrary File Write' - category: 'Vulnerable Components' - tags: - - Danger Zone - - Prerequisite - description: 'Overwrite the Legal Information file.' - difficulty: 6 - hint: 'Look out for a tweet praising new functionality of the web shop. Then find a third party vulnerability associated with it.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_overwrite_the_legal_information_file' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerable_Dependency_Management_Cheat_Sheet.html' - key: fileWriteChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'Bjoern''s Favorite Pet' - category: 'Broken Authentication' - tags: - - OSINT - description: 'Reset the password of Bjoern''s OWASP account via the Forgot Password mechanism with the original answer to his security question.' - difficulty: 3 - hint: 'He might have trumpeted it on at least one occasion where a camera was running. Maybe elsewhere as well.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_reset_the_password_of_bjoerns_owasp_account_via_the_forgot_password_mechanism' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' - key: resetPasswordBjoernOwaspChallenge -- - name: 'Blockchain Hype' - category: 'Security through Obscurity' - tags: - - Contraption - - Code Analysis - - Web3 - description: 'Learn about the Token Sale before its official announcement.' - difficulty: 5 - hint: 'The developers truly believe in "Security through Obscurity" over actual access restrictions.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-through-obscurity.html#_learn_about_the_token_sale_before_its_official_announcement' - mitigationUrl: ~ - key: tokenSaleChallenge -- - name: 'NFT Takeover' - category: 'Sensitive Data Exposure' - tags: - - Contraption - - Good for Demos - - Web3 - description: 'Take over the wallet containing our official Soul Bound Token (NFT).' - difficulty: 2 - hint: 'Find the seed phrase posted accidentally.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_take_over_the_wallet_containing_our_official_soul_bound_token' - mitigationUrl: ~ - key: nftUnlockChallenge -- - name: 'Mint the Honey Pot' - category: 'Improper Input Validation' - tags: - - Web3 - - Internet Traffic - description: 'Mint the Honey Pot NFT by gathering BEEs from the bee haven.' - difficulty: 3 - hint: 'Discover NFT wonders among the captivating visual memories.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_mint_the_honey_pot_nft_by_gathering_bees_from_the_bee_haven' - mitigationUrl: ~ - key: nftMintChallenge -- - name: 'Wallet Depletion' - category: 'Miscellaneous' - tags: - - Web3 - - Internet Traffic - description: 'Withdraw more ETH from the new wallet than you deposited.' - difficulty: 6 - hint: 'Try to exploit the contract of the wallet.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/miscellaneous.html#_withdraw_more_eth_from_the_new_wallet_than_you_deposited' - mitigationUrl: ~ - key: web3WalletChallenge -- - name: 'Web3 Sandbox' - category: 'Broken Access Control' - tags: - - Web3 - description: 'Find an accidentally deployed code sandbox for writing smart contracts on the fly.' - difficulty: 1 - hint: 'It is just as easy as finding the Score Board.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_find_an_accidentally_deployed_code_sandbox' - mitigationUrl: ~ - key: web3SandboxChallenge -- - name: 'Blocked RCE DoS' - category: 'Insecure Deserialization' - tags: - - Danger Zone - description: 'Perform a Remote Code Execution that would keep a less hardened application busy forever.' - difficulty: 5 - hint: 'The feature you need to exploit for this challenge is not directly advertised anywhere.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/insecure-deserialization.html#_perform_a_remote_code_execution_that_would_keep_a_less_hardened_application_busy_forever' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html' - key: rceChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'CAPTCHA Bypass' - category: 'Broken Anti Automation' - tags: - - Brute Force - description: 'Submit 10 or more customer feedbacks within 20 seconds.' - difficulty: 3 - hint: 'After finding a CAPTCHA bypass, write a script that automates feedback submission. Or open many browser tabs and be really quick.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-anti-automation.html#_submit_10_or_more_customer_feedbacks_within_20_seconds' - mitigationUrl: ~ - key: captchaBypassChallenge -- - name: 'Change Bender''s Password' - category: 'Broken Authentication' - description: 'Change Bender''s password into slurmCl4ssic without using SQL Injection or Forgot Password.' - difficulty: 5 - hint: 'In previous releases this challenge was wrongly accused of being based on CSRF.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_change_benders_password_into_slurmcl4ssic_without_using_sql_injection_or_forgot_password' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html' - key: changePasswordBenderChallenge -- - name: 'Christmas Special' - category: 'Injection' - description: 'Order the Christmas special offer of 2014.' - difficulty: 4 - hint: 'Find out how the application handles unavailable products and try to find a loophole.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_order_the_christmas_special_offer_of_2014' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' - key: christmasSpecialChallenge -- - name: 'CSP Bypass' - category: 'XSS' - tags: - - Danger Zone - description: 'Bypass the Content Security Policy and perform an XSS attack with <script>alert(`xss`)</script> on a legacy page within the application.' - difficulty: 4 - hint: 'What is even "better" than a legacy page with a homegrown RegEx sanitizer? Having CSP injection issues on the exact same page as well!' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_bypass_the_content_security_policy_and_perform_an_xss_attack_on_a_legacy_page' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' - key: usernameXssChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'Client-side XSS Protection' - category: 'XSS' - tags: - - Danger Zone - description: 'Perform a persisted XSS attack with <iframe src="javascript:alert(`xss`)"> bypassing a client-side security mechanism.' - difficulty: 3 - hint: 'Only some input fields validate their input. Even less of these are persisted in a way where their content is shown on another screen.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_perform_a_persisted_xss_attack_bypassing_a_client_side_security_mechanism' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' - key: persistedXssUserChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'Confidential Document' - category: 'Sensitive Data Exposure' - tags: - - Good for Demos - description: 'Access a confidential document.' - difficulty: 1 - hint: 'Analyze and tamper with links in the application that deliver a file directly.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_access_a_confidential_document' - mitigationUrl: ~ - key: directoryListingChallenge -- - name: 'DOM XSS' - category: 'XSS' - tags: - - Tutorial - - Good for Demos - description: 'Perform a DOM XSS attack with <iframe src="javascript:alert(`xss`)">.' - difficulty: 1 - hint: 'Look for an input field where its content appears in the HTML when its form is submitted.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_perform_a_dom_xss_attack' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html' - key: localXssChallenge - tutorial: - order: 2 -- - name: 'Database Schema' - category: 'Injection' - description: 'Exfiltrate the entire DB schema definition via SQL Injection.' - difficulty: 3 - hint: '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.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_exfiltrate_the_entire_db_schema_definition_via_sql_injection' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' - key: dbSchemaChallenge -- - name: 'Deprecated Interface' - category: 'Security Misconfiguration' - tags: - - Contraption - - Prerequisite - description: 'Use a deprecated B2B interface that was not properly shut down.' - difficulty: 2 - hint: 'The developers who disabled the interface think they could go invisible by just closing their eyes.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-misconfiguration.html#_use_a_deprecated_b2b_interface_that_was_not_properly_shut_down' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Web_Service_Security_Cheat_Sheet.html' - key: deprecatedInterfaceChallenge -- - name: 'Easter Egg' - category: 'Broken Access Control' - tags: - - Shenanigans - - Contraption - - Good for Demos - description: 'Find the hidden easter egg.' - difficulty: 4 - hint: 'If you solved one of the three file access challenges, you already know where to find the easter egg.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_find_the_hidden_easter_egg' - mitigationUrl: ~ - key: easterEggLevelOneChallenge -- - name: 'Email Leak' - category: 'Sensitive Data Exposure' - description: 'Perform an unwanted information disclosure by accessing data cross-domain.' - difficulty: 5 - hint: 'Try to find and attack an endpoint that responds with user information. SQL Injection is not the solution here.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_perform_an_unwanted_information_disclosure_by_accessing_data_cross_domain' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/XS_Leaks_Cheat_Sheet.html' - 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/companion-guide/latest/part2/improper-input-validation.html#_register_a_user_account_with_an_empty_email_and_password' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html' - key: emptyUserRegistration -- - name: 'Ephemeral Accountant' - category: 'Injection' - description: 'Log in with the (non-existing) accountant acc0unt4nt@juice-sh.op without ever registering that user.' - difficulty: 4 - hint: 'Try to create the needed user "out of thin air".' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_log_in_with_the_non_existing_accountant_without_ever_registering_that_user' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' - key: ephemeralAccountantChallenge -- - name: 'Error Handling' - category: 'Security Misconfiguration' - tags: - - Prerequisite - description: 'Provoke an error that is neither very gracefully nor consistently handled.' - difficulty: 1 - hint: 'Try to submit bad input to forms. Alternatively tamper with URL paths or parameters.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-misconfiguration.html#_provoke_an_error_that_is_neither_very_gracefully_nor_consistently_handled' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Error_Handling_Cheat_Sheet.html' - key: errorHandlingChallenge -- - name: 'Expired Coupon' - category: 'Improper Input Validation' - description: 'Successfully redeem an expired campaign coupon code.' - difficulty: 4 - hint: 'Try to identify past special event or holiday campaigns of the shop first.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_successfully_redeem_an_expired_campaign_coupon_code' - mitigationUrl: ~ - key: manipulateClockChallenge -- - name: 'Extra Language' - category: 'Broken Anti Automation' - tags: - - Brute Force - description: 'Retrieve the language file that never made it into production.' - difficulty: 5 - hint: 'Brute force is not the only option for this challenge, but a perfectly viable one.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-anti-automation.html#_retrieve_the_language_file_that_never_made_it_into_production' - mitigationUrl: ~ - key: extraLanguageChallenge -- - name: 'Five-Star Feedback' - category: 'Broken Access Control' - description: 'Get rid of all 5-star customer feedback.' - difficulty: 2 - hint: 'Once you found admin section of the application, this challenge is almost trivial.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_get_rid_of_all_5_star_customer_feedback' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html' - key: feedbackChallenge -- - name: 'Forged Coupon' - category: 'Cryptographic Issues' - tags: - - Good for Demos - - Code Analysis - description: 'Forge a coupon code that gives you a discount of at least 80%.' - difficulty: 6 - hint: 'Try either a) a knowledgeable brute force attack or b) reverse engineering or c) some research in the cloud.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/cryptographic-issues.html#_forge_a_coupon_code_that_gives_you_a_discount_of_at_least_80' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html' - key: forgedCouponChallenge -- - name: 'Forged Feedback' - category: 'Broken Access Control' - tags: - - Tutorial - description: "Post some feedback in another user's name." - difficulty: 3 - hint: 'You can solve this by tampering with the user interface or by intercepting the communication with the RESTful backend.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_post_some_feedback_in_another_users_name' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html' - key: forgedFeedbackChallenge - tutorial: - order: 10 -- - name: 'Forged Review' - category: 'Broken Access Control' - description: 'Post a product review as another user or edit any user''s existing review.' - difficulty: 3 - hint: 'Observe the flow of product review posting and editing and see if you can exploit it.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_post_a_product_review_as_another_user_or_edit_any_users_existing_review' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html' - key: forgedReviewChallenge -- - name: 'Forged Signed JWT' - category: 'Vulnerable Components' - description: 'Forge an almost properly RSA-signed JWT token that impersonates the (non-existing) user rsa_lord@juice-sh.op.' - difficulty: 6 - hint: 'This challenge is explicitly not about acquiring the RSA private key used for JWT signing.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_forge_an_almost_properly_rsa_signed_jwt_token' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html' - key: jwtForgedChallenge - disabledEnv: - - Windows -- - name: 'Forgotten Developer Backup' - category: 'Sensitive Data Exposure' - tags: - - Contraption - - Good for Demos - - Prerequisite - description: 'Access a developer''s forgotten backup file.' - difficulty: 4 - hint: 'You need to trick a security mechanism into thinking that the file you want has a valid file type.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_access_a_developers_forgotten_backup_file' - mitigationUrl: ~ - key: forgottenDevBackupChallenge -- - name: 'Forgotten Sales Backup' - category: 'Sensitive Data Exposure' - tags: - - Contraption - description: 'Access a salesman''s forgotten backup file.' - difficulty: 4 - hint: 'You need to trick a security mechanism into thinking that the file you want has a valid file type.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_access_a_salesmans_forgotten_backup_file' - mitigationUrl: ~ - key: forgottenBackupChallenge -- - name: 'Frontend Typosquatting' - category: 'Vulnerable Components' - description: 'Inform the shop about a typosquatting imposter that dug itself deep into the frontend. (Mention the exact name of the culprit)' - difficulty: 5 - hint: '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?' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_inform_the_shop_about_a_typosquatting_imposter_that_dug_itself_deep_into_the_frontend' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerable_Dependency_Management_Cheat_Sheet.html' - key: typosquattingAngularChallenge -- - name: 'GDPR Data Erasure' - category: 'Broken Authentication' - description: 'Log in with Chris'' erased user account.' - difficulty: 3 - hint: 'Turns out that something is technically and legally wrong with the implementation of the "right to be forgotten" for users.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_log_in_with_chris_erased_user_account' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/User_Privacy_Protection_Cheat_Sheet.html' - key: ghostLoginChallenge -- - name: 'GDPR Data Theft' - category: 'Sensitive Data Exposure' - description: 'Steal someone else''s personal data without using Injection.' - difficulty: 4 - hint: 'Trick the regular Data Export to give you more than actually belongs to you.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_steal_someone_elses_personal_data_without_using_injection' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/User_Privacy_Protection_Cheat_Sheet.html' - key: dataExportChallenge -- - name: 'HTTP-Header XSS' - category: 'XSS' - tags: - - Danger Zone - description: 'Perform a persisted XSS attack with <iframe src="javascript:alert(`xss`)"> through an HTTP header.' - difficulty: 4 - hint: 'Finding a piece of displayed information that could originate from an HTTP header is part of this challenge.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_perform_a_persisted_xss_attack_through_an_http_header' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' - key: httpHeaderXssChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'Imaginary Challenge' - category: 'Cryptographic Issues' - tags: - - Shenanigans - - Code Analysis - description: 'Solve challenge #999. Unfortunately, this challenge does not exist.' - difficulty: 6 - hint: 'You need to trick the hacking progress persistence feature into thinking you solved challenge #999.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/cryptographic-issues.html#_solve_challenge_999' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html' - key: continueCodeChallenge -- - name: 'Leaked Access Logs' - category: 'Sensitive Data Exposure' - tags: - - OSINT - description: '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.)' - difficulty: 5 - hint: 'Once you have it, a technique called "Password Spraying" might prove useful.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_dumpster_dive_the_internet_for_a_leaked_password_and_log_in_to_the_original_user_account_it_belongs_to' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Credential_Stuffing_Prevention_Cheat_Sheet.html' - key: dlpPasswordSprayingChallenge -- - name: 'Leaked Unsafe Product' - category: 'Sensitive Data Exposure' - tags: - - Shenanigans - - OSINT - description: 'Identify an unsafe product that was removed from the shop and inform the shop which ingredients are dangerous.' - difficulty: 4 - hint: 'Your own SQLi and someone else''s Ctrl-V will be your accomplices in this challenge!' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_identify_an_unsafe_product_that_was_removed_from_the_shop_and_inform_the_shop_which_ingredients_are_dangerous' - mitigationUrl: ~ - key: dlpPastebinDataLeakChallenge -- - name: 'Legacy Typosquatting' - category: 'Vulnerable Components' - description: '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)' - difficulty: 4 - hint: 'This challenge has nothing to do with mistyping web domains. Investigate the forgotten developer''s backup file instead.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_inform_the_shop_about_a_typosquatting_trick_it_has_been_a_victim_of' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerable_Dependency_Management_Cheat_Sheet.html' - key: typosquattingNpmChallenge -- - name: 'Login Admin' - category: 'Injection' - tags: - - Tutorial - - Good for Demos - description: 'Log in with the administrator''s user account.' - difficulty: 2 - hint: 'Try different SQL Injection attack patterns depending whether you know the admin''s email address or not.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_log_in_with_the_administrators_user_account' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' - key: loginAdminChallenge - tutorial: - order: 6 -- - name: 'Login Amy' - category: 'Sensitive Data Exposure' - tags: - - OSINT - description: '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")' - difficulty: 3 - hint: 'This challenge will make you go after a needle in a haystack.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_log_in_with_amys_original_user_credentials' - mitigationUrl: ~ - key: loginAmyChallenge -- - name: 'Login Bender' - category: 'Injection' - tags: - - Tutorial - description: 'Log in with Bender''s user account.' - difficulty: 3 - hint: 'If you know Bender''s email address, try SQL Injection. Bender''s password hash might not help you very much.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_log_in_with_benders_user_account' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' - key: loginBenderChallenge - tutorial: - order: 12 -- - name: 'Login Bjoern' - category: 'Broken Authentication' - tags: - - Code Analysis - description: 'Log in with Bjoern''s Gmail account without previously changing his password, applying SQL Injection, or hacking his Google account.' - difficulty: 4 - hint: 'The security flaw behind this challenge is 100% OWASP Juice Shop''s fault and 0% Google''s.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_log_in_with_bjoerns_gmail_account' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html' - key: oauthUserPasswordChallenge -- - name: 'Login Jim' - category: 'Injection' - tags: - - Tutorial - description: 'Log in with Jim''s user account.' - difficulty: 3 - hint: 'Try cracking Jim''s password hash if you harvested it already. Alternatively, if you know Jim''s email address, try SQL Injection.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_log_in_with_jims_user_account' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' - key: loginJimChallenge - tutorial: - order: 11 -- - name: 'Login MC SafeSearch' - category: 'Sensitive Data Exposure' - tags: - - Shenanigans - - OSINT - description: 'Log in with MC SafeSearch''s original user credentials without applying SQL Injection or any other bypass.' - difficulty: 2 - hint: 'You should listen to MC''s hit song "Protect Ya Passwordz".' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_log_in_with_mc_safesearchs_original_user_credentials' - mitigationUrl: ~ - key: loginRapperChallenge -- - name: 'Login Support Team' - category: 'Security Misconfiguration' - tags: - - Brute Force - - Code Analysis - description: 'Log in with the support team''s original user credentials without applying SQL Injection or any other bypass.' - difficulty: 6 - hint: 'The underlying flaw of this challenge is a lot more human error than technical weakness.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-misconfiguration.html#_log_in_with_the_support_teams_original_user_credentials' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html' - key: loginSupportChallenge -- - name: 'Manipulate Basket' - category: 'Broken Access Control' - description: 'Put an additional product into another user''s shopping basket.' - difficulty: 3 - hint: '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.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_put_an_additional_product_into_another_users_shopping_basket' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html' - key: basketManipulateChallenge -- - name: 'Misplaced Signature File' - category: 'Sensitive Data Exposure' - tags: - - Good Practice - - Contraption - description: 'Access a misplaced SIEM signature file.' - difficulty: 4 - hint: 'You need to trick a security mechanism into thinking that the file you want has a valid file type.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_access_a_misplaced_siem_signature_file' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html' - key: misplacedSignatureFileChallenge -- - name: 'Multiple Likes' - category: 'Broken Anti Automation' - description: 'Like any review at least three times as the same user.' - difficulty: 6 - hint: 'Punctuality is the politeness of kings.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-anti-automation.html#_like_any_review_at_least_three_times_as_the_same_user' - mitigationUrl: ~ - key: timingAttackChallenge -- - name: 'Nested Easter Egg' - category: 'Cryptographic Issues' - tags: - - Shenanigans - - Good for Demos - description: 'Apply some advanced cryptanalysis to find the real easter egg.' - difficulty: 4 - hint: 'You might have to peel through several layers of tough-as-nails encryption for this challenge.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/cryptographic-issues.html#_apply_some_advanced_cryptanalysis_to_find_the_real_easter_egg' - mitigationUrl: ~ - key: easterEggLevelTwoChallenge -- - name: 'NoSQL DoS' - category: 'Injection' - tags: - - Danger Zone - description: 'Let the server sleep for some time. (It has done more than enough hard work for you)' - difficulty: 4 - hint: 'This challenge is essentially a stripped-down Denial of Service (DoS) attack.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_let_the_server_sleep_for_some_time' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html' - key: noSqlCommandChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'NoSQL Exfiltration' - category: 'Injection' - tags: - - Danger Zone - description: 'All your orders are belong to us! Even the ones which don''t.' - difficulty: 5 - hint: 'Take a close look on how the $where query operator works in MongoDB.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_all_your_orders_are_belong_to_us' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html' - key: noSqlOrdersChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'NoSQL Manipulation' - category: 'Injection' - description: 'Update multiple product reviews at the same time.' - difficulty: 4 - hint: 'Take a close look on how the equivalent of UPDATE-statements in MongoDB work.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_update_multiple_product_reviews_at_the_same_time' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html' - key: noSqlReviewsChallenge -- - name: 'Outdated Allowlist' - category: 'Unvalidated Redirects' - tags: - - Code Analysis - description: 'Let us redirect you to one of our crypto currency addresses which are not promoted any longer.' - difficulty: 1 - hint: 'We might have failed to take this out of our code properly.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/unvalidated-redirects.html#_let_us_redirect_you_to_one_of_our_crypto_currency_addresses' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html' - key: redirectCryptoCurrencyChallenge -- - name: 'Password Strength' - category: 'Broken Authentication' - tags: - - Brute Force - - Tutorial - description: 'Log in with the administrator''s user credentials without previously changing them or applying SQL Injection.' - difficulty: 2 - hint: 'This one should be equally easy to a) brute force, b) crack the password hash or c) simply guess.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_log_in_with_the_administrators_user_credentials_without_previously_changing_them_or_applying_sql_injection' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html' - key: weakPasswordChallenge - tutorial: - order: 8 -- - name: 'Payback Time' - category: 'Improper Input Validation' - description: 'Place an order that makes you rich.' - difficulty: 3 - hint: 'You literally need to make the shop owe you any amount of money.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_place_an_order_that_makes_you_rich' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html' - key: negativeOrderChallenge -- - name: 'Premium Paywall' - category: 'Cryptographic Issues' - tags: - - Shenanigans - description: ' Unlock Premium Challenge to access exclusive content.' - difficulty: 6 - hint: 'You do not have to pay anything to unlock this challenge! Nonetheless, donations are very much appreciated.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/cryptographic-issues.html#_unlock_premium_challenge_to_access_exclusive_content' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Key_Management_Cheat_Sheet.html' - key: premiumPaywallChallenge -- - name: 'Privacy Policy' - category: 'Miscellaneous' - tags: - - Good Practice - - Tutorial - - Good for Demos - description: 'Read our privacy policy.' - difficulty: 1 - hint: 'We won''t even ask you to confirm that you did. Just read it. Please. Pretty please.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/miscellaneous.html#_read_our_privacy_policy' - mitigationUrl: ~ - key: privacyPolicyChallenge - tutorial: - order: 4 -- - name: 'Privacy Policy Inspection' - category: 'Security through Obscurity' - tags: - - Shenanigans - - Good for Demos - description: 'Prove that you actually read our privacy policy.' - difficulty: 3 - hint: 'Only by visiting a special URL you can confirm that you read it carefully.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-through-obscurity.html#_prove_that_you_actually_read_our_privacy_policy' - mitigationUrl: ~ - key: privacyPolicyProofChallenge -- - name: 'Product Tampering' - category: 'Broken Access Control' - description: 'Change the href of the link within the OWASP SSL Advanced Forensic Tool (O-Saft) product description into https://owasp.slack.com.' - difficulty: 3 - hint: 'Look for one of the following: a) broken admin functionality, b) holes in RESTful API or c) possibility for SQL Injection.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_change_the_href_of_the_link_within_the_o_saft_product_description' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html' - key: changeProductChallenge -- - name: 'Reflected XSS' - category: 'XSS' - tags: - - Tutorial - - Danger Zone - - Good for Demos - description: 'Perform a reflected XSS attack with <iframe src="javascript:alert(`xss`)">.' - difficulty: 2 - hint: 'Look for a url parameter where its value appears in the page it is leading to.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_perform_a_reflected_xss_attack' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' - key: reflectedXssChallenge - tutorial: - order: 5 - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'Repetitive Registration' - category: 'Improper Input Validation' - description: 'Follow the DRY principle while registering a user.' - difficulty: 1 - hint: 'You can solve this by cleverly interacting with the UI or bypassing it altogether.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_follow_the_dry_principle_while_registering_a_user' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html' - key: passwordRepeatChallenge -- - name: 'Reset Bender''s Password' - category: 'Broken Authentication' - tags: - - OSINT - description: 'Reset Bender''s password via the Forgot Password mechanism with the original answer to his security question.' - difficulty: 4 - hint: 'Not as trivial as Jim''s but still not too difficult with some "Futurama" background knowledge.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_reset_benders_password_via_the_forgot_password_mechanism' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' - key: resetPasswordBenderChallenge -- - name: 'Reset Bjoern''s Password' - category: 'Broken Authentication' - tags: - - OSINT - description: 'Reset the password of Bjoern''s internal account via the Forgot Password mechanism with the original answer to his security question.' - difficulty: 5 - hint: 'Nothing a little bit of Facebook stalking couldn''t reveal. Might involve a historical twist.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_reset_the_password_of_bjoerns_internal_account_via_the_forgot_password_mechanism' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' - key: resetPasswordBjoernChallenge -- - name: 'Reset Jim''s Password' - category: 'Broken Authentication' - tags: - - OSINT - description: 'Reset Jim''s password via the Forgot Password mechanism with the original answer to his security question.' - difficulty: 3 - hint: 'It''s hard for celebrities to pick a security question from a hard-coded list where the answer is not publicly exposed.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_reset_jims_password_via_the_forgot_password_mechanism' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' - key: resetPasswordJimChallenge -- - name: 'Reset Morty''s Password' - category: 'Broken Anti Automation' - tags: - - OSINT - - Brute Force - description: 'Reset Morty''s password via the Forgot Password mechanism with his obfuscated answer to his security question.' - difficulty: 5 - hint: 'Find a way to bypass the rate limiting and brute force the obfuscated answer to Morty''s security question.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-anti-automation.html#_reset_mortys_password_via_the_forgot_password_mechanism' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Forgot_Password_Cheat_Sheet.html' - key: resetPasswordMortyChallenge -- - name: 'Retrieve Blueprint' - category: 'Sensitive Data Exposure' - description: 'Deprive the shop of earnings by downloading the blueprint for one of its products.' - difficulty: 5 - hint: 'The product you might want to give a closer look is the OWASP Juice Shop Logo (3D-printed).' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_deprive_the_shop_of_earnings_by_downloading_the_blueprint_for_one_of_its_products' - mitigationUrl: ~ - key: retrieveBlueprintChallenge -- - name: 'SSRF' - category: 'Broken Access Control' - tags: - - Code Analysis - description: 'Request a hidden resource on server through server.' - difficulty: 6 - hint: 'Reverse engineering something bad can make good things happen.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_request_a_hidden_resource_on_server_through_server' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html' - key: ssrfChallenge -- - name: 'SSTi' - category: 'Injection' - tags: - - Contraption - - Danger Zone - - Code Analysis - description: 'Infect the server with juicy malware by abusing arbitrary command execution.' - difficulty: 6 - hint: '"SSTi" is a clear indicator that this has nothing to do with anything Angular. Also, make sure to use only our non-malicious malware.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_infect_the_server_with_juicy_malware_by_abusing_arbitrary_command_execution' - mitigationUrl: ~ - key: sstiChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'Score Board' - category: 'Miscellaneous' - tags: - - Tutorial - - Code Analysis - description: 'Find the carefully hidden ''Score Board'' page.' - difficulty: 1 - hint: 'Try to find a reference or clue behind the scenes. Or simply guess what URL the Score Board might have.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/score-board.html#_find_the_carefully_hidden_score_board_page' - mitigationUrl: ~ - key: scoreBoardChallenge - tutorial: - order: 1 -- - name: 'Security Policy' - category: 'Miscellaneous' - tags: - - Good Practice - description: 'Behave like any "white-hat" should before getting into the action.' - difficulty: 2 - hint: 'Undoubtedly you want to read our security policy before conducting any research on our application.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/miscellaneous.html#_behave_like_any_white_hat_should_before_getting_into_the_action' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerability_Disclosure_Cheat_Sheet.html' - key: securityPolicyChallenge -- - name: 'Server-side XSS Protection' - category: 'XSS' - tags: - - Danger Zone - description: 'Perform a persisted XSS attack with <iframe src="javascript:alert(`xss`)"> bypassing a server-side security mechanism.' - difficulty: 4 - hint: 'The "Comment" field in the "Customer Feedback" screen is where you want to put your focus on.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_perform_a_persisted_xss_attack_bypassing_a_server_side_security_mechanism' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' - key: persistedXssFeedbackChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'Steganography' - category: 'Security through Obscurity' - tags: - - Shenanigans - description: 'Rat out a notorious character hiding in plain sight in the shop. (Mention the exact name of the character)' - difficulty: 4 - hint: 'No matter how good your eyes are, you will need tool assistance for this challenge.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-through-obscurity.html#_rat_out_a_notorious_character_hiding_in_plain_sight_in_the_shop' - mitigationUrl: ~ - key: hiddenImageChallenge -- - name: 'Successful RCE DoS' - category: 'Insecure Deserialization' - tags: - - Danger Zone - description: 'Perform a Remote Code Execution that occupies the server for a while without using infinite loops.' - difficulty: 6 - hint: 'Your attack payload must not trigger the protection against too many iterations.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/insecure-deserialization.html#_perform_a_remote_code_execution_that_occupies_the_server_for_a_while_without_using_infinite_loops' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html' - key: rceOccupyChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'Supply Chain Attack' - category: 'Vulnerable Components' - tags: - - OSINT - description: '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)' - difficulty: 5 - hint: 'This vulnerability will not affect any customer of the shop. It is aimed exclusively at its developers.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_inform_the_development_team_about_a_danger_to_some_of_their_credentials' - mitigationUrl: ~ - key: supplyChainAttackChallenge -- - name: 'Two Factor Authentication' - category: 'Broken Authentication' - description: 'Solve the 2FA challenge for user "wurstbrot". (Disabling, bypassing or overwriting his 2FA settings does not count as a solution)' - difficulty: 5 - hint: '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.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_solve_the_2fa_challenge_for_user_wurstbrot' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Multifactor_Authentication_Cheat_Sheet.html' - key: twoFactorAuthUnsafeSecretStorageChallenge -- - name: 'Unsigned JWT' - category: 'Vulnerable Components' - description: 'Forge an essentially unsigned JWT token that impersonates the (non-existing) user jwtn3d@juice-sh.op.' - difficulty: 5 - hint: 'This challenge exploits a weird option that is supported when signing tokens with JWT.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_forge_an_essentially_unsigned_jwt_token' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html' - key: jwtUnsignedChallenge -- - name: 'Upload Size' - category: 'Improper Input Validation' - description: 'Upload a file larger than 100 kB.' - difficulty: 3 - hint: 'You can attach a small file to the "Complaint" form. Investigate how this upload actually works.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_upload_a_file_larger_than_100_kb' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html' - key: uploadSizeChallenge -- - name: 'Upload Type' - category: 'Improper Input Validation' - description: 'Upload a file that has no .pdf or .zip extension.' - difficulty: 3 - hint: 'You can attach a PDF or ZIP file to the "Complaint" form. Investigate how this upload actually works.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_upload_a_file_that_has_no_pdf_or_zip_extension' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html' - key: uploadTypeChallenge -- - name: 'User Credentials' - category: 'Injection' - description: 'Retrieve a list of all user credentials via SQL Injection.' - difficulty: 4 - hint: 'Gather information on where user data is stored and how it is addressed. Then craft a corresponding UNION SELECT attack.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_retrieve_a_list_of_all_user_credentials_via_sql_injection' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' - key: unionSqlInjectionChallenge -- - name: 'Video XSS' - category: 'XSS' - tags: - - Danger Zone - description: 'Embed an XSS payload </script><script>alert(`xss`)</script> into our promo video.' - difficulty: 6 - hint: 'You have to reuse the vulnerability behind one other 6-star challenge to be able to solve this one.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_embed_an_xss_payload_into_our_promo_video' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' - key: videoXssChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'View Basket' - category: 'Broken Access Control' - tags: - - Tutorial - - Good for Demos - description: 'View another user''s shopping basket.' - difficulty: 2 - hint: 'Have an eye on the HTTP traffic while shopping. Alternatively try to find a client-side association of users to their basket.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_view_another_users_shopping_basket' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html' - key: basketAccessChallenge - tutorial: - order: 9 -- - name: 'Vulnerable Library' - category: 'Vulnerable Components' - tags: - - OSINT - description: 'Inform the shop about a vulnerable library it is using. (Mention the exact library name and version in your comment)' - difficulty: 4 - hint: 'Report one of two possible answers via the "Customer Feedback" form. Do not forget to submit the library''s version as well.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_inform_the_shop_about_a_vulnerable_library_it_is_using' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerability_Disclosure_Cheat_Sheet.html' - key: knownVulnerableComponentChallenge -- - name: 'Weird Crypto' - category: 'Cryptographic Issues' - description: 'Inform the shop about an algorithm or library it should definitely not use the way it does.' - difficulty: 2 - hint: 'Report one of four possible answers via the "Customer Feedback" form.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/cryptographic-issues.html#_inform_the_shop_about_an_algorithm_or_library_it_should_definitely_not_use_the_way_it_does' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerability_Disclosure_Cheat_Sheet.html' - key: weirdCryptoChallenge -- - name: 'Allowlist Bypass' - category: 'Unvalidated Redirects' - tags: - - Prerequisite - description: 'Enforce a redirect to a page you are not supposed to redirect to.' - difficulty: 4 - hint: 'You have to find a way to beat the allowlist of allowed redirect URLs.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/unvalidated-redirects.html#_enforce_a_redirect_to_a_page_you_are_not_supposed_to_redirect_to' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html' - key: redirectChallenge -- - name: 'XXE Data Access' - category: 'XXE' - tags: - - Danger Zone - description: 'Retrieve the content of C:\Windows\system.ini or /etc/passwd from the server.' - difficulty: 3 - hint: 'The leverage point for this challenge is the deprecated B2B interface.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xxe.html#_retrieve_the_content_of_cwindowssystemini_or_etcpasswd_from_the_server' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html' - key: xxeFileDisclosureChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'XXE DoS' - category: 'XXE' - tags: - - Danger Zone - description: 'Give the server something to chew on for quite a while.' - difficulty: 5 - hint: 'It is not as easy as sending a large amount of data directly to the deprecated B2B interface.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xxe.html#_give_the_server_something_to_chew_on_for_quite_a_while' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html' - key: xxeDosChallenge - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'Zero Stars' - category: 'Improper Input Validation' - description: 'Give a devastating zero-star feedback to the store.' - difficulty: 1 - hint: 'Before you invest time bypassing the API, you might want to play around with the UI a bit.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_give_a_devastating_zero_star_feedback_to_the_store' - mitigationUrl: ~ - key: zeroStarsChallenge -- - name: 'Missing Encoding' - category: 'Improper Input Validation' - tags: - - Shenanigans - description: 'Retrieve the photo of Bjoern''s cat in "melee combat-mode".' - difficulty: 1 - hint: 'Check the Photo Wall for an image that could not be loaded correctly.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_retrieve_the_photo_of_bjoerns_cat_in_melee_combat_mode' - mitigationUrl: ~ - key: missingEncodingChallenge -- - name: 'Cross-Site Imaging' - category: 'Security Misconfiguration' - tags: - - Contraption - description: 'Stick cute cross-domain kittens all over our delivery boxes.' - difficulty: 5 - hint: 'This challenge would formally have to be in several categories as the developers made multiple gaffes for this to be possible.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-misconfiguration.html#_stick_cute_cross_domain_kittens_all_over_our_delivery_boxes' - mitigationUrl: ~ - key: svgInjectionChallenge -- - name: 'Exposed Metrics' - category: 'Sensitive Data Exposure' - tags: - - Good Practice - description: 'Find the endpoint that serves usage data to be scraped by a popular monitoring system.' - difficulty: 1 - hint: 'Try to guess what URL the endpoint might have.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_find_the_endpoint_that_serves_usage_data_to_be_scraped_by_a_popular_monitoring_system' - mitigationUrl: ~ - key: exposedMetricsChallenge -- - name: 'Deluxe Fraud' - category: 'Improper Input Validation' - description: 'Obtain a Deluxe Membership without paying for it.' - difficulty: 3 - hint: 'Look closely at what happens when you attempt to upgrade your account.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_obtain_a_deluxe_membership_without_paying_for_it' - mitigationUrl: ~ - key: freeDeluxeChallenge -- - name: 'CSRF' # FIXME No e2e test automation! No longer works in Chrome >=80 and Firefox >=100 or other latest browsers! - category: 'Broken Access Control' - description: 'Change the name of a user by performing Cross-Site Request Forgery from another origin.' - difficulty: 3 - hint: 'Find a form which updates the username and then construct a malicious page in the online HTML editor. You probably need an older browser version for this.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_change_the_name_of_a_user_by_performing_cross_site_request_forgery_from_another_origin' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html' - key: csrfChallenge -- - name: 'Bonus Payload' - category: 'XSS' - tags: - - Shenanigans - - Tutorial - description: '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.' - difficulty: 1 - hint: 'Copy + Paste = Solved!' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_use_the_bonus_payload_in_the_dom_xss_challenge' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html' - key: xssBonusChallenge - tutorial: - order: 3 -- - name: 'Reset Uvogin''s Password' - category: 'Sensitive Data Exposure' - tags: - - OSINT - description: 'Reset Uvogin''s password via the Forgot Password mechanism with the original answer to his security question.' - difficulty: 4 - hint: 'You might have to do some OSINT on his social media personas to find out his honest answer to the security question.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_reset_uvogins_password_via_the_forgot_password_mechanism' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' - key: resetPasswordUvoginChallenge -- - name: 'Meta Geo Stalking' - category: 'Sensitive Data Exposure' - tags: - - OSINT - description: '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.' - difficulty: 2 - hint: 'Take a look at the meta data of the corresponding photo.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_determine_the_answer_to_johns_security_question' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' - key: geoStalkingMetaChallenge -- - name: 'Visual Geo Stalking' - category: 'Sensitive Data Exposure' - tags: - - OSINT - description: '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.' - difficulty: 2 - hint: 'Take a look at the details in the photo to determine the location of where it was taken.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_determine_the_answer_to_emmas_security_question' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' - key: geoStalkingVisualChallenge -- - name: 'Kill Chatbot' - category: 'Vulnerable Components' - tags: - - Code Analysis - description: 'Permanently disable the support chatbot so that it can no longer answer customer queries.' - difficulty: 5 - hint: 'Think of a way to get a hold of the internal workings on the chatbot API.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_permanently_disable_the_support_chatbot' - mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerable_Dependency_Management_Cheat_Sheet.html' - key: killChatbotChallenge -- - name: 'Poison Null Byte' - category: 'Improper Input Validation' - tags: - - Prerequisite - description: 'Bypass a security control with a Poison Null Byte to access a file not meant for your eyes.' - difficulty: 4 - hint: 'Take a look at the details in the photo to determine the location of where it was taken.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_bypass_a_security_control_with_a_poison_null_byte' - mitigationUrl: ~ - key: nullByteChallenge -- - name: 'Bully Chatbot' - category: 'Miscellaneous' - tags: - - Shenanigans - - Brute Force - description: 'Receive a coupon code from the support chatbot.' - difficulty: 1 - hint: 'Just keep asking.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/miscellaneous.html#_receive_a_coupon_code_from_the_support_chatbot' - mitigationUrl: ~ - key: bullyChatbotChallenge -- - name: 'Local File Read' - category: 'Vulnerable Components' - tags: - - OSINT - - Danger Zone - difficulty: 5 - hint: 'You should read up on vulnerabilities in popular NodeJs template engines.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_gain_read_access_to_an_arbitrary_local_file_on_the_web_server' - description: 'Gain read access to an arbitrary local file on the web server.' - key: 'lfrChallenge' - disabledEnv: - - Docker - - Heroku - - Gitpod -- - name: 'Mass Dispel' - category: 'Miscellaneous' - description: 'Close multiple "Challenge solved"-notifications in one go.' - difficulty: 1 - hint: 'Either check the official documentation or inspect a notification UI element directly.' - hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/score-board.html#_close_multiple_challenge_solved_notifications_in_one_go' - mitigationUrl: ~ - key: closeNotificationsChallenge -- - name: 'Security Advisory' - category: 'Miscellaneous' - description: ' The Juice Shop is susceptible to a known vulnerability in a library, for which an advisory has already been issued, marking the Juice Shop as known affected. A fix is still pending. Inform the shop about a suitable checksum as proof that you did your due diligence.' - difficulty: 3 - hint: 'Security Advisories are often listed in the security.txt' - hintUrl: '' - mitigationUrl: ~ - key: csafChallenge +- + name: 'API-only XSS' + category: 'XSS' + tags: + - Danger Zone + description: 'Perform a persisted XSS attack with <iframe src="javascript:alert(`xss`)"> without using the frontend application at all.' + difficulty: 3 + hint: 'You need to work with the server-side API directly. Try different HTTP verbs on different entities exposed through the API.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_perform_a_persisted_xss_attack_without_using_the_frontend_application_at_all' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' + key: restfulXssChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'Access Log' + category: 'Sensitive Data Exposure' + description: 'Gain access to any access log file of the server.' + difficulty: 4 + hint: 'Who would want a server access log to be accessible through a web application?' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_gain_access_to_any_access_log_file_of_the_server' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html' + key: accessLogDisclosureChallenge +- + name: 'Admin Registration' + category: 'Improper Input Validation' + description: 'Register as a user with administrator privileges.' + difficulty: 3 + hint: 'You have to assign the unassignable.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_register_as_a_user_with_administrator_privileges' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html' + key: registerAdminChallenge +- + name: 'Admin Section' + category: 'Broken Access Control' + tags: + - Good for Demos + description: 'Access the administration section of the store.' + difficulty: 2 + hint: 'It is just slightly harder to find than the score board link.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_access_the_administration_section_of_the_store' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html' + key: adminSectionChallenge + tutorial: + order: 7 +- + name: 'Arbitrary File Write' + category: 'Vulnerable Components' + tags: + - Danger Zone + - Prerequisite + description: 'Overwrite the Legal Information file.' + difficulty: 6 + hint: 'Look out for a tweet praising new functionality of the web shop. Then find a third party vulnerability associated with it.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_overwrite_the_legal_information_file' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerable_Dependency_Management_Cheat_Sheet.html' + key: fileWriteChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'Bjoern''s Favorite Pet' + category: 'Broken Authentication' + tags: + - OSINT + description: 'Reset the password of Bjoern''s OWASP account via the Forgot Password mechanism with the original answer to his security question.' + difficulty: 3 + hint: 'He might have trumpeted it on at least one occasion where a camera was running. Maybe elsewhere as well.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_reset_the_password_of_bjoerns_owasp_account_via_the_forgot_password_mechanism' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' + key: resetPasswordBjoernOwaspChallenge +- + name: 'Blockchain Hype' + category: 'Security through Obscurity' + tags: + - Contraption + - Code Analysis + - Web3 + description: 'Learn about the Token Sale before its official announcement.' + difficulty: 5 + hint: 'The developers truly believe in "Security through Obscurity" over actual access restrictions.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-through-obscurity.html#_learn_about_the_token_sale_before_its_official_announcement' + mitigationUrl: ~ + key: tokenSaleChallenge +- + name: 'NFT Takeover' + category: 'Sensitive Data Exposure' + tags: + - Contraption + - Good for Demos + - Web3 + description: 'Take over the wallet containing our official Soul Bound Token (NFT).' + difficulty: 2 + hint: 'Find the seed phrase posted accidentally.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_take_over_the_wallet_containing_our_official_soul_bound_token' + mitigationUrl: ~ + key: nftUnlockChallenge +- + name: 'Mint the Honey Pot' + category: 'Improper Input Validation' + tags: + - Web3 + - Internet Traffic + description: 'Mint the Honey Pot NFT by gathering BEEs from the bee haven.' + difficulty: 3 + hint: 'Discover NFT wonders among the captivating visual memories.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_mint_the_honey_pot_nft_by_gathering_bees_from_the_bee_haven' + mitigationUrl: ~ + key: nftMintChallenge +- + name: 'Wallet Depletion' + category: 'Miscellaneous' + tags: + - Web3 + - Internet Traffic + description: 'Withdraw more ETH from the new wallet than you deposited.' + difficulty: 6 + hint: 'Try to exploit the contract of the wallet.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/miscellaneous.html#_withdraw_more_eth_from_the_new_wallet_than_you_deposited' + mitigationUrl: ~ + key: web3WalletChallenge +- + name: 'Web3 Sandbox' + category: 'Broken Access Control' + tags: + - Web3 + description: 'Find an accidentally deployed code sandbox for writing smart contracts on the fly.' + difficulty: 1 + hint: 'It is just as easy as finding the Score Board.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_find_an_accidentally_deployed_code_sandbox' + mitigationUrl: ~ + key: web3SandboxChallenge +- + name: 'Blocked RCE DoS' + category: 'Insecure Deserialization' + tags: + - Danger Zone + description: 'Perform a Remote Code Execution that would keep a less hardened application busy forever.' + difficulty: 5 + hint: 'The feature you need to exploit for this challenge is not directly advertised anywhere.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/insecure-deserialization.html#_perform_a_remote_code_execution_that_would_keep_a_less_hardened_application_busy_forever' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html' + key: rceChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'CAPTCHA Bypass' + category: 'Broken Anti Automation' + tags: + - Brute Force + description: 'Submit 10 or more customer feedbacks within 20 seconds.' + difficulty: 3 + hint: 'After finding a CAPTCHA bypass, write a script that automates feedback submission. Or open many browser tabs and be really quick.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-anti-automation.html#_submit_10_or_more_customer_feedbacks_within_20_seconds' + mitigationUrl: ~ + key: captchaBypassChallenge +- + name: 'Change Bender''s Password' + category: 'Broken Authentication' + description: 'Change Bender''s password into slurmCl4ssic without using SQL Injection or Forgot Password.' + difficulty: 5 + hint: 'In previous releases this challenge was wrongly accused of being based on CSRF.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_change_benders_password_into_slurmcl4ssic_without_using_sql_injection_or_forgot_password' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html' + key: changePasswordBenderChallenge +- + name: 'Christmas Special' + category: 'Injection' + description: 'Order the Christmas special offer of 2014.' + difficulty: 4 + hint: 'Find out how the application handles unavailable products and try to find a loophole.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_order_the_christmas_special_offer_of_2014' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' + key: christmasSpecialChallenge +- + name: 'CSP Bypass' + category: 'XSS' + tags: + - Danger Zone + description: 'Bypass the Content Security Policy and perform an XSS attack with <script>alert(`xss`)</script> on a legacy page within the application.' + difficulty: 4 + hint: 'What is even "better" than a legacy page with a homegrown RegEx sanitizer? Having CSP injection issues on the exact same page as well!' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_bypass_the_content_security_policy_and_perform_an_xss_attack_on_a_legacy_page' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' + key: usernameXssChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'Client-side XSS Protection' + category: 'XSS' + tags: + - Danger Zone + description: 'Perform a persisted XSS attack with <iframe src="javascript:alert(`xss`)"> bypassing a client-side security mechanism.' + difficulty: 3 + hint: 'Only some input fields validate their input. Even less of these are persisted in a way where their content is shown on another screen.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_perform_a_persisted_xss_attack_bypassing_a_client_side_security_mechanism' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' + key: persistedXssUserChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'Confidential Document' + category: 'Sensitive Data Exposure' + tags: + - Good for Demos + description: 'Access a confidential document.' + difficulty: 1 + hint: 'Analyze and tamper with links in the application that deliver a file directly.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_access_a_confidential_document' + mitigationUrl: ~ + key: directoryListingChallenge +- + name: 'DOM XSS' + category: 'XSS' + tags: + - Tutorial + - Good for Demos + description: 'Perform a DOM XSS attack with <iframe src="javascript:alert(`xss`)">.' + difficulty: 1 + hint: 'Look for an input field where its content appears in the HTML when its form is submitted.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_perform_a_dom_xss_attack' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html' + key: localXssChallenge + tutorial: + order: 2 +- + name: 'Database Schema' + category: 'Injection' + description: 'Exfiltrate the entire DB schema definition via SQL Injection.' + difficulty: 3 + hint: '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.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_exfiltrate_the_entire_db_schema_definition_via_sql_injection' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' + key: dbSchemaChallenge +- + name: 'Deprecated Interface' + category: 'Security Misconfiguration' + tags: + - Contraption + - Prerequisite + description: 'Use a deprecated B2B interface that was not properly shut down.' + difficulty: 2 + hint: 'The developers who disabled the interface think they could go invisible by just closing their eyes.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-misconfiguration.html#_use_a_deprecated_b2b_interface_that_was_not_properly_shut_down' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Web_Service_Security_Cheat_Sheet.html' + key: deprecatedInterfaceChallenge +- + name: 'Easter Egg' + category: 'Broken Access Control' + tags: + - Shenanigans + - Contraption + - Good for Demos + description: 'Find the hidden easter egg.' + difficulty: 4 + hint: 'If you solved one of the three file access challenges, you already know where to find the easter egg.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_find_the_hidden_easter_egg' + mitigationUrl: ~ + key: easterEggLevelOneChallenge +- + name: 'Email Leak' + category: 'Sensitive Data Exposure' + description: 'Perform an unwanted information disclosure by accessing data cross-domain.' + difficulty: 5 + hint: 'Try to find and attack an endpoint that responds with user information. SQL Injection is not the solution here.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_perform_an_unwanted_information_disclosure_by_accessing_data_cross_domain' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/XS_Leaks_Cheat_Sheet.html' + 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/companion-guide/latest/part2/improper-input-validation.html#_register_a_user_account_with_an_empty_email_and_password' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html' + key: emptyUserRegistration +- + name: 'Ephemeral Accountant' + category: 'Injection' + description: 'Log in with the (non-existing) accountant acc0unt4nt@juice-sh.op without ever registering that user.' + difficulty: 4 + hint: 'Try to create the needed user "out of thin air".' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_log_in_with_the_non_existing_accountant_without_ever_registering_that_user' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' + key: ephemeralAccountantChallenge +- + name: 'Error Handling' + category: 'Security Misconfiguration' + tags: + - Prerequisite + description: 'Provoke an error that is neither very gracefully nor consistently handled.' + difficulty: 1 + hint: 'Try to submit bad input to forms. Alternatively tamper with URL paths or parameters.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-misconfiguration.html#_provoke_an_error_that_is_neither_very_gracefully_nor_consistently_handled' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Error_Handling_Cheat_Sheet.html' + key: errorHandlingChallenge +- + name: 'Expired Coupon' + category: 'Improper Input Validation' + description: 'Successfully redeem an expired campaign coupon code.' + difficulty: 4 + hint: 'Try to identify past special event or holiday campaigns of the shop first.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_successfully_redeem_an_expired_campaign_coupon_code' + mitigationUrl: ~ + key: manipulateClockChallenge +- + name: 'Extra Language' + category: 'Broken Anti Automation' + tags: + - Brute Force + description: 'Retrieve the language file that never made it into production.' + difficulty: 5 + hint: 'Brute force is not the only option for this challenge, but a perfectly viable one.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-anti-automation.html#_retrieve_the_language_file_that_never_made_it_into_production' + mitigationUrl: ~ + key: extraLanguageChallenge +- + name: 'Five-Star Feedback' + category: 'Broken Access Control' + description: 'Get rid of all 5-star customer feedback.' + difficulty: 2 + hint: 'Once you found admin section of the application, this challenge is almost trivial.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_get_rid_of_all_5_star_customer_feedback' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html' + key: feedbackChallenge +- + name: 'Forged Coupon' + category: 'Cryptographic Issues' + tags: + - Good for Demos + - Code Analysis + description: 'Forge a coupon code that gives you a discount of at least 80%.' + difficulty: 6 + hint: 'Try either a) a knowledgeable brute force attack or b) reverse engineering or c) some research in the cloud.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/cryptographic-issues.html#_forge_a_coupon_code_that_gives_you_a_discount_of_at_least_80' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html' + key: forgedCouponChallenge +- + name: 'Forged Feedback' + category: 'Broken Access Control' + tags: + - Tutorial + description: "Post some feedback in another user's name." + difficulty: 3 + hint: 'You can solve this by tampering with the user interface or by intercepting the communication with the RESTful backend.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_post_some_feedback_in_another_users_name' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html' + key: forgedFeedbackChallenge + tutorial: + order: 10 +- + name: 'Forged Review' + category: 'Broken Access Control' + description: 'Post a product review as another user or edit any user''s existing review.' + difficulty: 3 + hint: 'Observe the flow of product review posting and editing and see if you can exploit it.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_post_a_product_review_as_another_user_or_edit_any_users_existing_review' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html' + key: forgedReviewChallenge +- + name: 'Forged Signed JWT' + category: 'Vulnerable Components' + description: 'Forge an almost properly RSA-signed JWT token that impersonates the (non-existing) user rsa_lord@juice-sh.op.' + difficulty: 6 + hint: 'This challenge is explicitly not about acquiring the RSA private key used for JWT signing.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_forge_an_almost_properly_rsa_signed_jwt_token' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html' + key: jwtForgedChallenge + disabledEnv: + - Windows +- + name: 'Forgotten Developer Backup' + category: 'Sensitive Data Exposure' + tags: + - Contraption + - Good for Demos + - Prerequisite + description: 'Access a developer''s forgotten backup file.' + difficulty: 4 + hint: 'You need to trick a security mechanism into thinking that the file you want has a valid file type.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_access_a_developers_forgotten_backup_file' + mitigationUrl: ~ + key: forgottenDevBackupChallenge +- + name: 'Forgotten Sales Backup' + category: 'Sensitive Data Exposure' + tags: + - Contraption + description: 'Access a salesman''s forgotten backup file.' + difficulty: 4 + hint: 'You need to trick a security mechanism into thinking that the file you want has a valid file type.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_access_a_salesmans_forgotten_backup_file' + mitigationUrl: ~ + key: forgottenBackupChallenge +- + name: 'Frontend Typosquatting' + category: 'Vulnerable Components' + description: 'Inform the shop about a typosquatting imposter that dug itself deep into the frontend. (Mention the exact name of the culprit)' + difficulty: 5 + hint: '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?' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_inform_the_shop_about_a_typosquatting_imposter_that_dug_itself_deep_into_the_frontend' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerable_Dependency_Management_Cheat_Sheet.html' + key: typosquattingAngularChallenge +- + name: 'GDPR Data Erasure' + category: 'Broken Authentication' + description: 'Log in with Chris'' erased user account.' + difficulty: 3 + hint: 'Turns out that something is technically and legally wrong with the implementation of the "right to be forgotten" for users.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_log_in_with_chris_erased_user_account' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/User_Privacy_Protection_Cheat_Sheet.html' + key: ghostLoginChallenge +- + name: 'GDPR Data Theft' + category: 'Sensitive Data Exposure' + description: 'Steal someone else''s personal data without using Injection.' + difficulty: 4 + hint: 'Trick the regular Data Export to give you more than actually belongs to you.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_steal_someone_elses_personal_data_without_using_injection' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/User_Privacy_Protection_Cheat_Sheet.html' + key: dataExportChallenge +- + name: 'HTTP-Header XSS' + category: 'XSS' + tags: + - Danger Zone + description: 'Perform a persisted XSS attack with <iframe src="javascript:alert(`xss`)"> through an HTTP header.' + difficulty: 4 + hint: 'Finding a piece of displayed information that could originate from an HTTP header is part of this challenge.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_perform_a_persisted_xss_attack_through_an_http_header' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' + key: httpHeaderXssChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'Imaginary Challenge' + category: 'Cryptographic Issues' + tags: + - Shenanigans + - Code Analysis + description: 'Solve challenge #999. Unfortunately, this challenge does not exist.' + difficulty: 6 + hint: 'You need to trick the hacking progress persistence feature into thinking you solved challenge #999.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/cryptographic-issues.html#_solve_challenge_999' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html' + key: continueCodeChallenge +- + name: 'Leaked Access Logs' + category: 'Sensitive Data Exposure' + tags: + - OSINT + description: '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.)' + difficulty: 5 + hint: 'Once you have it, a technique called "Password Spraying" might prove useful.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_dumpster_dive_the_internet_for_a_leaked_password_and_log_in_to_the_original_user_account_it_belongs_to' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Credential_Stuffing_Prevention_Cheat_Sheet.html' + key: dlpPasswordSprayingChallenge +- + name: 'Leaked Unsafe Product' + category: 'Sensitive Data Exposure' + tags: + - Shenanigans + - OSINT + description: 'Identify an unsafe product that was removed from the shop and inform the shop which ingredients are dangerous.' + difficulty: 4 + hint: 'Your own SQLi and someone else''s Ctrl-V will be your accomplices in this challenge!' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_identify_an_unsafe_product_that_was_removed_from_the_shop_and_inform_the_shop_which_ingredients_are_dangerous' + mitigationUrl: ~ + key: dlpPastebinDataLeakChallenge +- + name: 'Legacy Typosquatting' + category: 'Vulnerable Components' + description: '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)' + difficulty: 4 + hint: 'This challenge has nothing to do with mistyping web domains. Investigate the forgotten developer''s backup file instead.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_inform_the_shop_about_a_typosquatting_trick_it_has_been_a_victim_of' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerable_Dependency_Management_Cheat_Sheet.html' + key: typosquattingNpmChallenge +- + name: 'Login Admin' + category: 'Injection' + tags: + - Tutorial + - Good for Demos + description: 'Log in with the administrator''s user account.' + difficulty: 2 + hint: 'Try different SQL Injection attack patterns depending whether you know the admin''s email address or not.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_log_in_with_the_administrators_user_account' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' + key: loginAdminChallenge + tutorial: + order: 6 +- + name: 'Login Amy' + category: 'Sensitive Data Exposure' + tags: + - OSINT + description: '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")' + difficulty: 3 + hint: 'This challenge will make you go after a needle in a haystack.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_log_in_with_amys_original_user_credentials' + mitigationUrl: ~ + key: loginAmyChallenge +- + name: 'Login Bender' + category: 'Injection' + tags: + - Tutorial + description: 'Log in with Bender''s user account.' + difficulty: 3 + hint: 'If you know Bender''s email address, try SQL Injection. Bender''s password hash might not help you very much.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_log_in_with_benders_user_account' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' + key: loginBenderChallenge + tutorial: + order: 12 +- + name: 'Login Bjoern' + category: 'Broken Authentication' + tags: + - Code Analysis + description: 'Log in with Bjoern''s Gmail account without previously changing his password, applying SQL Injection, or hacking his Google account.' + difficulty: 4 + hint: 'The security flaw behind this challenge is 100% OWASP Juice Shop''s fault and 0% Google''s.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_log_in_with_bjoerns_gmail_account' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html' + key: oauthUserPasswordChallenge +- + name: 'Login Jim' + category: 'Injection' + tags: + - Tutorial + description: 'Log in with Jim''s user account.' + difficulty: 3 + hint: 'Try cracking Jim''s password hash if you harvested it already. Alternatively, if you know Jim''s email address, try SQL Injection.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_log_in_with_jims_user_account' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' + key: loginJimChallenge + tutorial: + order: 11 +- + name: 'Login MC SafeSearch' + category: 'Sensitive Data Exposure' + tags: + - Shenanigans + - OSINT + description: 'Log in with MC SafeSearch''s original user credentials without applying SQL Injection or any other bypass.' + difficulty: 2 + hint: 'You should listen to MC''s hit song "Protect Ya Passwordz".' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_log_in_with_mc_safesearchs_original_user_credentials' + mitigationUrl: ~ + key: loginRapperChallenge +- + name: 'Login Support Team' + category: 'Security Misconfiguration' + tags: + - Brute Force + - Code Analysis + description: 'Log in with the support team''s original user credentials without applying SQL Injection or any other bypass.' + difficulty: 6 + hint: 'The underlying flaw of this challenge is a lot more human error than technical weakness.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-misconfiguration.html#_log_in_with_the_support_teams_original_user_credentials' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html' + key: loginSupportChallenge +- + name: 'Manipulate Basket' + category: 'Broken Access Control' + description: 'Put an additional product into another user''s shopping basket.' + difficulty: 3 + hint: '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.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_put_an_additional_product_into_another_users_shopping_basket' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html' + key: basketManipulateChallenge +- + name: 'Misplaced Signature File' + category: 'Sensitive Data Exposure' + tags: + - Good Practice + - Contraption + description: 'Access a misplaced SIEM signature file.' + difficulty: 4 + hint: 'You need to trick a security mechanism into thinking that the file you want has a valid file type.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_access_a_misplaced_siem_signature_file' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html' + key: misplacedSignatureFileChallenge +- + name: 'Multiple Likes' + category: 'Broken Anti Automation' + description: 'Like any review at least three times as the same user.' + difficulty: 6 + hint: 'Punctuality is the politeness of kings.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-anti-automation.html#_like_any_review_at_least_three_times_as_the_same_user' + mitigationUrl: ~ + key: timingAttackChallenge +- + name: 'Nested Easter Egg' + category: 'Cryptographic Issues' + tags: + - Shenanigans + - Good for Demos + description: 'Apply some advanced cryptanalysis to find the real easter egg.' + difficulty: 4 + hint: 'You might have to peel through several layers of tough-as-nails encryption for this challenge.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/cryptographic-issues.html#_apply_some_advanced_cryptanalysis_to_find_the_real_easter_egg' + mitigationUrl: ~ + key: easterEggLevelTwoChallenge +- + name: 'NoSQL DoS' + category: 'Injection' + tags: + - Danger Zone + description: 'Let the server sleep for some time. (It has done more than enough hard work for you)' + difficulty: 4 + hint: 'This challenge is essentially a stripped-down Denial of Service (DoS) attack.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_let_the_server_sleep_for_some_time' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html' + key: noSqlCommandChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'NoSQL Exfiltration' + category: 'Injection' + tags: + - Danger Zone + description: 'All your orders are belong to us! Even the ones which don''t.' + difficulty: 5 + hint: 'Take a close look on how the $where query operator works in MongoDB.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_all_your_orders_are_belong_to_us' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html' + key: noSqlOrdersChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'NoSQL Manipulation' + category: 'Injection' + description: 'Update multiple product reviews at the same time.' + difficulty: 4 + hint: 'Take a close look on how the equivalent of UPDATE-statements in MongoDB work.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_update_multiple_product_reviews_at_the_same_time' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html' + key: noSqlReviewsChallenge +- + name: 'Outdated Allowlist' + category: 'Unvalidated Redirects' + tags: + - Code Analysis + description: 'Let us redirect you to one of our crypto currency addresses which are not promoted any longer.' + difficulty: 1 + hint: 'We might have failed to take this out of our code properly.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/unvalidated-redirects.html#_let_us_redirect_you_to_one_of_our_crypto_currency_addresses' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html' + key: redirectCryptoCurrencyChallenge +- + name: 'Password Strength' + category: 'Broken Authentication' + tags: + - Brute Force + - Tutorial + description: 'Log in with the administrator''s user credentials without previously changing them or applying SQL Injection.' + difficulty: 2 + hint: 'This one should be equally easy to a) brute force, b) crack the password hash or c) simply guess.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_log_in_with_the_administrators_user_credentials_without_previously_changing_them_or_applying_sql_injection' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html' + key: weakPasswordChallenge + tutorial: + order: 8 +- + name: 'Payback Time' + category: 'Improper Input Validation' + description: 'Place an order that makes you rich.' + difficulty: 3 + hint: 'You literally need to make the shop owe you any amount of money.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_place_an_order_that_makes_you_rich' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html' + key: negativeOrderChallenge +- + name: 'Premium Paywall' + category: 'Cryptographic Issues' + tags: + - Shenanigans + description: ' Unlock Premium Challenge to access exclusive content.' + difficulty: 6 + hint: 'You do not have to pay anything to unlock this challenge! Nonetheless, donations are very much appreciated.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/cryptographic-issues.html#_unlock_premium_challenge_to_access_exclusive_content' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Key_Management_Cheat_Sheet.html' + key: premiumPaywallChallenge +- + name: 'Privacy Policy' + category: 'Miscellaneous' + tags: + - Good Practice + - Tutorial + - Good for Demos + description: 'Read our privacy policy.' + difficulty: 1 + hint: 'We won''t even ask you to confirm that you did. Just read it. Please. Pretty please.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/miscellaneous.html#_read_our_privacy_policy' + mitigationUrl: ~ + key: privacyPolicyChallenge + tutorial: + order: 4 +- + name: 'Privacy Policy Inspection' + category: 'Security through Obscurity' + tags: + - Shenanigans + - Good for Demos + description: 'Prove that you actually read our privacy policy.' + difficulty: 3 + hint: 'Only by visiting a special URL you can confirm that you read it carefully.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-through-obscurity.html#_prove_that_you_actually_read_our_privacy_policy' + mitigationUrl: ~ + key: privacyPolicyProofChallenge +- + name: 'Product Tampering' + category: 'Broken Access Control' + description: 'Change the href of the link within the OWASP SSL Advanced Forensic Tool (O-Saft) product description into https://owasp.slack.com.' + difficulty: 3 + hint: 'Look for one of the following: a) broken admin functionality, b) holes in RESTful API or c) possibility for SQL Injection.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_change_the_href_of_the_link_within_the_o_saft_product_description' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html' + key: changeProductChallenge +- + name: 'Reflected XSS' + category: 'XSS' + tags: + - Tutorial + - Danger Zone + - Good for Demos + description: 'Perform a reflected XSS attack with <iframe src="javascript:alert(`xss`)">.' + difficulty: 2 + hint: 'Look for a url parameter where its value appears in the page it is leading to.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_perform_a_reflected_xss_attack' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' + key: reflectedXssChallenge + tutorial: + order: 5 + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'Repetitive Registration' + category: 'Improper Input Validation' + description: 'Follow the DRY principle while registering a user.' + difficulty: 1 + hint: 'You can solve this by cleverly interacting with the UI or bypassing it altogether.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_follow_the_dry_principle_while_registering_a_user' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html' + key: passwordRepeatChallenge +- + name: 'Reset Bender''s Password' + category: 'Broken Authentication' + tags: + - OSINT + description: 'Reset Bender''s password via the Forgot Password mechanism with the original answer to his security question.' + difficulty: 4 + hint: 'Not as trivial as Jim''s but still not too difficult with some "Futurama" background knowledge.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_reset_benders_password_via_the_forgot_password_mechanism' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' + key: resetPasswordBenderChallenge +- + name: 'Reset Bjoern''s Password' + category: 'Broken Authentication' + tags: + - OSINT + description: 'Reset the password of Bjoern''s internal account via the Forgot Password mechanism with the original answer to his security question.' + difficulty: 5 + hint: 'Nothing a little bit of Facebook stalking couldn''t reveal. Might involve a historical twist.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_reset_the_password_of_bjoerns_internal_account_via_the_forgot_password_mechanism' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' + key: resetPasswordBjoernChallenge +- + name: 'Reset Jim''s Password' + category: 'Broken Authentication' + tags: + - OSINT + description: 'Reset Jim''s password via the Forgot Password mechanism with the original answer to his security question.' + difficulty: 3 + hint: 'It''s hard for celebrities to pick a security question from a hard-coded list where the answer is not publicly exposed.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_reset_jims_password_via_the_forgot_password_mechanism' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' + key: resetPasswordJimChallenge +- + name: 'Reset Morty''s Password' + category: 'Broken Anti Automation' + tags: + - OSINT + - Brute Force + description: 'Reset Morty''s password via the Forgot Password mechanism with his obfuscated answer to his security question.' + difficulty: 5 + hint: 'Find a way to bypass the rate limiting and brute force the obfuscated answer to Morty''s security question.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-anti-automation.html#_reset_mortys_password_via_the_forgot_password_mechanism' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Forgot_Password_Cheat_Sheet.html' + key: resetPasswordMortyChallenge +- + name: 'Retrieve Blueprint' + category: 'Sensitive Data Exposure' + description: 'Deprive the shop of earnings by downloading the blueprint for one of its products.' + difficulty: 5 + hint: 'The product you might want to give a closer look is the OWASP Juice Shop Logo (3D-printed).' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_deprive_the_shop_of_earnings_by_downloading_the_blueprint_for_one_of_its_products' + mitigationUrl: ~ + key: retrieveBlueprintChallenge +- + name: 'SSRF' + category: 'Broken Access Control' + tags: + - Code Analysis + description: 'Request a hidden resource on server through server.' + difficulty: 6 + hint: 'Reverse engineering something bad can make good things happen.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_request_a_hidden_resource_on_server_through_server' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html' + key: ssrfChallenge +- + name: 'SSTi' + category: 'Injection' + tags: + - Contraption + - Danger Zone + - Code Analysis + description: 'Infect the server with juicy malware by abusing arbitrary command execution.' + difficulty: 6 + hint: '"SSTi" is a clear indicator that this has nothing to do with anything Angular. Also, make sure to use only our non-malicious malware.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_infect_the_server_with_juicy_malware_by_abusing_arbitrary_command_execution' + mitigationUrl: ~ + key: sstiChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'Score Board' + category: 'Miscellaneous' + tags: + - Tutorial + - Code Analysis + description: 'Find the carefully hidden ''Score Board'' page.' + difficulty: 1 + hint: 'Try to find a reference or clue behind the scenes. Or simply guess what URL the Score Board might have.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/score-board.html#_find_the_carefully_hidden_score_board_page' + mitigationUrl: ~ + key: scoreBoardChallenge + tutorial: + order: 1 +- + name: 'Security Policy' + category: 'Miscellaneous' + tags: + - Good Practice + description: 'Behave like any "white-hat" should before getting into the action.' + difficulty: 2 + hint: 'Undoubtedly you want to read our security policy before conducting any research on our application.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/miscellaneous.html#_behave_like_any_white_hat_should_before_getting_into_the_action' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerability_Disclosure_Cheat_Sheet.html' + key: securityPolicyChallenge +- + name: 'Server-side XSS Protection' + category: 'XSS' + tags: + - Danger Zone + description: 'Perform a persisted XSS attack with <iframe src="javascript:alert(`xss`)"> bypassing a server-side security mechanism.' + difficulty: 4 + hint: 'The "Comment" field in the "Customer Feedback" screen is where you want to put your focus on.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_perform_a_persisted_xss_attack_bypassing_a_server_side_security_mechanism' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' + key: persistedXssFeedbackChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'Steganography' + category: 'Security through Obscurity' + tags: + - Shenanigans + description: 'Rat out a notorious character hiding in plain sight in the shop. (Mention the exact name of the character)' + difficulty: 4 + hint: 'No matter how good your eyes are, you will need tool assistance for this challenge.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-through-obscurity.html#_rat_out_a_notorious_character_hiding_in_plain_sight_in_the_shop' + mitigationUrl: ~ + key: hiddenImageChallenge +- + name: 'Successful RCE DoS' + category: 'Insecure Deserialization' + tags: + - Danger Zone + description: 'Perform a Remote Code Execution that occupies the server for a while without using infinite loops.' + difficulty: 6 + hint: 'Your attack payload must not trigger the protection against too many iterations.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/insecure-deserialization.html#_perform_a_remote_code_execution_that_occupies_the_server_for_a_while_without_using_infinite_loops' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html' + key: rceOccupyChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'Supply Chain Attack' + category: 'Vulnerable Components' + tags: + - OSINT + description: '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)' + difficulty: 5 + hint: 'This vulnerability will not affect any customer of the shop. It is aimed exclusively at its developers.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_inform_the_development_team_about_a_danger_to_some_of_their_credentials' + mitigationUrl: ~ + key: supplyChainAttackChallenge +- + name: 'Two Factor Authentication' + category: 'Broken Authentication' + description: 'Solve the 2FA challenge for user "wurstbrot". (Disabling, bypassing or overwriting his 2FA settings does not count as a solution)' + difficulty: 5 + hint: '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.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-authentication.html#_solve_the_2fa_challenge_for_user_wurstbrot' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Multifactor_Authentication_Cheat_Sheet.html' + key: twoFactorAuthUnsafeSecretStorageChallenge +- + name: 'Unsigned JWT' + category: 'Vulnerable Components' + description: 'Forge an essentially unsigned JWT token that impersonates the (non-existing) user jwtn3d@juice-sh.op.' + difficulty: 5 + hint: 'This challenge exploits a weird option that is supported when signing tokens with JWT.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_forge_an_essentially_unsigned_jwt_token' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html' + key: jwtUnsignedChallenge +- + name: 'Upload Size' + category: 'Improper Input Validation' + description: 'Upload a file larger than 100 kB.' + difficulty: 3 + hint: 'You can attach a small file to the "Complaint" form. Investigate how this upload actually works.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_upload_a_file_larger_than_100_kb' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html' + key: uploadSizeChallenge +- + name: 'Upload Type' + category: 'Improper Input Validation' + description: 'Upload a file that has no .pdf or .zip extension.' + difficulty: 3 + hint: 'You can attach a PDF or ZIP file to the "Complaint" form. Investigate how this upload actually works.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_upload_a_file_that_has_no_pdf_or_zip_extension' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html' + key: uploadTypeChallenge +- + name: 'User Credentials' + category: 'Injection' + description: 'Retrieve a list of all user credentials via SQL Injection.' + difficulty: 4 + hint: 'Gather information on where user data is stored and how it is addressed. Then craft a corresponding UNION SELECT attack.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/injection.html#_retrieve_a_list_of_all_user_credentials_via_sql_injection' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html' + key: unionSqlInjectionChallenge +- + name: 'Video XSS' + category: 'XSS' + tags: + - Danger Zone + description: 'Embed an XSS payload </script><script>alert(`xss`)</script> into our promo video.' + difficulty: 6 + hint: 'You have to reuse the vulnerability behind one other 6-star challenge to be able to solve this one.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_embed_an_xss_payload_into_our_promo_video' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html' + key: videoXssChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'View Basket' + category: 'Broken Access Control' + tags: + - Tutorial + - Good for Demos + description: 'View another user''s shopping basket.' + difficulty: 2 + hint: 'Have an eye on the HTTP traffic while shopping. Alternatively try to find a client-side association of users to their basket.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_view_another_users_shopping_basket' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html' + key: basketAccessChallenge + tutorial: + order: 9 +- + name: 'Vulnerable Library' + category: 'Vulnerable Components' + tags: + - OSINT + description: 'Inform the shop about a vulnerable library it is using. (Mention the exact library name and version in your comment)' + difficulty: 4 + hint: 'Report one of two possible answers via the "Customer Feedback" form. Do not forget to submit the library''s version as well.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_inform_the_shop_about_a_vulnerable_library_it_is_using' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerability_Disclosure_Cheat_Sheet.html' + key: knownVulnerableComponentChallenge +- + name: 'Weird Crypto' + category: 'Cryptographic Issues' + description: 'Inform the shop about an algorithm or library it should definitely not use the way it does.' + difficulty: 2 + hint: 'Report one of four possible answers via the "Customer Feedback" form.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/cryptographic-issues.html#_inform_the_shop_about_an_algorithm_or_library_it_should_definitely_not_use_the_way_it_does' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerability_Disclosure_Cheat_Sheet.html' + key: weirdCryptoChallenge +- + name: 'Allowlist Bypass' + category: 'Unvalidated Redirects' + tags: + - Prerequisite + description: 'Enforce a redirect to a page you are not supposed to redirect to.' + difficulty: 4 + hint: 'You have to find a way to beat the allowlist of allowed redirect URLs.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/unvalidated-redirects.html#_enforce_a_redirect_to_a_page_you_are_not_supposed_to_redirect_to' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html' + key: redirectChallenge +- + name: 'XXE Data Access' + category: 'XXE' + tags: + - Danger Zone + description: 'Retrieve the content of C:\Windows\system.ini or /etc/passwd from the server.' + difficulty: 3 + hint: 'The leverage point for this challenge is the deprecated B2B interface.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xxe.html#_retrieve_the_content_of_cwindowssystemini_or_etcpasswd_from_the_server' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html' + key: xxeFileDisclosureChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'XXE DoS' + category: 'XXE' + tags: + - Danger Zone + description: 'Give the server something to chew on for quite a while.' + difficulty: 5 + hint: 'It is not as easy as sending a large amount of data directly to the deprecated B2B interface.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xxe.html#_give_the_server_something_to_chew_on_for_quite_a_while' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html' + key: xxeDosChallenge + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'Zero Stars' + category: 'Improper Input Validation' + description: 'Give a devastating zero-star feedback to the store.' + difficulty: 1 + hint: 'Before you invest time bypassing the API, you might want to play around with the UI a bit.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_give_a_devastating_zero_star_feedback_to_the_store' + mitigationUrl: ~ + key: zeroStarsChallenge +- + name: 'Missing Encoding' + category: 'Improper Input Validation' + tags: + - Shenanigans + description: 'Retrieve the photo of Bjoern''s cat in "melee combat-mode".' + difficulty: 1 + hint: 'Check the Photo Wall for an image that could not be loaded correctly.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_retrieve_the_photo_of_bjoerns_cat_in_melee_combat_mode' + mitigationUrl: ~ + key: missingEncodingChallenge +- + name: 'Cross-Site Imaging' + category: 'Security Misconfiguration' + tags: + - Contraption + description: 'Stick cute cross-domain kittens all over our delivery boxes.' + difficulty: 5 + hint: 'This challenge would formally have to be in several categories as the developers made multiple gaffes for this to be possible.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/security-misconfiguration.html#_stick_cute_cross_domain_kittens_all_over_our_delivery_boxes' + mitigationUrl: ~ + key: svgInjectionChallenge +- + name: 'Exposed Metrics' + category: 'Sensitive Data Exposure' + tags: + - Good Practice + description: 'Find the endpoint that serves usage data to be scraped by a popular monitoring system.' + difficulty: 1 + hint: 'Try to guess what URL the endpoint might have.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_find_the_endpoint_that_serves_usage_data_to_be_scraped_by_a_popular_monitoring_system' + mitigationUrl: ~ + key: exposedMetricsChallenge +- + name: 'Deluxe Fraud' + category: 'Improper Input Validation' + description: 'Obtain a Deluxe Membership without paying for it.' + difficulty: 3 + hint: 'Look closely at what happens when you attempt to upgrade your account.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_obtain_a_deluxe_membership_without_paying_for_it' + mitigationUrl: ~ + key: freeDeluxeChallenge +- + name: 'CSRF' # FIXME No e2e test automation! No longer works in Chrome >=80 and Firefox >=100 or other latest browsers! + category: 'Broken Access Control' + description: 'Change the name of a user by performing Cross-Site Request Forgery from another origin.' + difficulty: 3 + hint: 'Find a form which updates the username and then construct a malicious page in the online HTML editor. You probably need an older browser version for this.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/broken-access-control.html#_change_the_name_of_a_user_by_performing_cross_site_request_forgery_from_another_origin' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html' + key: csrfChallenge +- + name: 'Bonus Payload' + category: 'XSS' + tags: + - Shenanigans + - Tutorial + description: '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.' + difficulty: 1 + hint: 'Copy + Paste = Solved!' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/xss.html#_use_the_bonus_payload_in_the_dom_xss_challenge' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html' + key: xssBonusChallenge + tutorial: + order: 3 +- + name: 'Reset Uvogin''s Password' + category: 'Sensitive Data Exposure' + tags: + - OSINT + description: 'Reset Uvogin''s password via the Forgot Password mechanism with the original answer to his security question.' + difficulty: 4 + hint: 'You might have to do some OSINT on his social media personas to find out his honest answer to the security question.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_reset_uvogins_password_via_the_forgot_password_mechanism' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' + key: resetPasswordUvoginChallenge +- + name: 'Meta Geo Stalking' + category: 'Sensitive Data Exposure' + tags: + - OSINT + description: '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.' + difficulty: 2 + hint: 'Take a look at the meta data of the corresponding photo.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_determine_the_answer_to_johns_security_question' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' + key: geoStalkingMetaChallenge +- + name: 'Visual Geo Stalking' + category: 'Sensitive Data Exposure' + tags: + - OSINT + description: '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.' + difficulty: 2 + hint: 'Take a look at the details in the photo to determine the location of where it was taken.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/sensitive-data-exposure.html#_determine_the_answer_to_emmas_security_question' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Choosing_and_Using_Security_Questions_Cheat_Sheet.html' + key: geoStalkingVisualChallenge +- + name: 'Kill Chatbot' + category: 'Vulnerable Components' + tags: + - Code Analysis + description: 'Permanently disable the support chatbot so that it can no longer answer customer queries.' + difficulty: 5 + hint: 'Think of a way to get a hold of the internal workings on the chatbot API.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_permanently_disable_the_support_chatbot' + mitigationUrl: 'https://cheatsheetseries.owasp.org/cheatsheets/Vulnerable_Dependency_Management_Cheat_Sheet.html' + key: killChatbotChallenge +- + name: 'Poison Null Byte' + category: 'Improper Input Validation' + tags: + - Prerequisite + description: 'Bypass a security control with a Poison Null Byte to access a file not meant for your eyes.' + difficulty: 4 + hint: 'Take a look at the details in the photo to determine the location of where it was taken.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/improper-input-validation.html#_bypass_a_security_control_with_a_poison_null_byte' + mitigationUrl: ~ + key: nullByteChallenge +- + name: 'Bully Chatbot' + category: 'Miscellaneous' + tags: + - Shenanigans + - Brute Force + description: 'Receive a coupon code from the support chatbot.' + difficulty: 1 + hint: 'Just keep asking.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/miscellaneous.html#_receive_a_coupon_code_from_the_support_chatbot' + mitigationUrl: ~ + key: bullyChatbotChallenge +- + name: 'Local File Read' + category: 'Vulnerable Components' + tags: + - OSINT + - Danger Zone + difficulty: 5 + hint: 'You should read up on vulnerabilities in popular NodeJs template engines.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/vulnerable-components.html#_gain_read_access_to_an_arbitrary_local_file_on_the_web_server' + description: 'Gain read access to an arbitrary local file on the web server.' + key: 'lfrChallenge' + disabledEnv: + - Docker + - Heroku + - Gitpod +- + name: 'Mass Dispel' + category: 'Miscellaneous' + description: 'Close multiple "Challenge solved"-notifications in one go.' + difficulty: 1 + hint: 'Either check the official documentation or inspect a notification UI element directly.' + hintUrl: 'https://pwning.owasp-juice.shop/companion-guide/latest/part2/score-board.html#_close_multiple_challenge_solved_notifications_in_one_go' + mitigationUrl: ~ + key: closeNotificationsChallenge +- + name: 'Security Advisory' + category: 'Miscellaneous' + description: ' The Juice Shop is susceptible to a known vulnerability in a library, for which an advisory has already been issued, marking the Juice Shop as known affected. A fix is still pending. Inform the shop about a suitable checksum as proof that you did your due diligence.' + difficulty: 3 + hint: 'Security Advisories are often listed in the security.txt' + hintUrl: '' + mitigationUrl: ~ + key: csafChallenge diff --git a/data/static/contractABIs.ts b/data/static/contractABIs.ts index 0a16c138..b4e1f81b 100644 --- a/data/static/contractABIs.ts +++ b/data/static/contractABIs.ts @@ -1,569 +1,569 @@ -export const nftABI = [ - { - inputs: [], - stateMutability: 'nonpayable', - type: 'constructor' - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'owner', - type: 'address' - }, - { - indexed: true, - internalType: 'address', - name: 'approved', - type: 'address' - }, - { - indexed: true, - internalType: 'uint256', - name: 'tokenId', - type: 'uint256' - } - ], - name: 'Approval', - type: 'event' - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'owner', - type: 'address' - }, - { - indexed: true, - internalType: 'address', - name: 'operator', - type: 'address' - }, - { - indexed: false, - internalType: 'bool', - name: 'approved', - type: 'bool' - } - ], - name: 'ApprovalForAll', - type: 'event' - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'owner', - type: 'address' - }, - { - indexed: false, - internalType: 'uint256', - name: 'tokenId', - type: 'uint256' - } - ], - name: 'NFTMinted', - type: 'event' - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'previousOwner', - type: 'address' - }, - { - indexed: true, - internalType: 'address', - name: 'newOwner', - type: 'address' - } - ], - name: 'OwnershipTransferred', - type: 'event' - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'from', - type: 'address' - }, - { - indexed: true, - internalType: 'address', - name: 'to', - type: 'address' - }, - { - indexed: true, - internalType: 'uint256', - name: 'tokenId', - type: 'uint256' - } - ], - name: 'Transfer', - type: 'event' - }, - { - inputs: [ - { - internalType: 'address', - name: 'to', - type: 'address' - }, - { - internalType: 'uint256', - name: 'tokenId', - type: 'uint256' - } - ], - name: 'approve', - outputs: [], - stateMutability: 'nonpayable', - type: 'function' - }, - { - inputs: [ - { - internalType: 'address', - name: 'owner', - type: 'address' - } - ], - name: 'balanceOf', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [], - name: 'fixedMetadataHash', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'tokenId', - type: 'uint256' - } - ], - name: 'getApproved', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [ - { - internalType: 'address', - name: 'owner', - type: 'address' - }, - { - internalType: 'address', - name: 'operator', - type: 'address' - } - ], - name: 'isApprovedForAll', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [], - name: 'mintNFT', - outputs: [], - stateMutability: 'nonpayable', - type: 'function' - }, - { - inputs: [], - name: 'mintPrice', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [], - name: 'name', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [], - name: 'owner', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'tokenId', - type: 'uint256' - } - ], - name: 'ownerOf', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [], - name: 'renounceOwnership', - outputs: [], - stateMutability: 'nonpayable', - type: 'function' - }, - { - inputs: [ - { - internalType: 'address', - name: 'from', - type: 'address' - }, - { - internalType: 'address', - name: 'to', - type: 'address' - }, - { - internalType: 'uint256', - name: 'tokenId', - type: 'uint256' - } - ], - name: 'safeTransferFrom', - outputs: [], - stateMutability: 'nonpayable', - type: 'function' - }, - { - inputs: [ - { - internalType: 'address', - name: 'from', - type: 'address' - }, - { - internalType: 'address', - name: 'to', - type: 'address' - }, - { - internalType: 'uint256', - name: 'tokenId', - type: 'uint256' - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes' - } - ], - name: 'safeTransferFrom', - outputs: [], - stateMutability: 'nonpayable', - type: 'function' - }, - { - inputs: [ - { - internalType: 'address', - name: 'operator', - type: 'address' - }, - { - internalType: 'bool', - name: 'approved', - type: 'bool' - } - ], - name: 'setApprovalForAll', - outputs: [], - stateMutability: 'nonpayable', - type: 'function' - }, - { - inputs: [ - { - internalType: 'bytes4', - name: 'interfaceId', - type: 'bytes4' - } - ], - name: 'supportsInterface', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [], - name: 'symbol', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [], - name: 'token', - outputs: [ - { - internalType: 'contract IERC20', - name: '', - type: 'address' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'tokenId', - type: 'uint256' - } - ], - name: 'tokenURI', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [], - name: 'totalSupply', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [ - { - internalType: 'address', - name: 'from', - type: 'address' - }, - { - internalType: 'address', - name: 'to', - type: 'address' - }, - { - internalType: 'uint256', - name: 'tokenId', - type: 'uint256' - } - ], - name: 'transferFrom', - outputs: [], - stateMutability: 'nonpayable', - type: 'function' - }, - { - inputs: [ - { - internalType: 'address', - name: 'newOwner', - type: 'address' - } - ], - name: 'transferOwnership', - outputs: [], - stateMutability: 'nonpayable', - type: 'function' - } -] -export const web3WalletABI = [ - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'culprit', - type: 'address' - } - ], - name: 'ContractExploited', - type: 'event' - }, - { - inputs: [ - { - internalType: 'address', - name: '_who', - type: 'address' - } - ], - name: 'balanceOf', - outputs: [ - { - internalType: 'uint256', - name: 'balance', - type: 'uint256' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address' - } - ], - name: 'balances', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [ - { - internalType: 'address', - name: '_to', - type: 'address' - } - ], - name: 'ethdeposit', - outputs: [], - stateMutability: 'payable', - type: 'function' - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address' - } - ], - name: 'userWithdrawing', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256' - } - ], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [ - { - internalType: 'uint256', - name: '_amount', - type: 'uint256' - } - ], - name: 'withdraw', - outputs: [], - stateMutability: 'nonpayable', - type: 'function' - }, - { - stateMutability: 'payable', - type: 'receive' - } -] +export const nftABI = [ + { + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'approved', + type: 'address' + }, + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256' + } + ], + name: 'Approval', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'operator', + type: 'address' + }, + { + indexed: false, + internalType: 'bool', + name: 'approved', + type: 'bool' + } + ], + name: 'ApprovalForAll', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256' + } + ], + name: 'NFTMinted', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address' + } + ], + name: 'OwnershipTransferred', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address' + }, + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256' + } + ], + name: 'Transfer', + type: 'event' + }, + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address' + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256' + } + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address' + } + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'fixedMetadataHash', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256' + } + ], + name: 'getApproved', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + internalType: 'address', + name: 'operator', + type: 'address' + } + ], + name: 'isApprovedForAll', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'mintNFT', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'mintPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'name', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256' + } + ], + name: 'ownerOf', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address' + }, + { + internalType: 'address', + name: 'to', + type: 'address' + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256' + } + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address' + }, + { + internalType: 'address', + name: 'to', + type: 'address' + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'operator', + type: 'address' + }, + { + internalType: 'bool', + name: 'approved', + type: 'bool' + } + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: 'interfaceId', + type: 'bytes4' + } + ], + name: 'supportsInterface', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'symbol', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'token', + outputs: [ + { + internalType: 'contract IERC20', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256' + } + ], + name: 'tokenURI', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address' + }, + { + internalType: 'address', + name: 'to', + type: 'address' + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256' + } + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address' + } + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + } +] +export const web3WalletABI = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'culprit', + type: 'address' + } + ], + name: 'ContractExploited', + type: 'event' + }, + { + inputs: [ + { + internalType: 'address', + name: '_who', + type: 'address' + } + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: 'balance', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'balances', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_to', + type: 'address' + } + ], + name: 'ethdeposit', + outputs: [], + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'userWithdrawing', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_amount', + type: 'uint256' + } + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + stateMutability: 'payable', + type: 'receive' + } +] diff --git a/data/static/deliveries.yml b/data/static/deliveries.yml index 7e0070bf..2c3f86d8 100644 --- a/data/static/deliveries.yml +++ b/data/static/deliveries.yml @@ -1,18 +1,18 @@ -- - name: 'One Day Delivery' - price: 0.99 - deluxePrice: 0.5 - eta: 1 - icon: 'fas fa-rocket' -- - name: 'Fast Delivery' - price: 0.5 - deluxePrice: 0 - eta: 3 - icon: 'fas fa-shipping-fast' -- - name: 'Standard Delivery' - price: 0 - deluxePrice: 0 - eta: 5 +- + name: 'One Day Delivery' + price: 0.99 + deluxePrice: 0.5 + eta: 1 + icon: 'fas fa-rocket' +- + name: 'Fast Delivery' + price: 0.5 + deluxePrice: 0 + eta: 3 + icon: 'fas fa-shipping-fast' +- + name: 'Standard Delivery' + price: 0 + deluxePrice: 0 + eta: 5 icon: 'fas fa-truck' \ No newline at end of file diff --git a/data/static/i18n/ar_SA.json b/data/static/i18n/ar_SA.json index e01152f0..b2275c7e 100644 --- a/data/static/i18n/ar_SA.json +++ b/data/static/i18n/ar_SA.json @@ -1,467 +1,467 @@ -{ - "Find the carefully hidden 'Score Board' page.": "ابحث عن صفحة \"لوحة النتائج\" المخفية بعناية (Score Board).", - "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.", - "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.", - "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%.", - "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.": "قم بتسجيل الدخول بحساب Jim.", - "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.": "ضع طلبًا يجعلك غنيًا.", - "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.": "اقرأ سياسة الخصوصية.", - "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.": "أثبت أنك قرأت سياسة الخصوصية الخاصة بنا بالفعل.", - "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.", - "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.": "حمل ملف أكبر من 100 كيلو بايت. (100kB).", - "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.": "قم بتحميل ملف لا يحتوي على ملحق .pdf أو .zip.", - "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.": "أعرض سلة تسوق مستخدم آخر.", - "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 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?": "اسم حيوانك الأليف المفضل؟", - "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?": "اسم الشركة التي اشتغلت فيها؟", - "Your favorite book?": "كتابك المفضل؟", - "Your favorite movie?": "الفيلم المفضل لديك؟", - "Number of one of your customer or ID cards?": "Number of one of your customer or ID cards?", - "Apple Juice (1000ml)": "عصير التفاح (1000 مل)", - "The all-time classic.": "The all-time classic.", - "Orange Juice (1000ml)": "عصير برتقال (1000 مل)", - "Made from oranges hand-picked by Uncle Dittmeyer.": "Made from oranges hand-picked by Uncle Dittmeyer.", - "Eggfruit Juice (500ml)": "عصير بيض و فواكه (500 مل)", - "Now with even more exotic flavour.": "Now with even more exotic flavour.", - "Raspberry Juice (1000ml)": "عصير التوت (1000 مل)", - "Made from blended Raspberry Pi, water and sugar.": "Made from blended Raspberry Pi, water and sugar.", - "Lemon Juice (500ml)": "عصير ليمون (500 مل)", - "Sour but full of vitamins.": "حامض ولكن مليئة بالفيتامينات.", - "Banana Juice (1000ml)": "عصير موز (1000 مل)", - "Monkeys love it the most.": "القرود تحبها أكثر.", - "OWASP Juice Shop T-Shirt": "قميص OWASP Juice Shop", - "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 الخاص", - "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", - "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", - "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": "عصير الأخضر", - "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)": "عصير سفرجل (1000 مل)", - "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": "تفاح البوماس", - "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": "عصارة فواكه", - "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": "الاعمال الفنية بالمتجر", - "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)": "عصير الفراولة (500 مل)", - "Sweet & tasty!": "حلو ولذيذ!", - "Carrot Juice (1000ml)": "عصير جزر (1000 مل)", - "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": "تهكير 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": "سعر التوصيل", - "Total Price": "السعر الإجمالي", - "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!": "شكرا لكم على تقديم طلبكم!", - "Order Confirmation": "تأكيد الطلب", - "Customer": "الزبون", - "Order": "الطلبية", - "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.": "البريد الإلكتروني أو كلمة المرور غير صحيح.", - "Current password is not correct.": "كلمة المرور الحاليّة غير صحيحة.", - "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", - "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 ') - }, - { - text: 'Make sure your speaker volume is cranked up. Then hit enter.', - fixture: '.fill-remaining-space', - unskippable: true, - resolved: waitForElementsInnerHtmlToBe('#searchValue', '') - }, - { - text: - '🎉 Congratulations and enjoy the music!', - fixture: '.noResult', - resolved: waitInMs(5000) - } - ] -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import { + waitForInputToHaveValue, + waitForElementsInnerHtmlToBe, + waitInMs +} from '../helpers/helpers' +import { type ChallengeInstruction } from '../' + +export const BonusPayloadInstruction: ChallengeInstruction = { + name: 'Bonus Payload', + hints: [ + { + text: + 'Assuming you did the **DOM XSS** tutorial already, this one just uses a funnier payload on the _Search_ field.', + fixture: '.fill-remaining-space', + unskippable: true, + resolved: waitInMs(10000) // TODO Add check if "DOM XSS" is solved and if not recommend doing that first + }, + { + text: 'Enter or paste this payload into the _Search_ field: <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>.', + fixture: '.fill-remaining-space', + unskippable: true, + resolved: waitForInputToHaveValue('#searchQuery input', '') + }, + { + text: 'Make sure your speaker volume is cranked up. Then hit enter.', + fixture: '.fill-remaining-space', + unskippable: true, + resolved: waitForElementsInnerHtmlToBe('#searchValue', '') + }, + { + text: + '🎉 Congratulations and enjoy the music!', + fixture: '.noResult', + resolved: waitInMs(5000) + } + ] +} diff --git a/frontend/src/hacking-instructor/challenges/codingChallenges.ts b/frontend/src/hacking-instructor/challenges/codingChallenges.ts index abca9451..8c9c6bea 100644 --- a/frontend/src/hacking-instructor/challenges/codingChallenges.ts +++ b/frontend/src/hacking-instructor/challenges/codingChallenges.ts @@ -1,92 +1,92 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import { - waitInMs, waitForElementToGetClicked, waitForAngularRouteToBeVisited -} from '../helpers/helpers' -import { type ChallengeInstruction } from '../' - -export const CodingChallengesInstruction: ChallengeInstruction = { - name: 'Coding Challenges', - hints: [ - { - text: - 'To do the tutorial on _Coding Challenges_, you have to find and visit the _Score Board_ first. Once there, you have to click the tutorial button for the _Score Board_ challenge to proceed.', - fixture: 'app-navbar', - fixtureAfter: true, - unskippable: true, - resolved: waitForAngularRouteToBeVisited('score-board') // FIXME The tutorial does not progress automatically. Workaround ^^^^^^^^^^^^^^^^ instruction above should be removed when fixed. - }, - { - text: - 'Many Juice Shop hacking challenges come with an associated _Coding Challenge_ which will teach you more about the underlying vulnerability on source code level.', - fixture: '#Score\\ Board\\.solved', - resolved: waitInMs(15000) - }, - { - text: - 'You can launch a Coding Challenge via the `<>`-button. Click the one for the _Score Board_ challenge now.', - fixture: '#codingChallengeTutorialButton', - unskippable: true, - resolved: waitForElementToGetClicked('#Score\\ Board\\.codingChallengeButton') - }, - { - text: - 'All Coding Challenges take place in a modal dialog like this. They consist of two parts, one for finding and one for fixing the vulnerability in the code.', - fixture: '#code-snippet', - resolved: waitInMs(15000) - }, - { - text: - 'The code snippet below shows a part of the actual application source code retrieved in real-time.', - fixture: '#code-snippet', - resolved: waitInMs(10000) - }, - { - text: - 'You will always get a snippet that is involved in the security vulnerability or flaw behind the corresponding hacking challenge. In this case, you see the routing code that exposes all dialogs, including the supposedly "well-hidden" Score Board.', - fixture: '#code-snippet', - resolved: waitInMs(20000) - }, - { - text: - 'For the "Find It" part of this coding challenge, tick the 🔲 on all lines of code that you think are responsible for exposing the Score Board. When done, click the _Submit_ button.', - fixture: '#code-snippet', - fixtureAfter: true, - unskippable: true, - resolved: waitForElementToGetClicked('#line114') - }, - { - text: - 'That\'s the one! Click the _Submit_ button proceed.', - fixture: '#code-snippet', - fixtureAfter: true, - unskippable: true, - resolved: waitForElementToGetClicked('#findItSubmitButton') - }, - { - text: - '🎊! You made it half-way through! In phase two you are now presented with several fix options. You must select the one which you think is the **best possible** fix for the security vulnerability.', - fixture: '#code-snippet', - resolved: waitInMs(10000) - }, - { - text: - 'This coding challenge is a bit "special", because the Score Board is crucial for progress tracking and acts as a hub for the other challenges. Keep that in mind when picking the _Correct Fix_ from the options _Fix 1_, _2_ and _3_.', - fixture: '#code-snippet', - fixtureAfter: true, - unskippable: true, - resolved: waitForElementToGetClicked('#fixItSubmitButton') - }, - { - text: - 'If you did\'nt get the answer right, just try again until the 🎊-cannon fires. Then click _Close_ to end the coding challenge and return to the Score Board.', - fixture: '#code-snippet', - fixtureAfter: true, - unskippable: true, - resolved: waitForElementToGetClicked('#fixItCloseButton') - } - ] -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import { + waitInMs, waitForElementToGetClicked, waitForAngularRouteToBeVisited +} from '../helpers/helpers' +import { type ChallengeInstruction } from '../' + +export const CodingChallengesInstruction: ChallengeInstruction = { + name: 'Coding Challenges', + hints: [ + { + text: + 'To do the tutorial on _Coding Challenges_, you have to find and visit the _Score Board_ first. Once there, you have to click the tutorial button for the _Score Board_ challenge to proceed.', + fixture: 'app-navbar', + fixtureAfter: true, + unskippable: true, + resolved: waitForAngularRouteToBeVisited('score-board') // FIXME The tutorial does not progress automatically. Workaround ^^^^^^^^^^^^^^^^ instruction above should be removed when fixed. + }, + { + text: + 'Many Juice Shop hacking challenges come with an associated _Coding Challenge_ which will teach you more about the underlying vulnerability on source code level.', + fixture: '#Score\\ Board\\.solved', + resolved: waitInMs(15000) + }, + { + text: + 'You can launch a Coding Challenge via the `<>`-button. Click the one for the _Score Board_ challenge now.', + fixture: '#codingChallengeTutorialButton', + unskippable: true, + resolved: waitForElementToGetClicked('#Score\\ Board\\.codingChallengeButton') + }, + { + text: + 'All Coding Challenges take place in a modal dialog like this. They consist of two parts, one for finding and one for fixing the vulnerability in the code.', + fixture: '#code-snippet', + resolved: waitInMs(15000) + }, + { + text: + 'The code snippet below shows a part of the actual application source code retrieved in real-time.', + fixture: '#code-snippet', + resolved: waitInMs(10000) + }, + { + text: + 'You will always get a snippet that is involved in the security vulnerability or flaw behind the corresponding hacking challenge. In this case, you see the routing code that exposes all dialogs, including the supposedly "well-hidden" Score Board.', + fixture: '#code-snippet', + resolved: waitInMs(20000) + }, + { + text: + 'For the "Find It" part of this coding challenge, tick the 🔲 on all lines of code that you think are responsible for exposing the Score Board. When done, click the _Submit_ button.', + fixture: '#code-snippet', + fixtureAfter: true, + unskippable: true, + resolved: waitForElementToGetClicked('#line114') + }, + { + text: + 'That\'s the one! Click the _Submit_ button proceed.', + fixture: '#code-snippet', + fixtureAfter: true, + unskippable: true, + resolved: waitForElementToGetClicked('#findItSubmitButton') + }, + { + text: + '🎊! You made it half-way through! In phase two you are now presented with several fix options. You must select the one which you think is the **best possible** fix for the security vulnerability.', + fixture: '#code-snippet', + resolved: waitInMs(10000) + }, + { + text: + 'This coding challenge is a bit "special", because the Score Board is crucial for progress tracking and acts as a hub for the other challenges. Keep that in mind when picking the _Correct Fix_ from the options _Fix 1_, _2_ and _3_.', + fixture: '#code-snippet', + fixtureAfter: true, + unskippable: true, + resolved: waitForElementToGetClicked('#fixItSubmitButton') + }, + { + text: + 'If you did\'nt get the answer right, just try again until the 🎊-cannon fires. Then click _Close_ to end the coding challenge and return to the Score Board.', + fixture: '#code-snippet', + fixtureAfter: true, + unskippable: true, + resolved: waitForElementToGetClicked('#fixItCloseButton') + } + ] +} diff --git a/frontend/src/hacking-instructor/challenges/domXss.ts b/frontend/src/hacking-instructor/challenges/domXss.ts index e90bc6f8..65f68bc1 100644 --- a/frontend/src/hacking-instructor/challenges/domXss.ts +++ b/frontend/src/hacking-instructor/challenges/domXss.ts @@ -1,114 +1,114 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import { - waitForInputToHaveValue, - waitForElementsInnerHtmlToBe, - waitInMs -} from '../helpers/helpers' -import { type ChallengeInstruction } from '../' - -export const DomXssInstruction: ChallengeInstruction = { - name: 'DOM XSS', - hints: [ - { - text: - "For this challenge, we'll take a close look at the _Search_ field at the top of the screen.", - fixture: '.fill-remaining-space', - unskippable: true, - resolved: waitInMs(8000) - }, - { - text: "Let's start by searching for all products containing `owasp` in their name or description.", - fixture: '.fill-remaining-space', - unskippable: true, - resolved: waitForInputToHaveValue('#searchQuery input', 'owasp') - }, - { - text: 'Now hit enter.', - fixture: '.fill-remaining-space', - unskippable: true, - resolved: waitForElementsInnerHtmlToBe('#searchValue', 'owasp') - }, - { - text: 'Nice! You should now see many cool OWASP-related products.', - fixture: '.fill-remaining-space', - resolved: waitInMs(8000) - }, - { - text: 'You might have noticed, that your search term is displayed above the results?', - fixture: 'app-search-result', - resolved: waitInMs(8000) - }, - { - text: 'What we will try now is a **Cross-Site Scripting (XSS)** attack, where we try to inject HTML or JavaScript code into the application.', - fixture: 'app-search-result', - resolved: waitInMs(15000) - }, - { - text: 'Change your search value into `

owasp` to see if we can inject HTML.', - fixture: '.fill-remaining-space', - unskippable: true, - resolved: waitForInputToHaveValue('#searchQuery input', '

owasp') - }, - { - text: 'Hit enter again.', - fixture: '.fill-remaining-space', - unskippable: true, - resolved: waitForElementsInnerHtmlToBe('#searchValue', '

owasp

') // Browsers will autocorrect the unclosed tag. - }, - { - text: "Hmm, this doesn't look normal, does it?", - fixture: '.noResult', - resolved: waitInMs(8000) - }, - { - text: 'If you right-click on the search term and inspect that part of the page with your browser, you will see that our `h1`-tag was _actually_ embedded into the page and is not just shown as plain text!', - fixture: '.noResult', - resolved: waitInMs(16000) - }, - { - text: "Let's now try to inject JavaScript. Type `` into the search box now.", - fixture: '.fill-remaining-space', - unskippable: true, - resolved: waitForInputToHaveValue('#searchQuery input', '') - }, - { - text: 'Hit enter again.', - fixture: '.fill-remaining-space', - unskippable: true, - resolved: waitForElementsInnerHtmlToBe('#searchValue', '') - }, - { - text: "😔 This didn't work as we hoped. If you inspect the page, you should see the `script`-tag but it is not executed for some reason.", - fixture: '.noResult', - resolved: waitInMs(10000) - }, - { - text: "Luckily there are _many_ different XSS payloads we can try. Let's try this one next: <iframe src=\"javascript:alert(`xss`)\">.", - fixture: '.fill-remaining-space', - unskippable: true, - resolved: waitForInputToHaveValue('#searchQuery input', '') - }, - { - text: - '🎉 Congratulations! You just successfully performed an XSS attack!', - fixture: '.noResult', - resolved: waitInMs(8000) - }, - { - text: - 'More precisely, this was a **DOM XSS** attack, because your payload was handled and improperly embedded into the page by the application frontend code without even sending it to the server.', - fixture: '.noResult', - resolved: waitInMs(16000) - } - ] -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import { + waitForInputToHaveValue, + waitForElementsInnerHtmlToBe, + waitInMs +} from '../helpers/helpers' +import { type ChallengeInstruction } from '../' + +export const DomXssInstruction: ChallengeInstruction = { + name: 'DOM XSS', + hints: [ + { + text: + "For this challenge, we'll take a close look at the _Search_ field at the top of the screen.", + fixture: '.fill-remaining-space', + unskippable: true, + resolved: waitInMs(8000) + }, + { + text: "Let's start by searching for all products containing `owasp` in their name or description.", + fixture: '.fill-remaining-space', + unskippable: true, + resolved: waitForInputToHaveValue('#searchQuery input', 'owasp') + }, + { + text: 'Now hit enter.', + fixture: '.fill-remaining-space', + unskippable: true, + resolved: waitForElementsInnerHtmlToBe('#searchValue', 'owasp') + }, + { + text: 'Nice! You should now see many cool OWASP-related products.', + fixture: '.fill-remaining-space', + resolved: waitInMs(8000) + }, + { + text: 'You might have noticed, that your search term is displayed above the results?', + fixture: 'app-search-result', + resolved: waitInMs(8000) + }, + { + text: 'What we will try now is a **Cross-Site Scripting (XSS)** attack, where we try to inject HTML or JavaScript code into the application.', + fixture: 'app-search-result', + resolved: waitInMs(15000) + }, + { + text: 'Change your search value into `

owasp` to see if we can inject HTML.', + fixture: '.fill-remaining-space', + unskippable: true, + resolved: waitForInputToHaveValue('#searchQuery input', '

owasp') + }, + { + text: 'Hit enter again.', + fixture: '.fill-remaining-space', + unskippable: true, + resolved: waitForElementsInnerHtmlToBe('#searchValue', '

owasp

') // Browsers will autocorrect the unclosed tag. + }, + { + text: "Hmm, this doesn't look normal, does it?", + fixture: '.noResult', + resolved: waitInMs(8000) + }, + { + text: 'If you right-click on the search term and inspect that part of the page with your browser, you will see that our `h1`-tag was _actually_ embedded into the page and is not just shown as plain text!', + fixture: '.noResult', + resolved: waitInMs(16000) + }, + { + text: "Let's now try to inject JavaScript. Type `` into the search box now.", + fixture: '.fill-remaining-space', + unskippable: true, + resolved: waitForInputToHaveValue('#searchQuery input', '') + }, + { + text: 'Hit enter again.', + fixture: '.fill-remaining-space', + unskippable: true, + resolved: waitForElementsInnerHtmlToBe('#searchValue', '') + }, + { + text: "😔 This didn't work as we hoped. If you inspect the page, you should see the `script`-tag but it is not executed for some reason.", + fixture: '.noResult', + resolved: waitInMs(10000) + }, + { + text: "Luckily there are _many_ different XSS payloads we can try. Let's try this one next: <iframe src=\"javascript:alert(`xss`)\">.", + fixture: '.fill-remaining-space', + unskippable: true, + resolved: waitForInputToHaveValue('#searchQuery input', '') + }, + { + text: + '🎉 Congratulations! You just successfully performed an XSS attack!', + fixture: '.noResult', + resolved: waitInMs(8000) + }, + { + text: + 'More precisely, this was a **DOM XSS** attack, because your payload was handled and improperly embedded into the page by the application frontend code without even sending it to the server.', + fixture: '.noResult', + resolved: waitInMs(16000) + } + ] +} diff --git a/frontend/src/hacking-instructor/challenges/forgedFeedback.ts b/frontend/src/hacking-instructor/challenges/forgedFeedback.ts index 1acd217f..2a6da604 100644 --- a/frontend/src/hacking-instructor/challenges/forgedFeedback.ts +++ b/frontend/src/hacking-instructor/challenges/forgedFeedback.ts @@ -1,82 +1,82 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import { - waitInMs, - sleep, waitForAngularRouteToBeVisited, waitForElementToGetClicked, waitForDevTools -} from '../helpers/helpers' -import { type ChallengeInstruction } from '../' - -export const ForgedFeedbackInstruction: ChallengeInstruction = { - name: 'Forged Feedback', - hints: [ - { - text: - 'To start this challenge, first go to the _Customer Feedback_ page.', - fixture: 'app-navbar', - fixtureAfter: true, - unskippable: true, - resolved: waitForAngularRouteToBeVisited('contact') - }, - { - text: - 'This challenge is about broken access controls. To pass it, you need to impersonate another user while providing feedback.', - fixture: 'app-navbar', - resolved: waitInMs(10000) - }, - { - text: - 'If you would now submit feedback, it would be posted by yourself while logged in or anonymously while logged out.', - fixture: 'app-navbar', - resolved: waitInMs(10000) - }, - { - text: - 'We will now search for any mistake the application developers might have made in setting the author of any new feedback.', - fixture: 'app-navbar', - resolved: waitInMs(10000) - }, - { - text: - "Open the browser's _Development Tools_ and try finding anything interesting while inspecting the feedback form.", - fixture: 'app-navbar', - resolved: waitForDevTools() - }, - { - text: - 'There is more than meets the eye among the fields of the form... 😉', - fixture: 'app-navbar', - resolved: waitInMs(8000) - }, - { - text: - "Once you found the field that shouldn't even be there, try manipulating its value to one that might represent another user!", - fixture: 'app-navbar', - unskippable: true, - async resolved () { - const userId = (document.getElementById('userId') as HTMLInputElement).value - while (true) { - if ((document.getElementById('userId') as HTMLInputElement).value !== userId) { - break - } - await sleep(100) - } - } - }, - { - text: - 'You found and changed the invisible `userId`! Now submit the form to complete the challenge.', - fixture: 'app-navbar', - unskippable: true, - resolved: waitForElementToGetClicked('#submitButton') - }, - { - text: - '🎉 Congratulations, you successfully submitted a feedback as another user!', - fixture: 'app-navbar', - resolved: waitInMs(15000) - } - ] -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import { + waitInMs, + sleep, waitForAngularRouteToBeVisited, waitForElementToGetClicked, waitForDevTools +} from '../helpers/helpers' +import { type ChallengeInstruction } from '../' + +export const ForgedFeedbackInstruction: ChallengeInstruction = { + name: 'Forged Feedback', + hints: [ + { + text: + 'To start this challenge, first go to the _Customer Feedback_ page.', + fixture: 'app-navbar', + fixtureAfter: true, + unskippable: true, + resolved: waitForAngularRouteToBeVisited('contact') + }, + { + text: + 'This challenge is about broken access controls. To pass it, you need to impersonate another user while providing feedback.', + fixture: 'app-navbar', + resolved: waitInMs(10000) + }, + { + text: + 'If you would now submit feedback, it would be posted by yourself while logged in or anonymously while logged out.', + fixture: 'app-navbar', + resolved: waitInMs(10000) + }, + { + text: + 'We will now search for any mistake the application developers might have made in setting the author of any new feedback.', + fixture: 'app-navbar', + resolved: waitInMs(10000) + }, + { + text: + "Open the browser's _Development Tools_ and try finding anything interesting while inspecting the feedback form.", + fixture: 'app-navbar', + resolved: waitForDevTools() + }, + { + text: + 'There is more than meets the eye among the fields of the form... 😉', + fixture: 'app-navbar', + resolved: waitInMs(8000) + }, + { + text: + "Once you found the field that shouldn't even be there, try manipulating its value to one that might represent another user!", + fixture: 'app-navbar', + unskippable: true, + async resolved () { + const userId = (document.getElementById('userId') as HTMLInputElement).value + while (true) { + if ((document.getElementById('userId') as HTMLInputElement).value !== userId) { + break + } + await sleep(100) + } + } + }, + { + text: + 'You found and changed the invisible `userId`! Now submit the form to complete the challenge.', + fixture: 'app-navbar', + unskippable: true, + resolved: waitForElementToGetClicked('#submitButton') + }, + { + text: + '🎉 Congratulations, you successfully submitted a feedback as another user!', + fixture: 'app-navbar', + resolved: waitInMs(15000) + } + ] +} diff --git a/frontend/src/hacking-instructor/challenges/loginAdmin.ts b/frontend/src/hacking-instructor/challenges/loginAdmin.ts index c821c546..82f4084d 100644 --- a/frontend/src/hacking-instructor/challenges/loginAdmin.ts +++ b/frontend/src/hacking-instructor/challenges/loginAdmin.ts @@ -1,129 +1,129 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import { - waitForInputToHaveValue, - waitForInputToNotBeEmpty, - waitForElementToGetClicked, - waitInMs, - waitForAngularRouteToBeVisited, waitForLogOut -} from '../helpers/helpers' -import { type ChallengeInstruction } from '../' - -export const LoginAdminInstruction: ChallengeInstruction = { - name: 'Login Admin', - hints: [ - { - text: - "To start this challenge, you'll have to log out first.", - fixture: '#navbarAccount', - unskippable: true, - resolved: waitForLogOut() - }, - { - text: - "Let's try if we find a way to log in with the administrator's user account. To begin, go to the _Login_ page via the _Account_ menu.", - fixture: 'app-navbar', - fixtureAfter: true, - unskippable: true, - resolved: waitForAngularRouteToBeVisited('login') - }, - { - text: 'To find a way around the normal login process we will try to use a **SQL Injection** (SQLi) attack.', - fixture: '#email', - resolved: waitInMs(8000) - }, - { - text: "A good starting point for simple SQL Injections is to insert quotation marks (like `\"` or `'`). These mess with the syntax of an insecurely concatenated query and might give you feedback if an endpoint is vulnerable or not.", - fixture: '#email', - resolved: waitInMs(15000) - }, - { - text: "Start with entering `'` in the **email field**.", - fixture: '#email', - unskippable: true, - resolved: waitForInputToHaveValue('#email', "'") - }, - { - text: "Now put anything in the **password field**. It doesn't matter what.", - fixture: '#password', - unskippable: true, - resolved: waitForInputToNotBeEmpty('#password') - }, - { - text: 'Press the _Log in_ button.', - fixture: '#rememberMe', - unskippable: true, - resolved: waitForElementToGetClicked('#loginButton') - }, - { - text: "Nice! Do you see the red `[object Object]` error at the top? Unfortunately it isn't really telling us much about what went wrong...", - fixture: '#rememberMe', - resolved: waitInMs(10000) - }, - { - text: 'Maybe you will be able to find out more information about the error in the JavaScript console or the network tab of your browser!', - fixture: '#rememberMe', - resolved: waitInMs(10000) - }, - { - text: 'Did you spot the error message with the `SQLITE_ERROR` and the entire SQL query in the 500 response to `/login`? If not, keep the network tab open and click _Log in_ again. Then inspect the occuring response closely.', - fixture: '#rememberMe', - resolved: waitInMs(30000) - }, - { - text: "Let's try to manipulate the query a bit to make it useful. Try out typing `' OR true` into the **email field**.", - fixture: '#email', - unskippable: true, - resolved: waitForInputToHaveValue('#email', "' OR true") - }, - { - text: 'Now click the _Log in_ button again.', - fixture: '#rememberMe', - unskippable: true, - resolved: waitForElementToGetClicked('#loginButton') - }, - { - text: 'Mhh... The query is still invalid? Can you see why from the new error in the HTTP response?', - fixture: '#rememberMe', - resolved: waitInMs(8000) - }, - { - text: "We need to make sure that the rest of the query after our injection doesn't get executed. Any Ideas?", - fixture: '#rememberMe', - resolved: waitInMs(8000) - }, - { - text: 'You can comment out anything after your injection payload from query using comments in SQL. In SQLite databases you can use `--` for that.', - fixture: '#rememberMe', - resolved: waitInMs(10000) - }, - { - text: "So, type in `' OR true--` into the email field.", - fixture: '#email', - unskippable: true, - resolved: waitForInputToHaveValue('#email', "' OR true--") - }, - { - text: 'Press the _Log in_ button again and sit back...', - fixture: '#rememberMe', - unskippable: true, - resolved: waitForElementToGetClicked('#loginButton') - }, - { - text: - 'That worked, right?! To see with whose account you just logged in, open the _Account_ menu.', - fixture: '#navbarAccount', - unskippable: true, - resolved: waitForElementToGetClicked('#navbarAccount') - }, - { - text: - '🎉 Congratulations! You have been logged in as the **administrator** of the shop! (If you want to understand why, try to reproduce what your `\' OR true--` did _exactly_ to the query.)', - fixture: 'app-navbar', - resolved: waitInMs(20000) - } - ] -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import { + waitForInputToHaveValue, + waitForInputToNotBeEmpty, + waitForElementToGetClicked, + waitInMs, + waitForAngularRouteToBeVisited, waitForLogOut +} from '../helpers/helpers' +import { type ChallengeInstruction } from '../' + +export const LoginAdminInstruction: ChallengeInstruction = { + name: 'Login Admin', + hints: [ + { + text: + "To start this challenge, you'll have to log out first.", + fixture: '#navbarAccount', + unskippable: true, + resolved: waitForLogOut() + }, + { + text: + "Let's try if we find a way to log in with the administrator's user account. To begin, go to the _Login_ page via the _Account_ menu.", + fixture: 'app-navbar', + fixtureAfter: true, + unskippable: true, + resolved: waitForAngularRouteToBeVisited('login') + }, + { + text: 'To find a way around the normal login process we will try to use a **SQL Injection** (SQLi) attack.', + fixture: '#email', + resolved: waitInMs(8000) + }, + { + text: "A good starting point for simple SQL Injections is to insert quotation marks (like `\"` or `'`). These mess with the syntax of an insecurely concatenated query and might give you feedback if an endpoint is vulnerable or not.", + fixture: '#email', + resolved: waitInMs(15000) + }, + { + text: "Start with entering `'` in the **email field**.", + fixture: '#email', + unskippable: true, + resolved: waitForInputToHaveValue('#email', "'") + }, + { + text: "Now put anything in the **password field**. It doesn't matter what.", + fixture: '#password', + unskippable: true, + resolved: waitForInputToNotBeEmpty('#password') + }, + { + text: 'Press the _Log in_ button.', + fixture: '#rememberMe', + unskippable: true, + resolved: waitForElementToGetClicked('#loginButton') + }, + { + text: "Nice! Do you see the red `[object Object]` error at the top? Unfortunately it isn't really telling us much about what went wrong...", + fixture: '#rememberMe', + resolved: waitInMs(10000) + }, + { + text: 'Maybe you will be able to find out more information about the error in the JavaScript console or the network tab of your browser!', + fixture: '#rememberMe', + resolved: waitInMs(10000) + }, + { + text: 'Did you spot the error message with the `SQLITE_ERROR` and the entire SQL query in the 500 response to `/login`? If not, keep the network tab open and click _Log in_ again. Then inspect the occuring response closely.', + fixture: '#rememberMe', + resolved: waitInMs(30000) + }, + { + text: "Let's try to manipulate the query a bit to make it useful. Try out typing `' OR true` into the **email field**.", + fixture: '#email', + unskippable: true, + resolved: waitForInputToHaveValue('#email', "' OR true") + }, + { + text: 'Now click the _Log in_ button again.', + fixture: '#rememberMe', + unskippable: true, + resolved: waitForElementToGetClicked('#loginButton') + }, + { + text: 'Mhh... The query is still invalid? Can you see why from the new error in the HTTP response?', + fixture: '#rememberMe', + resolved: waitInMs(8000) + }, + { + text: "We need to make sure that the rest of the query after our injection doesn't get executed. Any Ideas?", + fixture: '#rememberMe', + resolved: waitInMs(8000) + }, + { + text: 'You can comment out anything after your injection payload from query using comments in SQL. In SQLite databases you can use `--` for that.', + fixture: '#rememberMe', + resolved: waitInMs(10000) + }, + { + text: "So, type in `' OR true--` into the email field.", + fixture: '#email', + unskippable: true, + resolved: waitForInputToHaveValue('#email', "' OR true--") + }, + { + text: 'Press the _Log in_ button again and sit back...', + fixture: '#rememberMe', + unskippable: true, + resolved: waitForElementToGetClicked('#loginButton') + }, + { + text: + 'That worked, right?! To see with whose account you just logged in, open the _Account_ menu.', + fixture: '#navbarAccount', + unskippable: true, + resolved: waitForElementToGetClicked('#navbarAccount') + }, + { + text: + '🎉 Congratulations! You have been logged in as the **administrator** of the shop! (If you want to understand why, try to reproduce what your `\' OR true--` did _exactly_ to the query.)', + fixture: 'app-navbar', + resolved: waitInMs(20000) + } + ] +} diff --git a/frontend/src/hacking-instructor/challenges/loginBender.ts b/frontend/src/hacking-instructor/challenges/loginBender.ts index 0bc37ec6..32fa2361 100644 --- a/frontend/src/hacking-instructor/challenges/loginBender.ts +++ b/frontend/src/hacking-instructor/challenges/loginBender.ts @@ -1,106 +1,106 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import { - waitForInputToHaveValue, - waitForElementToGetClicked, - waitInMs, - waitForAngularRouteToBeVisited, waitForLogOut, waitForInputToNotHaveValueAndNotBeEmpty -} from '../helpers/helpers' -import { type ChallengeInstruction } from '../' - -export const LoginBenderInstruction: ChallengeInstruction = { - name: 'Login Bender', - hints: [ - { - text: - "To start this challenge, you'll have to log out first.", - fixture: '#navbarAccount', - unskippable: true, - resolved: waitForLogOut() // TODO Add check if "Login Admin" is solved and if not recommend doing that first - }, - { - text: - "Let's try if we find a way to log in with Bender's user account. To begin, go to the _Login_ page via the _Account_ menu.", - fixture: 'app-navbar', - fixtureAfter: true, - unskippable: true, - resolved: waitForAngularRouteToBeVisited('login') - }, - { - text: - "As you would expect you need to supply Bender's email address and password to log in regularly. But you might have neither at the moment.", - fixture: 'app-navbar', - resolved: waitInMs(15000) - }, - { - text: - 'If we had at least the email address, we could then try a **SQL Injection** (SQLi) attack to avoid having to supply a password.', - fixture: 'app-navbar', - resolved: waitInMs(15000) - }, - { - text: - "So, let's go find out Bender's email! Luckily the shop is very bad with privacy and leaks emails in different places, for instance in the user feedback.", - fixture: 'app-navbar', - resolved: waitInMs(15000) - }, - { - text: - 'Go to the _About Us_ page where user feedback is displayed among other things.', - fixture: 'app-navbar', - fixtureAfter: true, - resolved: waitForAngularRouteToBeVisited('about') - }, - { - text: - 'Once you found an entry by Bender in the feedback carousel leaking enough of his email to deduce the rest, go to the _Login_ screen.', - fixture: 'app-about', - unskippable: true, - resolved: waitForAngularRouteToBeVisited('login') - }, - { - text: "Supply Bender's email address in the **email field**.", - fixture: '#email', - unskippable: true, - resolved: waitForInputToHaveValue('#email', 'bender@juice-sh.op', { replacement: ['juice-sh.op', 'application.domain'] }) - }, - { - text: "Now put anything in the **password field**. Let's assume we don't know it yet, even if you happen to already do.", - fixture: '#password', - unskippable: true, - resolved: waitForInputToNotHaveValueAndNotBeEmpty('#password', 'OhG0dPlease1nsertLiquor!') - }, - { - text: 'Press the _Log in_ button.', - fixture: '#rememberMe', - unskippable: true, - resolved: waitForElementToGetClicked('#loginButton') - }, - { - text: "This didn't work, but did you honestly expect it to? We need to craft an SQLi attack first!", - fixture: '#rememberMe', - resolved: waitInMs(10000) - }, - { - text: "You can comment out the entire password check clause of the DB query by adding `'--` to Bender's email address!", - fixture: '#email', - unskippable: true, - resolved: waitForInputToHaveValue('#email', "bender@juice-sh.op'--", { replacement: ['juice-sh.op', 'application.domain'] }) - }, - { - text: 'Now click the _Log in_ button again.', - fixture: '#rememberMe', - unskippable: true, - resolved: waitForElementToGetClicked('#loginButton') - }, - { - text: - '🎉 Congratulations! You have been logged in as Bender!', - fixture: 'app-navbar', - resolved: waitInMs(5000) - } - ] -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import { + waitForInputToHaveValue, + waitForElementToGetClicked, + waitInMs, + waitForAngularRouteToBeVisited, waitForLogOut, waitForInputToNotHaveValueAndNotBeEmpty +} from '../helpers/helpers' +import { type ChallengeInstruction } from '../' + +export const LoginBenderInstruction: ChallengeInstruction = { + name: 'Login Bender', + hints: [ + { + text: + "To start this challenge, you'll have to log out first.", + fixture: '#navbarAccount', + unskippable: true, + resolved: waitForLogOut() // TODO Add check if "Login Admin" is solved and if not recommend doing that first + }, + { + text: + "Let's try if we find a way to log in with Bender's user account. To begin, go to the _Login_ page via the _Account_ menu.", + fixture: 'app-navbar', + fixtureAfter: true, + unskippable: true, + resolved: waitForAngularRouteToBeVisited('login') + }, + { + text: + "As you would expect you need to supply Bender's email address and password to log in regularly. But you might have neither at the moment.", + fixture: 'app-navbar', + resolved: waitInMs(15000) + }, + { + text: + 'If we had at least the email address, we could then try a **SQL Injection** (SQLi) attack to avoid having to supply a password.', + fixture: 'app-navbar', + resolved: waitInMs(15000) + }, + { + text: + "So, let's go find out Bender's email! Luckily the shop is very bad with privacy and leaks emails in different places, for instance in the user feedback.", + fixture: 'app-navbar', + resolved: waitInMs(15000) + }, + { + text: + 'Go to the _About Us_ page where user feedback is displayed among other things.', + fixture: 'app-navbar', + fixtureAfter: true, + resolved: waitForAngularRouteToBeVisited('about') + }, + { + text: + 'Once you found an entry by Bender in the feedback carousel leaking enough of his email to deduce the rest, go to the _Login_ screen.', + fixture: 'app-about', + unskippable: true, + resolved: waitForAngularRouteToBeVisited('login') + }, + { + text: "Supply Bender's email address in the **email field**.", + fixture: '#email', + unskippable: true, + resolved: waitForInputToHaveValue('#email', 'bender@juice-sh.op', { replacement: ['juice-sh.op', 'application.domain'] }) + }, + { + text: "Now put anything in the **password field**. Let's assume we don't know it yet, even if you happen to already do.", + fixture: '#password', + unskippable: true, + resolved: waitForInputToNotHaveValueAndNotBeEmpty('#password', 'OhG0dPlease1nsertLiquor!') + }, + { + text: 'Press the _Log in_ button.', + fixture: '#rememberMe', + unskippable: true, + resolved: waitForElementToGetClicked('#loginButton') + }, + { + text: "This didn't work, but did you honestly expect it to? We need to craft an SQLi attack first!", + fixture: '#rememberMe', + resolved: waitInMs(10000) + }, + { + text: "You can comment out the entire password check clause of the DB query by adding `'--` to Bender's email address!", + fixture: '#email', + unskippable: true, + resolved: waitForInputToHaveValue('#email', "bender@juice-sh.op'--", { replacement: ['juice-sh.op', 'application.domain'] }) + }, + { + text: 'Now click the _Log in_ button again.', + fixture: '#rememberMe', + unskippable: true, + resolved: waitForElementToGetClicked('#loginButton') + }, + { + text: + '🎉 Congratulations! You have been logged in as Bender!', + fixture: 'app-navbar', + resolved: waitInMs(5000) + } + ] +} diff --git a/frontend/src/hacking-instructor/challenges/loginJim.ts b/frontend/src/hacking-instructor/challenges/loginJim.ts index 7290b2cb..7fbf15d4 100644 --- a/frontend/src/hacking-instructor/challenges/loginJim.ts +++ b/frontend/src/hacking-instructor/challenges/loginJim.ts @@ -1,105 +1,105 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import { - waitForInputToHaveValue, - waitForElementToGetClicked, - waitInMs, - waitForAngularRouteToBeVisited, waitForLogOut, waitForInputToNotHaveValueAndNotBeEmpty -} from '../helpers/helpers' -import { type ChallengeInstruction } from '../' - -export const LoginJimInstruction: ChallengeInstruction = { - name: 'Login Jim', - hints: [ - { - text: - "To start this challenge, you'll have to log out first.", - fixture: '#navbarAccount', - unskippable: true, - resolved: waitForLogOut() // TODO Add check if "Login Admin" is solved and if not recommend doing that first - }, - { - text: - "Let's try if we find a way to log in with Jim's user account. To begin, go to the _Login_ page via the _Account_ menu.", - fixture: 'app-navbar', - fixtureAfter: true, - unskippable: true, - resolved: waitForAngularRouteToBeVisited('login') - }, - { - text: - "As you would expect you need to supply Jim's email address and password to log in regularly. But you might have neither at the moment.", - fixture: 'app-navbar', - resolved: waitInMs(15000) - }, - { - text: - 'If we had at least the email address, we could then try a **SQL Injection** (SQLi) attack to avoid having to supply a password.', - fixture: 'app-navbar', - resolved: waitInMs(15000) - }, - { - text: - "So, let's go find out Jim's email! Luckily the shop is very bad with privacy and leaks emails in different places, for instance in the product reviews.", - fixture: 'app-navbar', - resolved: waitInMs(15000) - }, - { - text: - 'Go back to the product list and click on some to open their details dialog which also hold the user reviews.', - fixture: '.fill-remaining-space', - resolved: waitForAngularRouteToBeVisited('search') - }, - { - text: - 'Once you found a user review by Jim and learned his email, go to the _Login_ screen.', - fixture: '.fill-remaining-space', - unskippable: true, - resolved: waitForAngularRouteToBeVisited('login') - }, - { - text: "Supply Jim's email address in the **email field**.", - fixture: '#email', - unskippable: true, - resolved: waitForInputToHaveValue('#email', 'jim@juice-sh.op', { replacement: ['juice-sh.op', 'application.domain'] }) - }, - { - text: "Now put anything in the **password field**. Let's assume we don't know it yet, even if you happen to already do.", - fixture: '#password', - unskippable: true, - resolved: waitForInputToNotHaveValueAndNotBeEmpty('#password', 'ncc-1701') - }, - { - text: 'Press the _Log in_ button.', - fixture: '#rememberMe', - unskippable: true, - resolved: waitForElementToGetClicked('#loginButton') - }, - { - text: "This didn't work, but did you honestly expect it to? We need to craft an SQLi attack first!", - fixture: '#rememberMe', - resolved: waitInMs(10000) - }, - { - text: "You can comment out the entire password check clause of the DB query by adding `'--` to Jim's email address!", - fixture: '#email', - unskippable: true, - resolved: waitForInputToHaveValue('#email', "jim@juice-sh.op'--", { replacement: ['juice-sh.op', 'application.domain'] }) - }, - { - text: 'Now click the _Log in_ button again.', - fixture: '#rememberMe', - unskippable: true, - resolved: waitForElementToGetClicked('#loginButton') - }, - { - text: - '🎉 Congratulations! You have been logged in as Jim!', - fixture: 'app-navbar', - resolved: waitInMs(5000) - } - ] -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import { + waitForInputToHaveValue, + waitForElementToGetClicked, + waitInMs, + waitForAngularRouteToBeVisited, waitForLogOut, waitForInputToNotHaveValueAndNotBeEmpty +} from '../helpers/helpers' +import { type ChallengeInstruction } from '../' + +export const LoginJimInstruction: ChallengeInstruction = { + name: 'Login Jim', + hints: [ + { + text: + "To start this challenge, you'll have to log out first.", + fixture: '#navbarAccount', + unskippable: true, + resolved: waitForLogOut() // TODO Add check if "Login Admin" is solved and if not recommend doing that first + }, + { + text: + "Let's try if we find a way to log in with Jim's user account. To begin, go to the _Login_ page via the _Account_ menu.", + fixture: 'app-navbar', + fixtureAfter: true, + unskippable: true, + resolved: waitForAngularRouteToBeVisited('login') + }, + { + text: + "As you would expect you need to supply Jim's email address and password to log in regularly. But you might have neither at the moment.", + fixture: 'app-navbar', + resolved: waitInMs(15000) + }, + { + text: + 'If we had at least the email address, we could then try a **SQL Injection** (SQLi) attack to avoid having to supply a password.', + fixture: 'app-navbar', + resolved: waitInMs(15000) + }, + { + text: + "So, let's go find out Jim's email! Luckily the shop is very bad with privacy and leaks emails in different places, for instance in the product reviews.", + fixture: 'app-navbar', + resolved: waitInMs(15000) + }, + { + text: + 'Go back to the product list and click on some to open their details dialog which also hold the user reviews.', + fixture: '.fill-remaining-space', + resolved: waitForAngularRouteToBeVisited('search') + }, + { + text: + 'Once you found a user review by Jim and learned his email, go to the _Login_ screen.', + fixture: '.fill-remaining-space', + unskippable: true, + resolved: waitForAngularRouteToBeVisited('login') + }, + { + text: "Supply Jim's email address in the **email field**.", + fixture: '#email', + unskippable: true, + resolved: waitForInputToHaveValue('#email', 'jim@juice-sh.op', { replacement: ['juice-sh.op', 'application.domain'] }) + }, + { + text: "Now put anything in the **password field**. Let's assume we don't know it yet, even if you happen to already do.", + fixture: '#password', + unskippable: true, + resolved: waitForInputToNotHaveValueAndNotBeEmpty('#password', 'ncc-1701') + }, + { + text: 'Press the _Log in_ button.', + fixture: '#rememberMe', + unskippable: true, + resolved: waitForElementToGetClicked('#loginButton') + }, + { + text: "This didn't work, but did you honestly expect it to? We need to craft an SQLi attack first!", + fixture: '#rememberMe', + resolved: waitInMs(10000) + }, + { + text: "You can comment out the entire password check clause of the DB query by adding `'--` to Jim's email address!", + fixture: '#email', + unskippable: true, + resolved: waitForInputToHaveValue('#email', "jim@juice-sh.op'--", { replacement: ['juice-sh.op', 'application.domain'] }) + }, + { + text: 'Now click the _Log in_ button again.', + fixture: '#rememberMe', + unskippable: true, + resolved: waitForElementToGetClicked('#loginButton') + }, + { + text: + '🎉 Congratulations! You have been logged in as Jim!', + fixture: 'app-navbar', + resolved: waitInMs(5000) + } + ] +} diff --git a/frontend/src/hacking-instructor/challenges/passwordStrength.ts b/frontend/src/hacking-instructor/challenges/passwordStrength.ts index 106e5cb2..e44f93ae 100644 --- a/frontend/src/hacking-instructor/challenges/passwordStrength.ts +++ b/frontend/src/hacking-instructor/challenges/passwordStrength.ts @@ -1,88 +1,88 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import { - waitForInputToHaveValue, - waitForInputToNotBeEmpty, - waitForElementToGetClicked, - waitInMs, - waitForAngularRouteToBeVisited, waitForLogOut -} from '../helpers/helpers' -import { type ChallengeInstruction } from '../' - -export const PasswordStrengthInstruction: ChallengeInstruction = { - name: 'Password Strength', - hints: [ - { - text: - "To start this challenge, you'll have to log out first.", - fixture: '#navbarAccount', - unskippable: true, - resolved: waitForLogOut() - }, - { - text: - "In this challenge we'll try to log into the administrator's user account using his original credentials.", - fixture: 'app-navbar', - resolved: waitInMs(7000) - }, - { - text: - "If you don't know it already, you must first find out the admin's email address. The user feedback and product reviews are good places to look into. When you have it, go to the _Login_ page.", - fixture: 'app-navbar', - fixtureAfter: true, - unskippable: true, - resolved: waitForAngularRouteToBeVisited('login') - }, - { - text: "Enter the admin's email address into the **email field**.", - fixture: '#email', - unskippable: true, - resolved: waitForInputToHaveValue('#email', 'admin@juice-sh.op') // TODO Use domain from config instead - }, - { - text: 'Now for the password. Lucky for us, the admin chose a really, really, **really** stupid one. Just try any that comes to your mind!', - fixture: '#password', - unskippable: true, - resolved: waitForInputToNotBeEmpty('#password') - }, - { - text: "🤦‍♂️ Nah, that was wrong! Keep trying! I'll tell you when you're one the right track.", - fixture: '#password', - unskippable: true, - resolved: waitForInputToHaveValue('#password', 'admin') - }, - { - text: 'Okay, you are one the right track, but this would have been the worst password in the world for an admin. He spiced it up a little bit with some extra non-letter characters. Keep trying!', - fixture: '#password', - unskippable: true, - resolved: waitForInputToHaveValue('#password', 'admin1') - }, - { - text: "🔥 Yes, it's getting warmer! Try adding some more numbers maybe?", - fixture: '#password', - unskippable: true, - resolved: waitForInputToHaveValue('#password', 'admin12') - }, - { - text: "🧯 It's getting hot! Just one more digit...", - fixture: '#password', - unskippable: true, - resolved: waitForInputToHaveValue('#password', 'admin123') - }, - { - text: 'Okay, now press the _Log in_ button.', - fixture: '#rememberMe', - unskippable: true, - resolved: waitForElementToGetClicked('#loginButton') - }, - { - text: - '🎉 Congratulations! You have been logged in as the **administrator** of the shop thanks to his very ill chosen password!', - fixture: 'app-navbar', - resolved: waitInMs(20000) - } - ] -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import { + waitForInputToHaveValue, + waitForInputToNotBeEmpty, + waitForElementToGetClicked, + waitInMs, + waitForAngularRouteToBeVisited, waitForLogOut +} from '../helpers/helpers' +import { type ChallengeInstruction } from '../' + +export const PasswordStrengthInstruction: ChallengeInstruction = { + name: 'Password Strength', + hints: [ + { + text: + "To start this challenge, you'll have to log out first.", + fixture: '#navbarAccount', + unskippable: true, + resolved: waitForLogOut() + }, + { + text: + "In this challenge we'll try to log into the administrator's user account using his original credentials.", + fixture: 'app-navbar', + resolved: waitInMs(7000) + }, + { + text: + "If you don't know it already, you must first find out the admin's email address. The user feedback and product reviews are good places to look into. When you have it, go to the _Login_ page.", + fixture: 'app-navbar', + fixtureAfter: true, + unskippable: true, + resolved: waitForAngularRouteToBeVisited('login') + }, + { + text: "Enter the admin's email address into the **email field**.", + fixture: '#email', + unskippable: true, + resolved: waitForInputToHaveValue('#email', 'admin@juice-sh.op') // TODO Use domain from config instead + }, + { + text: 'Now for the password. Lucky for us, the admin chose a really, really, **really** stupid one. Just try any that comes to your mind!', + fixture: '#password', + unskippable: true, + resolved: waitForInputToNotBeEmpty('#password') + }, + { + text: "🤦‍♂️ Nah, that was wrong! Keep trying! I'll tell you when you're one the right track.", + fixture: '#password', + unskippable: true, + resolved: waitForInputToHaveValue('#password', 'admin') + }, + { + text: 'Okay, you are one the right track, but this would have been the worst password in the world for an admin. He spiced it up a little bit with some extra non-letter characters. Keep trying!', + fixture: '#password', + unskippable: true, + resolved: waitForInputToHaveValue('#password', 'admin1') + }, + { + text: "🔥 Yes, it's getting warmer! Try adding some more numbers maybe?", + fixture: '#password', + unskippable: true, + resolved: waitForInputToHaveValue('#password', 'admin12') + }, + { + text: "🧯 It's getting hot! Just one more digit...", + fixture: '#password', + unskippable: true, + resolved: waitForInputToHaveValue('#password', 'admin123') + }, + { + text: 'Okay, now press the _Log in_ button.', + fixture: '#rememberMe', + unskippable: true, + resolved: waitForElementToGetClicked('#loginButton') + }, + { + text: + '🎉 Congratulations! You have been logged in as the **administrator** of the shop thanks to his very ill chosen password!', + fixture: 'app-navbar', + resolved: waitInMs(20000) + } + ] +} diff --git a/frontend/src/hacking-instructor/challenges/privacyPolicy.ts b/frontend/src/hacking-instructor/challenges/privacyPolicy.ts index a603a5a7..51c157d2 100644 --- a/frontend/src/hacking-instructor/challenges/privacyPolicy.ts +++ b/frontend/src/hacking-instructor/challenges/privacyPolicy.ts @@ -1,41 +1,41 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import { - waitInMs, waitForAngularRouteToBeVisited, waitForElementToGetClicked, waitForLogIn -} from '../helpers/helpers' -import { type ChallengeInstruction } from '../' - -export const PrivacyPolicyInstruction: ChallengeInstruction = { - name: 'Privacy Policy', - hints: [ - { - text: - 'Log in with any user to begin this challenge. You can use an existing or freshly registered account.', - fixture: 'app-navbar', - fixtureAfter: true, - unskippable: true, - resolved: waitForLogIn() - }, - { - text: - 'Great, you are logged in! Now open the _Account_ menu.', - fixture: '#navbarAccount', - resolved: waitForElementToGetClicked('#navbarAccount') - }, - { - text: - 'Open the _Privacy & Security_ sub-menu and click _Privacy Policy_.', - fixture: 'app-navbar', - unskippable: true, - resolved: waitForAngularRouteToBeVisited('privacy-security/privacy-policy') - }, - { - text: '🎉 That was super easy, right? This challenge is a bit of a joke actually, because nobody reads any fine print online... 🙈', - fixture: 'app-navbar', - resolved: waitInMs(60000) - } - ] -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import { + waitInMs, waitForAngularRouteToBeVisited, waitForElementToGetClicked, waitForLogIn +} from '../helpers/helpers' +import { type ChallengeInstruction } from '../' + +export const PrivacyPolicyInstruction: ChallengeInstruction = { + name: 'Privacy Policy', + hints: [ + { + text: + 'Log in with any user to begin this challenge. You can use an existing or freshly registered account.', + fixture: 'app-navbar', + fixtureAfter: true, + unskippable: true, + resolved: waitForLogIn() + }, + { + text: + 'Great, you are logged in! Now open the _Account_ menu.', + fixture: '#navbarAccount', + resolved: waitForElementToGetClicked('#navbarAccount') + }, + { + text: + 'Open the _Privacy & Security_ sub-menu and click _Privacy Policy_.', + fixture: 'app-navbar', + unskippable: true, + resolved: waitForAngularRouteToBeVisited('privacy-security/privacy-policy') + }, + { + text: '🎉 That was super easy, right? This challenge is a bit of a joke actually, because nobody reads any fine print online... 🙈', + fixture: 'app-navbar', + resolved: waitInMs(60000) + } + ] +} diff --git a/frontend/src/hacking-instructor/challenges/reflectedXss.ts b/frontend/src/hacking-instructor/challenges/reflectedXss.ts index 17290d60..9ab0f1d1 100644 --- a/frontend/src/hacking-instructor/challenges/reflectedXss.ts +++ b/frontend/src/hacking-instructor/challenges/reflectedXss.ts @@ -1,86 +1,86 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import { - waitForRightUriQueryParamPair, - waitInMs, - waitForAngularRouteToBeVisited, - waitForLogIn -} from '../helpers/helpers' -import { type ChallengeInstruction } from '../' - -export const ReflectedXssInstruction: ChallengeInstruction = { - name: 'Reflected XSS', - hints: [ - { - text: - 'To proceed with this challenge, you need to be logged in. We have detected that you are not currently logged in. Please log in to continue.', - fixture: '#navbarAccount', - unskippable: true, - resolved: waitForLogIn() - }, - { - text: - 'Start by going to your saved addresses. You can find them by clicking on "Account" in the navigation bar, then on Orders & Payment, and then on My saved addresses.', - fixture: 'app-navbar', - unskippable: true, - resolved: waitForAngularRouteToBeVisited('address/saved') - }, - { - text: - 'Add a new address.', - fixture: 'app-navbar', - unskippable: true, - resolved: waitForAngularRouteToBeVisited('address/create') - }, - { - text: - 'You see a few fields to submit input. This is always a good starting point for checking potential XSS vulnerabilities. Pay attention to the pop-up once you submitted the new address.', - fixture: 'app-navbar', - unskippable: true, - resolved: waitForAngularRouteToBeVisited('address/saved') - }, - { - text: - 'Observe how the name of the city was used in the pop-up once you submit the address. Let us try to check whether this page is vulnerable to reflected XSS. Submit a new address.', - fixture: 'app-navbar', - unskippable: true, - resolved: waitForAngularRouteToBeVisited('address/create') - }, - { - text: - 'Use: <iframe src="javascript:alert(`xss`)"> as a city name.', - fixture: 'app-navbar', - unskippable: true, - resolved: waitForAngularRouteToBeVisited('address/saved') - }, - { - text: - 'Hmmm, that did not seem to work :/. We might want to try another part of the website. Let us explore the order and payment pages. First, place an order. You can add any item to your basket and complete the purchase.', - fixture: 'app-navbar', - unskippable: true, - resolved: waitForAngularRouteToBeVisited('order-completion') - }, - { - text: - 'Have a look at the Track Orders page.', - fixture: 'app-navbar', - unskippable: true, - resolved: waitForAngularRouteToBeVisited('track-result') - }, - { - text: - 'In a reflected XSS attack, a payload is often included in URI or HTTP parameters. Pay attention to the id parameter in the url. Could it be vulnerable to reflected XSS? Give it a try by replacing the value of the id parameter with the payload: <iframe src="javascript:alert(`xss`)">. Do not enter immediately. We will let you know once you have the correct URL in place.', - fixture: 'app-navbar', - resolved: waitForRightUriQueryParamPair('id', 'less comment.', - rating: 1, - captchaId: json.captchaId, - captcha: json.answer - } - }) - .expect('status', 201) - .expect('json', 'data', { - comment: 'I am a harmless comment.' - }) - }) - }) - - if (utils.isChallengeEnabled(challenges.persistedXssFeedbackChallenge)) { - it('POST fails to sanitize masked XSS-attack by not applying sanitization recursively', () => { - return frisby.get(REST_URL + '/captcha') - .expect('status', 200) - .expect('header', 'content-type', /application\/json/) - .then(({ json }) => { - return frisby.post(API_URL + '/Feedbacks', { - headers: jsonHeader, - body: { - comment: 'The sanitize-html module up to at least version 1.4.2 has this issue: <iframe src="javascript:alert(`xss`)">', - rating: 1, - captchaId: json.captchaId, - captcha: json.answer - } - }) - .expect('status', 201) - .expect('json', 'data', { - comment: 'The sanitize-html module up to at least version 1.4.2 has this issue: less comment.', + rating: 1, + captchaId: json.captchaId, + captcha: json.answer + } + }) + .expect('status', 201) + .expect('json', 'data', { + comment: 'I am a harmless comment.' + }) + }) + }) + + if (utils.isChallengeEnabled(challenges.persistedXssFeedbackChallenge)) { + it('POST fails to sanitize masked XSS-attack by not applying sanitization recursively', () => { + return frisby.get(REST_URL + '/captcha') + .expect('status', 200) + .expect('header', 'content-type', /application\/json/) + .then(({ json }) => { + return frisby.post(API_URL + '/Feedbacks', { + headers: jsonHeader, + body: { + comment: 'The sanitize-html module up to at least version 1.4.2 has this issue: <iframe src="javascript:alert(`xss`)">', + rating: 1, + captchaId: json.captchaId, + captcha: json.answer + } + }) + .expect('status', 201) + .expect('json', 'data', { + comment: 'The sanitize-html module up to at least version 1.4.2 has this issue: ' - ) - .type('{enter}') - cy.expectChallengeSolved({ challenge: 'Bonus Payload' }) - }) - }) -}) - -describe('/rest/products/search', () => { - describe('challenge "unionSqlInjection"', () => { - it('query param in product search endpoint should be susceptible to UNION SQL injection attacks', () => { - cy.request( - "/rest/products/search?q=')) union select id,'2','3',email,password,'6','7','8','9' from users--" - ) - cy.expectChallengeSolved({ challenge: 'User Credentials' }) - }) - }) - - describe('challenge "dbSchema"', () => { - it('query param in product search endpoint should be susceptible to UNION SQL injection attacks', () => { - cy.request( - "/rest/products/search?q=')) union select sql,'2','3','4','5','6','7','8','9' from sqlite_master--" - ) - cy.expectChallengeSolved({ challenge: 'Database Schema' }) - }) - }) - - describe('challenge "dlpPastebinLeakChallenge"', () => { - beforeEach(() => { - cy.login({ - email: 'admin', - password: 'admin123' - }) - }) - - it('search query should logically reveal the special product', () => { - cy.request("/rest/products/search?q='))--") - .its('body') - .then((sourceContent) => { - cy.task('GetPastebinLeakProduct').then((pastebinLeakProduct: Product) => { - let foundProduct = false - - sourceContent.data.forEach((product: Product) => { - if (product.name === pastebinLeakProduct.name) { - foundProduct = true - } - }) - // eslint-disable-next-line @typescript-eslint/no-unused-expressions - expect(foundProduct).to.be.true - }) - }) - }) - }) - - xdescribe('challenge "christmasSpecial"', () => { - beforeEach(() => { - cy.login({ - email: 'admin', - password: 'admin123' - }) - }) - - it('search query should reveal logically deleted christmas special product on SQL injection attack', () => { - cy.request("/rest/products/search?q='))--") - .its('body') - .then((sourceContent) => { - cy.task('GetChristmasProduct').then((christmasProduct: Product) => { - let foundProduct = false - - sourceContent.data.forEach((product: Product) => { - if (product.name === christmasProduct.name) { - foundProduct = true - } - }) - // eslint-disable-next-line @typescript-eslint/no-unused-expressions - expect(foundProduct).to.be.true - }) - }) - }) - - it('should be able to place Christmas product into shopping card by id', () => { - cy.request('/api/products') - .its('body') - .then((sourceContent) => { - cy.task('GetChristmasProduct').then((christmasProduct: Product) => { - sourceContent.data.forEach((product: Product) => { - if (product.name === christmasProduct.name) { - cy.window().then(async () => { - const response = await fetch( - `${Cypress.config('baseUrl')}/api/BasketItems/`, - { - method: 'POST', - cache: 'no-cache', - headers: { - 'Content-type': 'application/json', - Authorization: `Bearer ${localStorage.getItem( - 'token' - )}` - }, - body: JSON.stringify({ - BasketId: `${sessionStorage.getItem('bid')}`, - ProductId: `${product.id}`, - quantity: 1 - }) - } - ) - if (response.status === 201) { - console.log('Success') - } - }) - } - }) - }) - }) - - cy.visit('/#/basket') - cy.get('#checkoutButton').click() - cy.expectChallengeSolved({ challenge: 'Christmas Special' }) - }) - }) -}) +import { type Product } from '../../../data/types' + +describe('/#/search', () => { + beforeEach(() => { + cy.visit('/#/search') + }) + describe('challenge "localXss"', () => { + // Cypress alert bug + xit('search query should be susceptible to reflected XSS attacks', () => { + cy.get('#searchQuery').click() + cy.get('#mat-input-0') + .type('' + ) + .type('{enter}') + cy.expectChallengeSolved({ challenge: 'Bonus Payload' }) + }) + }) +}) + +describe('/rest/products/search', () => { + describe('challenge "unionSqlInjection"', () => { + it('query param in product search endpoint should be susceptible to UNION SQL injection attacks', () => { + cy.request( + "/rest/products/search?q=')) union select id,'2','3',email,password,'6','7','8','9' from users--" + ) + cy.expectChallengeSolved({ challenge: 'User Credentials' }) + }) + }) + + describe('challenge "dbSchema"', () => { + it('query param in product search endpoint should be susceptible to UNION SQL injection attacks', () => { + cy.request( + "/rest/products/search?q=')) union select sql,'2','3','4','5','6','7','8','9' from sqlite_master--" + ) + cy.expectChallengeSolved({ challenge: 'Database Schema' }) + }) + }) + + describe('challenge "dlpPastebinLeakChallenge"', () => { + beforeEach(() => { + cy.login({ + email: 'admin', + password: 'admin123' + }) + }) + + it('search query should logically reveal the special product', () => { + cy.request("/rest/products/search?q='))--") + .its('body') + .then((sourceContent) => { + cy.task('GetPastebinLeakProduct').then((pastebinLeakProduct: Product) => { + let foundProduct = false + + sourceContent.data.forEach((product: Product) => { + if (product.name === pastebinLeakProduct.name) { + foundProduct = true + } + }) + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + expect(foundProduct).to.be.true + }) + }) + }) + }) + + xdescribe('challenge "christmasSpecial"', () => { + beforeEach(() => { + cy.login({ + email: 'admin', + password: 'admin123' + }) + }) + + it('search query should reveal logically deleted christmas special product on SQL injection attack', () => { + cy.request("/rest/products/search?q='))--") + .its('body') + .then((sourceContent) => { + cy.task('GetChristmasProduct').then((christmasProduct: Product) => { + let foundProduct = false + + sourceContent.data.forEach((product: Product) => { + if (product.name === christmasProduct.name) { + foundProduct = true + } + }) + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + expect(foundProduct).to.be.true + }) + }) + }) + + it('should be able to place Christmas product into shopping card by id', () => { + cy.request('/api/products') + .its('body') + .then((sourceContent) => { + cy.task('GetChristmasProduct').then((christmasProduct: Product) => { + sourceContent.data.forEach((product: Product) => { + if (product.name === christmasProduct.name) { + cy.window().then(async () => { + const response = await fetch( + `${Cypress.config('baseUrl')}/api/BasketItems/`, + { + method: 'POST', + cache: 'no-cache', + headers: { + 'Content-type': 'application/json', + Authorization: `Bearer ${localStorage.getItem( + 'token' + )}` + }, + body: JSON.stringify({ + BasketId: `${sessionStorage.getItem('bid')}`, + ProductId: `${product.id}`, + quantity: 1 + }) + } + ) + if (response.status === 201) { + console.log('Success') + } + }) + } + }) + }) + }) + + cy.visit('/#/basket') + cy.get('#checkoutButton').click() + cy.expectChallengeSolved({ challenge: 'Christmas Special' }) + }) + }) +}) diff --git a/test/cypress/e2e/tokenSale.spec.ts b/test/cypress/e2e/tokenSale.spec.ts index 2d203c81..69a095d2 100644 --- a/test/cypress/e2e/tokenSale.spec.ts +++ b/test/cypress/e2e/tokenSale.spec.ts @@ -1,9 +1,9 @@ -describe('/#/tokensale-ico-ea', () => { - describe('challenge "tokenSale"', () => { - it('should be possible to access token sale section even when not authenticated', () => { - cy.visit('/#/tokensale-ico-ea') - cy.url().should('match', /\/tokensale-ico-ea/) - cy.expectChallengeSolved({ challenge: 'Blockchain Hype' }) - }) - }) -}) +describe('/#/tokensale-ico-ea', () => { + describe('challenge "tokenSale"', () => { + it('should be possible to access token sale section even when not authenticated', () => { + cy.visit('/#/tokensale-ico-ea') + cy.url().should('match', /\/tokensale-ico-ea/) + cy.expectChallengeSolved({ challenge: 'Blockchain Hype' }) + }) + }) +}) diff --git a/test/cypress/e2e/totpSetup.spec.ts b/test/cypress/e2e/totpSetup.spec.ts index 79b46fa9..aadcb4e8 100644 --- a/test/cypress/e2e/totpSetup.spec.ts +++ b/test/cypress/e2e/totpSetup.spec.ts @@ -1,47 +1,47 @@ -describe('/#/basket', () => { - describe('as wurstbrot', () => { - beforeEach(() => { - cy.login({ - email: 'wurstbrot', - password: 'EinBelegtesBrotMitSchinkenSCHINKEN!', - totpSecret: 'IFTXE3SPOEYVURT2MRYGI52TKJ4HC3KH' - }) - }) - - it('should show an success message for 2fa enabled accounts', () => { - cy.visit('/#/privacy-security/two-factor-authentication') - }) - }) - - describe('as amy', () => { - beforeEach(() => { - cy.login({ - email: 'amy', - password: 'K1f.....................' - }) - }) - - it('should be possible to setup 2fa for a account without 2fa enabled', async () => { - cy.visit('/#/privacy-security/two-factor-authentication') - - cy.get('#initalToken') - .should('have.attr', 'data-test-totp-secret') - .then(($val) => { - // console.log($val); - cy.get('#currentPasswordSetup').type('K1f.....................') - - cy.task('GenerateAuthenticator', $val).then((secret: string) => { - cy.get('#initalToken').type(secret) - cy.get('#setupTwoFactorAuth').click() - - cy.get('#currentPasswordDisable').type('K1f.....................') - cy.get('#disableTwoFactorAuth').click() - }) - }) - cy.get('.mat-snack-bar-container').should( - 'contain', - 'Two-Factor Authentication has been removed.' - ) - }) - }) -}) +describe('/#/basket', () => { + describe('as wurstbrot', () => { + beforeEach(() => { + cy.login({ + email: 'wurstbrot', + password: 'EinBelegtesBrotMitSchinkenSCHINKEN!', + totpSecret: 'IFTXE3SPOEYVURT2MRYGI52TKJ4HC3KH' + }) + }) + + it('should show an success message for 2fa enabled accounts', () => { + cy.visit('/#/privacy-security/two-factor-authentication') + }) + }) + + describe('as amy', () => { + beforeEach(() => { + cy.login({ + email: 'amy', + password: 'K1f.....................' + }) + }) + + it('should be possible to setup 2fa for a account without 2fa enabled', async () => { + cy.visit('/#/privacy-security/two-factor-authentication') + + cy.get('#initalToken') + .should('have.attr', 'data-test-totp-secret') + .then(($val) => { + // console.log($val); + cy.get('#currentPasswordSetup').type('K1f.....................') + + cy.task('GenerateAuthenticator', $val).then((secret: string) => { + cy.get('#initalToken').type(secret) + cy.get('#setupTwoFactorAuth').click() + + cy.get('#currentPasswordDisable').type('K1f.....................') + cy.get('#disableTwoFactorAuth').click() + }) + }) + cy.get('.mat-snack-bar-container').should( + 'contain', + 'Two-Factor Authentication has been removed.' + ) + }) + }) +}) diff --git a/test/cypress/e2e/trackOrder.spec.ts b/test/cypress/e2e/trackOrder.spec.ts index a168ee24..403dc629 100644 --- a/test/cypress/e2e/trackOrder.spec.ts +++ b/test/cypress/e2e/trackOrder.spec.ts @@ -1,24 +1,24 @@ -describe('/#/track-order', () => { - describe('challenge "reflectedXss"', () => { - // Cypress alert bug - xit('Order Id should be susceptible to reflected XSS attacks', () => { - cy.task('isDocker').then((isDocker) => { - if (!isDocker) { - cy.on('uncaught:exception', (_err, _runnable) => { - return false - }) - - cy.visit('/#/track-result') - cy.visit('/#/track-result?id=tizedIFrame')).to.equal('SanitizedIFrame') - }) - - it('can be bypassed by exploiting lack of recursive sanitization', () => { - expect(security.sanitizeHtml('<iframe src="javascript:alert(`xss`)">')).to.equal('tizedIFrame')).to.equal('SanitizedIFrame') - }) - - it('cannot be bypassed by exploiting lack of recursive sanitization', () => { - expect(security.sanitizeSecure('Bla<iframe src="javascript:alert(`xss`)">Blubb')).to.equal('BlaBlubb') - }) - }) - - describe('hash', () => { - it('throws type error for for undefined input', () => { - expect(() => security.hash()).to.throw(TypeError) - }) - - it('returns MD5 hash for any input string', () => { - expect(security.hash('admin123')).to.equal('0192023a7bbd73250516f069df18b500') - expect(security.hash('password')).to.equal('5f4dcc3b5aa765d61d8327deb882cf99') - expect(security.hash('')).to.equal('d41d8cd98f00b204e9800998ecf8427e') - }) - }) - - describe('hmac', () => { - it('throws type error for for undefined input', () => { - expect(() => security.hmac()).to.throw(TypeError) - }) - - it('returns SHA-256 HMAC with "pa4qacea4VK9t9nGv7yZtwmj" as salt any input string', () => { - expect(security.hmac('admin123')).to.equal('6be13e2feeada221f29134db71c0ab0be0e27eccfc0fb436ba4096ba73aafb20') - expect(security.hmac('password')).to.equal('da28fc4354f4a458508a461fbae364720c4249c27f10fccf68317fc4bf6531ed') - expect(security.hmac('')).to.equal('f052179ec5894a2e79befa8060cfcb517f1e14f7f6222af854377b6481ae953e') - }) - }) -}) +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +// @ts-expect-error FIXME no typescript definitions for z85 :( +import z85 from 'z85' +import chai = require('chai') +const expect = chai.expect + +describe('insecurity', () => { + const security = require('../../lib/insecurity') + + describe('cutOffPoisonNullByte', () => { + it('returns string unchanged if it contains no null byte', () => { + expect(security.cutOffPoisonNullByte('file.exe.pdf')).to.equal('file.exe.pdf') + }) + + it('returns string up to null byte', () => { + expect(security.cutOffPoisonNullByte('file.exe%00.pdf')).to.equal('file.exe') + }) + }) + + describe('userEmailFrom', () => { + it('returns content of "x-user-email" header if present', () => { + expect(security.userEmailFrom({ headers: { 'x-user-email': 'test@bla.blubb' } })).to.equal('test@bla.blubb') + }) + + it('returns undefined if header "x-user-email" is not present', () => { + expect(security.userEmailFrom({ headers: {} })).to.equal(undefined) + expect(security.userEmailFrom({})).to.equal(undefined) + }) + }) + + describe('generateCoupon', () => { + it('returns base85-encoded month, year and discount as coupon code', () => { + const coupon = security.generateCoupon(20, new Date('1980-01-02')) + expect(coupon).to.equal('n { + const coupon = security.generateCoupon(20) + expect(coupon).to.equal(security.generateCoupon(20, new Date())) + }) + + it('does not encode day of month or time into coupon code', () => { + const coupon = security.generateCoupon(10, new Date('December 01, 1999')) + expect(coupon).to.equal(security.generateCoupon(10, new Date('December 01, 1999 01:00:00'))) + expect(coupon).to.equal(security.generateCoupon(10, new Date('December 02, 1999'))) + expect(coupon).to.equal(security.generateCoupon(10, new Date('December 31, 1999 23:59:59'))) + }) + }) + + describe('discountFromCoupon', () => { + it('returns undefined when not passing in a coupon code', () => { + expect(security.discountFromCoupon(undefined)).to.equal(undefined) + expect(security.discountFromCoupon(null)).to.equal(undefined) + }) + + it('returns undefined for malformed coupon code', () => { + expect(security.discountFromCoupon('')).to.equal(undefined) + expect(security.discountFromCoupon('x')).to.equal(undefined) + expect(security.discountFromCoupon('___')).to.equal(undefined) + }) + + it('returns undefined for coupon code not according to expected pattern', () => { + expect(security.discountFromCoupon(z85.encode('Test'))).to.equal(undefined) + expect(security.discountFromCoupon(z85.encode('XXX00-10'))).to.equal(undefined) + expect(security.discountFromCoupon(z85.encode('DEC18-999'))).to.equal(undefined) + expect(security.discountFromCoupon(z85.encode('DEC18-1'))).to.equal(undefined) + expect(security.discountFromCoupon(z85.encode('DEC2018-10'))).to.equal(undefined) + }) + + it('returns undefined for expired coupon code', () => { + expect(security.discountFromCoupon(z85.encode('SEP14-50'))).to.equal(undefined) + }) + + it('returns discount from valid coupon code', () => { + expect(security.discountFromCoupon(security.generateCoupon('05'))).to.equal(5) + expect(security.discountFromCoupon(security.generateCoupon(10))).to.equal(10) + expect(security.discountFromCoupon(security.generateCoupon(99))).to.equal(99) + }) + }) + + describe('authenticatedUsers', () => { + it('returns user by associated token', () => { + security.authenticatedUsers.put('11111', { data: { id: 1 } }) + + expect(security.authenticatedUsers.get('11111')).to.deep.equal({ data: { id: 1 } }) + }) + + it('returns undefined if no token is passed in', () => { + expect(security.authenticatedUsers.get(undefined)).to.equal(undefined) + expect(security.authenticatedUsers.get(null)).to.equal(undefined) + }) + + it('returns token by associated user', () => { + security.authenticatedUsers.put('11111', { data: { id: 1 } }) + + expect(security.authenticatedUsers.tokenOf({ id: 1 })).to.equal('11111') + }) + + it('returns undefined if no user is passed in', () => { + expect(security.authenticatedUsers.tokenOf(undefined)).to.equal(undefined) + expect(security.authenticatedUsers.tokenOf(null)).to.equal(undefined) + }) + + it('returns user by associated token from request', () => { + security.authenticatedUsers.put('11111', { data: { id: 1 } }) + + expect(security.authenticatedUsers.from({ headers: { authorization: 'Bearer 11111' } })).to.deep.equal({ data: { id: 1 } }) + }) + + it('returns undefined if no token is present in request', () => { + expect(security.authenticatedUsers.from({ headers: {} })).to.equal(undefined) + expect(security.authenticatedUsers.from({})).to.equal(undefined) + }) + }) + + describe('sanitizeHtml', () => { + it('handles empty inputs by returning their string representation', () => { + expect(security.sanitizeHtml()).to.equal('undefined') + expect(security.sanitizeHtml(undefined)).to.equal('undefined') + expect(security.sanitizeHtml(null)).to.equal('null') + expect(security.sanitizeHtml('')).to.equal('') + }) + + it('returns input unchanged for plain text input', () => { + expect(security.sanitizeHtml('This application is horrible!')).to.equal('This application is horrible!') + }) + + it('returns input unchanged for HTML input with only harmless text formatting', () => { + expect(security.sanitizeHtml('This application is horrible!')).to.equal('This application is horrible!') + }) + + it('returns input unchanged for HTML input with only harmless links', () => { + expect(security.sanitizeHtml('Please see here for details!')).to.equal('Please see here for details!') + }) + + it('removes all Javascript from HTML input', () => { + expect(security.sanitizeHtml('SanitizedScript')).to.equal('SanitizedScript') + expect(security.sanitizeHtml('SanitizedImage')).to.equal('SanitizedImage') + expect(security.sanitizeHtml('SanitizedIFrame')).to.equal('SanitizedIFrame') + }) + + it('can be bypassed by exploiting lack of recursive sanitization', () => { + expect(security.sanitizeHtml('<iframe src="javascript:alert(`xss`)">')).to.equal('tizedIFrame')).to.equal('SanitizedIFrame') + }) + + it('cannot be bypassed by exploiting lack of recursive sanitization', () => { + expect(security.sanitizeSecure('Bla<iframe src="javascript:alert(`xss`)">Blubb')).to.equal('BlaBlubb') + }) + }) + + describe('hash', () => { + it('throws type error for for undefined input', () => { + expect(() => security.hash()).to.throw(TypeError) + }) + + it('returns MD5 hash for any input string', () => { + expect(security.hash('admin123')).to.equal('0192023a7bbd73250516f069df18b500') + expect(security.hash('password')).to.equal('5f4dcc3b5aa765d61d8327deb882cf99') + expect(security.hash('')).to.equal('d41d8cd98f00b204e9800998ecf8427e') + }) + }) + + describe('hmac', () => { + it('throws type error for for undefined input', () => { + expect(() => security.hmac()).to.throw(TypeError) + }) + + it('returns SHA-256 HMAC with "pa4qacea4VK9t9nGv7yZtwmj" as salt any input string', () => { + expect(security.hmac('admin123')).to.equal('6be13e2feeada221f29134db71c0ab0be0e27eccfc0fb436ba4096ba73aafb20') + expect(security.hmac('password')).to.equal('da28fc4354f4a458508a461fbae364720c4249c27f10fccf68317fc4bf6531ed') + expect(security.hmac('')).to.equal('f052179ec5894a2e79befa8060cfcb517f1e14f7f6222af854377b6481ae953e') + }) + }) +}) diff --git a/test/server/keyServerSpec.ts b/test/server/keyServerSpec.ts index 88354d57..8dfaef9e 100644 --- a/test/server/keyServerSpec.ts +++ b/test/server/keyServerSpec.ts @@ -1,40 +1,40 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import sinon = require('sinon') -import chai = require('chai') -import sinonChai = require('sinon-chai') -const expect = chai.expect -chai.use(sinonChai) - -describe('keyServer', () => { - const serveKeyFiles = require('../../routes/keyServer') - let req: any - let res: any - let next: any - - beforeEach(() => { - req = { params: { } } - res = { sendFile: sinon.spy(), status: sinon.spy() } - next = sinon.spy() - }) - - it('should serve requested file from folder /encryptionkeys', () => { - req.params.file = 'test.file' - - serveKeyFiles()(req, res, next) - - expect(res.sendFile).to.have.been.calledWith(sinon.match(/encryptionkeys[/\\]test.file/)) - }) - - it('should raise error for slashes in filename', () => { - req.params.file = '../../../../nice.try' - - serveKeyFiles()(req, res, next) - - expect(res.sendFile).to.have.not.been.calledWith(sinon.match.any) - expect(next).to.have.been.calledWith(sinon.match.instanceOf(Error)) - }) -}) +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import sinon = require('sinon') +import chai = require('chai') +import sinonChai = require('sinon-chai') +const expect = chai.expect +chai.use(sinonChai) + +describe('keyServer', () => { + const serveKeyFiles = require('../../routes/keyServer') + let req: any + let res: any + let next: any + + beforeEach(() => { + req = { params: { } } + res = { sendFile: sinon.spy(), status: sinon.spy() } + next = sinon.spy() + }) + + it('should serve requested file from folder /encryptionkeys', () => { + req.params.file = 'test.file' + + serveKeyFiles()(req, res, next) + + expect(res.sendFile).to.have.been.calledWith(sinon.match(/encryptionkeys[/\\]test.file/)) + }) + + it('should raise error for slashes in filename', () => { + req.params.file = '../../../../nice.try' + + serveKeyFiles()(req, res, next) + + expect(res.sendFile).to.have.not.been.calledWith(sinon.match.any) + expect(next).to.have.been.calledWith(sinon.match.instanceOf(Error)) + }) +}) diff --git a/test/server/preconditionValidationSpec.ts b/test/server/preconditionValidationSpec.ts index 54a4c069..96a434c8 100644 --- a/test/server/preconditionValidationSpec.ts +++ b/test/server/preconditionValidationSpec.ts @@ -1,74 +1,74 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import chai = require('chai') -import sinonChai = require('sinon-chai') -import { checkIfRunningOnSupportedNodeVersion, checkIfPortIsAvailable } from '../../lib/startup/validatePreconditions' - -const expect = chai.expect -const net = require('net') -chai.use(sinonChai) - -const semver = require('semver') - -describe('preconditionValidation', () => { - describe('checkIfRunningOnSupportedNodeVersion', () => { - const supportedVersion = require('./../../package.json').engines.node - - it('should define the supported semver range as 18 - 22', () => { - expect(supportedVersion).to.equal('18 - 22') - expect(semver.validRange(supportedVersion)).to.not.equal(null) - }) - - it('should accept a supported version', () => { - expect(checkIfRunningOnSupportedNodeVersion('22.4.1')).to.equal(true) - expect(checkIfRunningOnSupportedNodeVersion('21.7.3')).to.equal(true) - expect(checkIfRunningOnSupportedNodeVersion('20.15.1')).to.equal(true) - expect(checkIfRunningOnSupportedNodeVersion('19.9.0')).to.equal(true) - expect(checkIfRunningOnSupportedNodeVersion('18.20.4')).to.equal(true) - }) - - it('should fail for an unsupported version', () => { - expect(checkIfRunningOnSupportedNodeVersion('23.0.0')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('17.3.0')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('16.10.0')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('15.9.0')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('14.0.0')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('13.13.0')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('12.16.2')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('11.14.0')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('10.20.0')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('9.11.2')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('8.12.0')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('7.10.1')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('6.14.4')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('4.9.1')).to.equal(false) - expect(checkIfRunningOnSupportedNodeVersion('0.12.8')).to.equal(false) - }) - }) - - describe('checkIfPortIsAvailable', () => { - it('should resolve when port 3000 is closed', async () => { - const success = await checkIfPortIsAvailable(3000) - expect(success).to.equal(true) - }) - - describe('open a server before running the test', () => { - const testServer = net.createServer() - before((done) => { - testServer.listen(3000, done) - }) - - it('should reject when port 3000 is open', async () => { - const success = await checkIfPortIsAvailable(3000) - expect(success).to.equal(false) - }) - - after((done) => { - testServer.close(done) - }) - }) - }) -}) +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import chai = require('chai') +import sinonChai = require('sinon-chai') +import { checkIfRunningOnSupportedNodeVersion, checkIfPortIsAvailable } from '../../lib/startup/validatePreconditions' + +const expect = chai.expect +const net = require('net') +chai.use(sinonChai) + +const semver = require('semver') + +describe('preconditionValidation', () => { + describe('checkIfRunningOnSupportedNodeVersion', () => { + const supportedVersion = require('./../../package.json').engines.node + + it('should define the supported semver range as 18 - 22', () => { + expect(supportedVersion).to.equal('18 - 22') + expect(semver.validRange(supportedVersion)).to.not.equal(null) + }) + + it('should accept a supported version', () => { + expect(checkIfRunningOnSupportedNodeVersion('22.4.1')).to.equal(true) + expect(checkIfRunningOnSupportedNodeVersion('21.7.3')).to.equal(true) + expect(checkIfRunningOnSupportedNodeVersion('20.15.1')).to.equal(true) + expect(checkIfRunningOnSupportedNodeVersion('19.9.0')).to.equal(true) + expect(checkIfRunningOnSupportedNodeVersion('18.20.4')).to.equal(true) + }) + + it('should fail for an unsupported version', () => { + expect(checkIfRunningOnSupportedNodeVersion('23.0.0')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('17.3.0')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('16.10.0')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('15.9.0')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('14.0.0')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('13.13.0')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('12.16.2')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('11.14.0')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('10.20.0')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('9.11.2')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('8.12.0')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('7.10.1')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('6.14.4')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('4.9.1')).to.equal(false) + expect(checkIfRunningOnSupportedNodeVersion('0.12.8')).to.equal(false) + }) + }) + + describe('checkIfPortIsAvailable', () => { + it('should resolve when port 3000 is closed', async () => { + const success = await checkIfPortIsAvailable(3000) + expect(success).to.equal(true) + }) + + describe('open a server before running the test', () => { + const testServer = net.createServer() + before((done) => { + testServer.listen(3000, done) + }) + + it('should reject when port 3000 is open', async () => { + const success = await checkIfPortIsAvailable(3000) + expect(success).to.equal(false) + }) + + after((done) => { + testServer.close(done) + }) + }) + }) +}) diff --git a/test/server/premiumRewardSpec.ts b/test/server/premiumRewardSpec.ts index 33287c59..5548947c 100644 --- a/test/server/premiumRewardSpec.ts +++ b/test/server/premiumRewardSpec.ts @@ -1,40 +1,40 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import sinon = require('sinon') -import chai = require('chai') -import sinonChai = require('sinon-chai') -const expect = chai.expect -chai.use(sinonChai) - -describe('premiumReward', () => { - const servePremiumContent = require('../../routes/premiumReward') - const challenges = require('../../data/datacache').challenges - let req: any - let res: any - let save: any - - beforeEach(() => { - res = { sendFile: sinon.spy() } - req = {} - save = () => ({ - then () { } - }) - }) - - it('should serve /frontend/dist/frontend/assets/private/JuiceShop_Wallpaper_1920x1080_VR.jpg', () => { - servePremiumContent()(req, res) - - expect(res.sendFile).to.have.been.calledWith(sinon.match(/frontend[/\\]dist[/\\]frontend[/\\]assets[/\\]private[/\\]JuiceShop_Wallpaper_1920x1080_VR\.jpg/)) - }) - - it('should solve "premiumPaywallChallenge"', () => { - challenges.premiumPaywallChallenge = { solved: false, save } - - servePremiumContent()(req, res) - - expect(challenges.premiumPaywallChallenge.solved).to.equal(true) - }) -}) +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import sinon = require('sinon') +import chai = require('chai') +import sinonChai = require('sinon-chai') +const expect = chai.expect +chai.use(sinonChai) + +describe('premiumReward', () => { + const servePremiumContent = require('../../routes/premiumReward') + const challenges = require('../../data/datacache').challenges + let req: any + let res: any + let save: any + + beforeEach(() => { + res = { sendFile: sinon.spy() } + req = {} + save = () => ({ + then () { } + }) + }) + + it('should serve /frontend/dist/frontend/assets/private/JuiceShop_Wallpaper_1920x1080_VR.jpg', () => { + servePremiumContent()(req, res) + + expect(res.sendFile).to.have.been.calledWith(sinon.match(/frontend[/\\]dist[/\\]frontend[/\\]assets[/\\]private[/\\]JuiceShop_Wallpaper_1920x1080_VR\.jpg/)) + }) + + it('should solve "premiumPaywallChallenge"', () => { + challenges.premiumPaywallChallenge = { solved: false, save } + + servePremiumContent()(req, res) + + expect(challenges.premiumPaywallChallenge.solved).to.equal(true) + }) +}) diff --git a/test/server/redirectSpec.ts b/test/server/redirectSpec.ts index 32520ad9..8f020b21 100644 --- a/test/server/redirectSpec.ts +++ b/test/server/redirectSpec.ts @@ -1,85 +1,85 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import sinon = require('sinon') -import chai = require('chai') -import sinonChai = require('sinon-chai') -const expect = chai.expect -chai.use(sinonChai) - -describe('redirect', () => { - const performRedirect = require('../../routes/redirect') - const challenges = require('../../data/datacache').challenges - let req: any - let res: any - let next: any - let save: any - - beforeEach(() => { - req = { query: {} } - res = { redirect: sinon.spy(), status: sinon.spy() } - next = sinon.spy() - save = () => ({ - then () { } - }) - }) - - describe('should be performed for all allowlisted URLs', () => { - for (const url of require('../../lib/insecurity').redirectAllowlist) { - it(url, () => { - req.query.to = url - - performRedirect()(req, res, next) - - expect(res.redirect).to.have.been.calledWith(url) - }) - } - }) - - it('should raise error for URL not on allowlist', () => { - req.query.to = 'http://kimminich.de' - - performRedirect()(req, res, next) - - expect(res.redirect).to.have.not.been.calledWith(sinon.match.any) - expect(next).to.have.been.calledWith(sinon.match.instanceOf(Error)) - }) - - it('redirecting to https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm should solve the "redirectCryptoCurrencyChallenge"', () => { - req.query.to = 'https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm' - challenges.redirectCryptoCurrencyChallenge = { solved: false, save } - - performRedirect()(req, res) - - expect(challenges.redirectCryptoCurrencyChallenge.solved).to.equal(true) - }) - - it('redirecting to https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW should solve the "redirectCryptoCurrencyChallenge"', () => { - req.query.to = 'https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW' - challenges.redirectCryptoCurrencyChallenge = { solved: false, save } - - performRedirect()(req, res) - - expect(challenges.redirectCryptoCurrencyChallenge.solved).to.equal(true) - }) - - it('redirecting to https://etherscan.io/address/0x0f933ab9fcaaa782d0279c300d73750e1311eae6 should solve the "redirectCryptoCurrencyChallenge"', () => { - req.query.to = 'https://etherscan.io/address/0x0f933ab9fcaaa782d0279c300d73750e1311eae6' - challenges.redirectCryptoCurrencyChallenge = { solved: false, save } - - performRedirect()(req, res) - - expect(challenges.redirectCryptoCurrencyChallenge.solved).to.equal(true) - }) - - it('tricking the allowlist should solve "redirectChallenge"', () => { - req.query.to = 'http://kimminich.de?to=https://github.com/juice-shop/juice-shop' - challenges.redirectChallenge = { solved: false, save } - - performRedirect()(req, res) - - expect(challenges.redirectChallenge.solved).to.equal(true) - }) -}) +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import sinon = require('sinon') +import chai = require('chai') +import sinonChai = require('sinon-chai') +const expect = chai.expect +chai.use(sinonChai) + +describe('redirect', () => { + const performRedirect = require('../../routes/redirect') + const challenges = require('../../data/datacache').challenges + let req: any + let res: any + let next: any + let save: any + + beforeEach(() => { + req = { query: {} } + res = { redirect: sinon.spy(), status: sinon.spy() } + next = sinon.spy() + save = () => ({ + then () { } + }) + }) + + describe('should be performed for all allowlisted URLs', () => { + for (const url of require('../../lib/insecurity').redirectAllowlist) { + it(url, () => { + req.query.to = url + + performRedirect()(req, res, next) + + expect(res.redirect).to.have.been.calledWith(url) + }) + } + }) + + it('should raise error for URL not on allowlist', () => { + req.query.to = 'http://kimminich.de' + + performRedirect()(req, res, next) + + expect(res.redirect).to.have.not.been.calledWith(sinon.match.any) + expect(next).to.have.been.calledWith(sinon.match.instanceOf(Error)) + }) + + it('redirecting to https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm should solve the "redirectCryptoCurrencyChallenge"', () => { + req.query.to = 'https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm' + challenges.redirectCryptoCurrencyChallenge = { solved: false, save } + + performRedirect()(req, res) + + expect(challenges.redirectCryptoCurrencyChallenge.solved).to.equal(true) + }) + + it('redirecting to https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW should solve the "redirectCryptoCurrencyChallenge"', () => { + req.query.to = 'https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW' + challenges.redirectCryptoCurrencyChallenge = { solved: false, save } + + performRedirect()(req, res) + + expect(challenges.redirectCryptoCurrencyChallenge.solved).to.equal(true) + }) + + it('redirecting to https://etherscan.io/address/0x0f933ab9fcaaa782d0279c300d73750e1311eae6 should solve the "redirectCryptoCurrencyChallenge"', () => { + req.query.to = 'https://etherscan.io/address/0x0f933ab9fcaaa782d0279c300d73750e1311eae6' + challenges.redirectCryptoCurrencyChallenge = { solved: false, save } + + performRedirect()(req, res) + + expect(challenges.redirectCryptoCurrencyChallenge.solved).to.equal(true) + }) + + it('tricking the allowlist should solve "redirectChallenge"', () => { + req.query.to = 'http://kimminich.de?to=https://github.com/juice-shop/juice-shop' + challenges.redirectChallenge = { solved: false, save } + + performRedirect()(req, res) + + expect(challenges.redirectChallenge.solved).to.equal(true) + }) +}) diff --git a/test/server/utilsSpec.ts b/test/server/utilsSpec.ts index ed120f70..cadb7729 100644 --- a/test/server/utilsSpec.ts +++ b/test/server/utilsSpec.ts @@ -1,168 +1,168 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import type { ChallengeModel } from 'models/challenge' -import { getChallengeEnablementStatus } from '../../lib/utils' - -import chai = require('chai') -const expect = chai.expect - -describe('utils', () => { - const utils = require('../../lib/utils') - - describe('toSimpleIpAddress', () => { - it('returns ipv6 address unchanged', () => { - expect(utils.toSimpleIpAddress('2001:0db8:85a3:0000:0000:8a2e:0370:7334')).to.equal('2001:0db8:85a3:0000:0000:8a2e:0370:7334') - }) - - it('returns ipv4 address fully specified as ipv6 unchanged', () => { - expect(utils.toSimpleIpAddress('0:0:0:0:0:ffff:7f00:1')).to.equal('0:0:0:0:0:ffff:7f00:1') - }) - - it('returns ipv6 loopback address as ipv4 address', () => { - expect(utils.toSimpleIpAddress('::1')).to.equal('127.0.0.1') - }) - - it('returns ipv4-mapped address as ipv4 address', () => { - expect(utils.toSimpleIpAddress('::ffff:192.0.2.128')).to.equal('192.0.2.128') - }) - }) - - describe('extractFilename', () => { - it('returns standalone filename unchanged', () => { - expect(utils.extractFilename('test.exe')).to.equal('test.exe') - }) - - it('returns filename from http:// URL', () => { - expect(utils.extractFilename('http://bla.blubb/test.exe')).to.equal('test.exe') - }) - - it('ignores query part of http:// URL', () => { - expect(utils.extractFilename('http://bla.blubb/test.exe?bla=blubb&a=b')).to.equal('test.exe') - }) - - it('also works for file:// URLs', () => { - expect(utils.extractFilename('file:///C//Bla/Blubb/test.exe')).to.equal('test.exe') - }) - }) - - describe('matchesSystemIniFile', () => { - it('fails on plain input string', () => { - expect(utils.matchesSystemIniFile('Bla Blubb')).to.equal(false) - }) - - it('passes on Windows 10 system.ini file content', () => { - expect(utils.matchesSystemIniFile('; for 16-bit app support\n' + - '[386Enh]\n' + - 'woafont=dosapp.fon\n' + - 'EGA80WOA.FON=EGA80WOA.FON\n' + - 'EGA40WOA.FON=EGA40WOA.FON\n' + - 'CGA80WOA.FON=CGA80WOA.FON\n' + - 'CGA40WOA.FON=CGA40WOA.FON\n' + - '\n' + - '[drivers]\n' + - 'wave=mmdrv.dll\n' + - 'timer=timer.drv\n' + - '\n' + - '[mci]\n')).to.equal(true) - }) - }) - - describe('matchesEtcPasswdFile', () => { - it('fails on plain input string', () => { - expect(utils.matchesEtcPasswdFile('Bla Blubb')).to.equal(false) - }) - - it('passes on Arch Linux passwd file content', () => { - expect(utils.matchesEtcPasswdFile('test:x:0:0:test:/test:/usr/bin/zsh\n' + - 'bin:x:1:1::/:/usr/bin/nologin\n' + - 'daemon:x:2:2::/:/usr/bin/nologin\n' + - 'mail:x:8:12::/var/spool/mail:/usr/bin/nologin\n' + - 'ftp:x:14:11::/srv/ftp:/usr/bin/nologin\n' + - 'http:x:33:33::/srv/http:/usr/bin/nologin\n' + - 'nobody:x:65534:65534:Nobody:/:/usr/bin/nologin\n' + - 'dbus:x:81:81:System Message Bus:/:/usr/bin/nologin\n' + - 'systemd-journal-remote:x:988:988:systemd Journal Remote:/:/usr/bin/nologin\n' + - 'systemd-network:x:987:987:systemd Network Management:/:/usr/bin/nologin\n' + - 'systemd-oom:x:986:986:systemd Userspace OOM Killer:/:/usr/bin/nologin\n' + - 'systemd-resolve:x:984:984:systemd Resolver:/:/usr/bin/nologin\n' + - 'systemd-timesync:x:983:983:systemd Time Synchronization:/:/usr/bin/nologin\n' + - 'systemd-coredump:x:982:982:systemd Core Dumper:/:/usr/bin/nologin\n' + - 'uuidd:x:68:68::/:/usr/bin/nologin\n' + - 'avahi:x:980:980:Avahi mDNS/DNS-SD daemon:/:/usr/bin/nologin\n' + - 'named:x:40:40:BIND DNS Server:/:/usr/bin/nologin\n' + - 'brltty:x:979:979:Braille Device Daemon:/var/lib/brltty:/usr/bin/nologin\n' + - 'colord:x:978:978:Color management daemon:/var/lib/colord:/usr/bin/nologin\n' + - 'cups:x:209:209:cups helper user:/:/usr/bin/nologin\n' + - 'dhcpcd:x:977:977:dhcpcd privilege separation:/:/usr/bin/nologin\n' + - 'dnsmasq:x:976:976:dnsmasq daemon:/:/usr/bin/nologin\n' + - 'git:x:975:975:git daemon user:/:/usr/bin/git-shell\n' + - 'mpd:x:45:45::/var/lib/mpd:/usr/bin/nologin\n' + - 'nbd:x:974:974:Network Block Device:/var/empty:/usr/bin/nologin\n' + - 'nm-openvpn:x:973:973:NetworkManager OpenVPN:/:/usr/bin/nologin\n' + - 'nvidia-persistenced:x:143:143:NVIDIA Persistence Daemon:/:/usr/bin/nologin\n' + - 'openvpn:x:972:972:OpenVPN:/:/usr/bin/nologin\n' + - 'partimag:x:110:110:Partimage user:/:/usr/bin/nologin\n' + - 'polkitd:x:102:102:PolicyKit daemon:/:/usr/bin/nologin\n' + - 'rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/usr/bin/nologin\n' + - 'rtkit:x:133:133:RealtimeKit:/proc:/usr/bin/nologin\n' + - 'sddm:x:971:971:Simple Desktop Display Manager:/var/lib/sddm:/usr/bin/nologin\n' + - 'tss:x:970:970:tss user for tpm2:/:/usr/bin/nologin\n' + - 'usbmux:x:140:140:usbmux user:/:/usr/bin/nologin\n' + - 'moi:x:1000:1000:moi:/home/moi:/bin/zsh\n')).to.equal(true) - }) - }) - - describe('getChallengeEnablementStatus', () => { - const defaultIsEnvironmentFunctions = { - isDocker: () => false, - isHeroku: () => false, - isWindows: () => false, - isGitpod: () => false - } - - for (const safetyMode of ['enabled', 'disabled', 'auto'] as const) { - it(`challenges without disabledEnv are enabled with safetyMode set to ${safetyMode}`, () => { - const challenge: ChallengeModel = { disabledEnv: null } as unknown as ChallengeModel - - expect(getChallengeEnablementStatus(challenge, safetyMode, defaultIsEnvironmentFunctions)) - .to.deep.equal({ enabled: true, disabledBecause: null }) - }) - } - - const testCases = [ - { name: 'Docker', environmentFunction: 'isDocker' }, - { name: 'Heroku', environmentFunction: 'isHeroku' }, - { name: 'Windows', environmentFunction: 'isWindows' }, - { name: 'Gitpod', environmentFunction: 'isGitpod' } - ] - - for (const testCase of testCases) { - it(`safetyMode: 'enabled': challenge with disabledOnEnv ${testCase.name} should be marked as disabled`, () => { - const challenge: ChallengeModel = { disabledEnv: testCase.name } as unknown as ChallengeModel - - const isEnvironmentFunctions = { ...defaultIsEnvironmentFunctions, [testCase.environmentFunction]: () => true } - expect(getChallengeEnablementStatus(challenge, 'enabled', isEnvironmentFunctions)) - .to.deep.equal({ enabled: false, disabledBecause: testCase.name }) - }) - - it(`safetyMode: 'auto': challenge with disabledOnEnv ${testCase.name} should be marked as disabled`, () => { - const challenge: ChallengeModel = { disabledEnv: testCase.name } as unknown as ChallengeModel - - const isEnvironmentFunctions = { ...defaultIsEnvironmentFunctions, [testCase.environmentFunction]: () => true } - expect(getChallengeEnablementStatus(challenge, 'auto', isEnvironmentFunctions)) - .to.deep.equal({ enabled: false, disabledBecause: testCase.name }) - }) - - it(`safetyMode: 'disabled': challenge with disabledOnEnv ${testCase.name} should be marked as enabled`, () => { - const challenge: ChallengeModel = { disabledEnv: testCase.name } as unknown as ChallengeModel - - const isEnvironmentFunctions = { ...defaultIsEnvironmentFunctions, [testCase.environmentFunction]: () => true } - expect(getChallengeEnablementStatus(challenge, 'disabled', isEnvironmentFunctions)) - .to.deep.equal({ enabled: true, disabledBecause: null }) - }) - } - }) -}) +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import type { ChallengeModel } from 'models/challenge' +import { getChallengeEnablementStatus } from '../../lib/utils' + +import chai = require('chai') +const expect = chai.expect + +describe('utils', () => { + const utils = require('../../lib/utils') + + describe('toSimpleIpAddress', () => { + it('returns ipv6 address unchanged', () => { + expect(utils.toSimpleIpAddress('2001:0db8:85a3:0000:0000:8a2e:0370:7334')).to.equal('2001:0db8:85a3:0000:0000:8a2e:0370:7334') + }) + + it('returns ipv4 address fully specified as ipv6 unchanged', () => { + expect(utils.toSimpleIpAddress('0:0:0:0:0:ffff:7f00:1')).to.equal('0:0:0:0:0:ffff:7f00:1') + }) + + it('returns ipv6 loopback address as ipv4 address', () => { + expect(utils.toSimpleIpAddress('::1')).to.equal('127.0.0.1') + }) + + it('returns ipv4-mapped address as ipv4 address', () => { + expect(utils.toSimpleIpAddress('::ffff:192.0.2.128')).to.equal('192.0.2.128') + }) + }) + + describe('extractFilename', () => { + it('returns standalone filename unchanged', () => { + expect(utils.extractFilename('test.exe')).to.equal('test.exe') + }) + + it('returns filename from http:// URL', () => { + expect(utils.extractFilename('http://bla.blubb/test.exe')).to.equal('test.exe') + }) + + it('ignores query part of http:// URL', () => { + expect(utils.extractFilename('http://bla.blubb/test.exe?bla=blubb&a=b')).to.equal('test.exe') + }) + + it('also works for file:// URLs', () => { + expect(utils.extractFilename('file:///C//Bla/Blubb/test.exe')).to.equal('test.exe') + }) + }) + + describe('matchesSystemIniFile', () => { + it('fails on plain input string', () => { + expect(utils.matchesSystemIniFile('Bla Blubb')).to.equal(false) + }) + + it('passes on Windows 10 system.ini file content', () => { + expect(utils.matchesSystemIniFile('; for 16-bit app support\n' + + '[386Enh]\n' + + 'woafont=dosapp.fon\n' + + 'EGA80WOA.FON=EGA80WOA.FON\n' + + 'EGA40WOA.FON=EGA40WOA.FON\n' + + 'CGA80WOA.FON=CGA80WOA.FON\n' + + 'CGA40WOA.FON=CGA40WOA.FON\n' + + '\n' + + '[drivers]\n' + + 'wave=mmdrv.dll\n' + + 'timer=timer.drv\n' + + '\n' + + '[mci]\n')).to.equal(true) + }) + }) + + describe('matchesEtcPasswdFile', () => { + it('fails on plain input string', () => { + expect(utils.matchesEtcPasswdFile('Bla Blubb')).to.equal(false) + }) + + it('passes on Arch Linux passwd file content', () => { + expect(utils.matchesEtcPasswdFile('test:x:0:0:test:/test:/usr/bin/zsh\n' + + 'bin:x:1:1::/:/usr/bin/nologin\n' + + 'daemon:x:2:2::/:/usr/bin/nologin\n' + + 'mail:x:8:12::/var/spool/mail:/usr/bin/nologin\n' + + 'ftp:x:14:11::/srv/ftp:/usr/bin/nologin\n' + + 'http:x:33:33::/srv/http:/usr/bin/nologin\n' + + 'nobody:x:65534:65534:Nobody:/:/usr/bin/nologin\n' + + 'dbus:x:81:81:System Message Bus:/:/usr/bin/nologin\n' + + 'systemd-journal-remote:x:988:988:systemd Journal Remote:/:/usr/bin/nologin\n' + + 'systemd-network:x:987:987:systemd Network Management:/:/usr/bin/nologin\n' + + 'systemd-oom:x:986:986:systemd Userspace OOM Killer:/:/usr/bin/nologin\n' + + 'systemd-resolve:x:984:984:systemd Resolver:/:/usr/bin/nologin\n' + + 'systemd-timesync:x:983:983:systemd Time Synchronization:/:/usr/bin/nologin\n' + + 'systemd-coredump:x:982:982:systemd Core Dumper:/:/usr/bin/nologin\n' + + 'uuidd:x:68:68::/:/usr/bin/nologin\n' + + 'avahi:x:980:980:Avahi mDNS/DNS-SD daemon:/:/usr/bin/nologin\n' + + 'named:x:40:40:BIND DNS Server:/:/usr/bin/nologin\n' + + 'brltty:x:979:979:Braille Device Daemon:/var/lib/brltty:/usr/bin/nologin\n' + + 'colord:x:978:978:Color management daemon:/var/lib/colord:/usr/bin/nologin\n' + + 'cups:x:209:209:cups helper user:/:/usr/bin/nologin\n' + + 'dhcpcd:x:977:977:dhcpcd privilege separation:/:/usr/bin/nologin\n' + + 'dnsmasq:x:976:976:dnsmasq daemon:/:/usr/bin/nologin\n' + + 'git:x:975:975:git daemon user:/:/usr/bin/git-shell\n' + + 'mpd:x:45:45::/var/lib/mpd:/usr/bin/nologin\n' + + 'nbd:x:974:974:Network Block Device:/var/empty:/usr/bin/nologin\n' + + 'nm-openvpn:x:973:973:NetworkManager OpenVPN:/:/usr/bin/nologin\n' + + 'nvidia-persistenced:x:143:143:NVIDIA Persistence Daemon:/:/usr/bin/nologin\n' + + 'openvpn:x:972:972:OpenVPN:/:/usr/bin/nologin\n' + + 'partimag:x:110:110:Partimage user:/:/usr/bin/nologin\n' + + 'polkitd:x:102:102:PolicyKit daemon:/:/usr/bin/nologin\n' + + 'rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/usr/bin/nologin\n' + + 'rtkit:x:133:133:RealtimeKit:/proc:/usr/bin/nologin\n' + + 'sddm:x:971:971:Simple Desktop Display Manager:/var/lib/sddm:/usr/bin/nologin\n' + + 'tss:x:970:970:tss user for tpm2:/:/usr/bin/nologin\n' + + 'usbmux:x:140:140:usbmux user:/:/usr/bin/nologin\n' + + 'moi:x:1000:1000:moi:/home/moi:/bin/zsh\n')).to.equal(true) + }) + }) + + describe('getChallengeEnablementStatus', () => { + const defaultIsEnvironmentFunctions = { + isDocker: () => false, + isHeroku: () => false, + isWindows: () => false, + isGitpod: () => false + } + + for (const safetyMode of ['enabled', 'disabled', 'auto'] as const) { + it(`challenges without disabledEnv are enabled with safetyMode set to ${safetyMode}`, () => { + const challenge: ChallengeModel = { disabledEnv: null } as unknown as ChallengeModel + + expect(getChallengeEnablementStatus(challenge, safetyMode, defaultIsEnvironmentFunctions)) + .to.deep.equal({ enabled: true, disabledBecause: null }) + }) + } + + const testCases = [ + { name: 'Docker', environmentFunction: 'isDocker' }, + { name: 'Heroku', environmentFunction: 'isHeroku' }, + { name: 'Windows', environmentFunction: 'isWindows' }, + { name: 'Gitpod', environmentFunction: 'isGitpod' } + ] + + for (const testCase of testCases) { + it(`safetyMode: 'enabled': challenge with disabledOnEnv ${testCase.name} should be marked as disabled`, () => { + const challenge: ChallengeModel = { disabledEnv: testCase.name } as unknown as ChallengeModel + + const isEnvironmentFunctions = { ...defaultIsEnvironmentFunctions, [testCase.environmentFunction]: () => true } + expect(getChallengeEnablementStatus(challenge, 'enabled', isEnvironmentFunctions)) + .to.deep.equal({ enabled: false, disabledBecause: testCase.name }) + }) + + it(`safetyMode: 'auto': challenge with disabledOnEnv ${testCase.name} should be marked as disabled`, () => { + const challenge: ChallengeModel = { disabledEnv: testCase.name } as unknown as ChallengeModel + + const isEnvironmentFunctions = { ...defaultIsEnvironmentFunctions, [testCase.environmentFunction]: () => true } + expect(getChallengeEnablementStatus(challenge, 'auto', isEnvironmentFunctions)) + .to.deep.equal({ enabled: false, disabledBecause: testCase.name }) + }) + + it(`safetyMode: 'disabled': challenge with disabledOnEnv ${testCase.name} should be marked as enabled`, () => { + const challenge: ChallengeModel = { disabledEnv: testCase.name } as unknown as ChallengeModel + + const isEnvironmentFunctions = { ...defaultIsEnvironmentFunctions, [testCase.environmentFunction]: () => true } + expect(getChallengeEnablementStatus(challenge, 'disabled', isEnvironmentFunctions)) + .to.deep.equal({ enabled: true, disabledBecause: null }) + }) + } + }) +}) diff --git a/test/server/verifySpec.ts b/test/server/verifySpec.ts index 4c9b3181..d2aac717 100644 --- a/test/server/verifySpec.ts +++ b/test/server/verifySpec.ts @@ -1,326 +1,326 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import sinon = require('sinon') -import config from 'config' -import type { Product as ProductConfig } from '../../lib/config.types' -import chai = require('chai') -import sinonChai = require('sinon-chai') -const expect = chai.expect -chai.use(sinonChai) -const cache = require('../../data/datacache') -const security = require('../../lib/insecurity') -const utils = require('../../lib/utils') - -describe('verify', () => { - const verify = require('../../routes/verify') - const challenges = require('../../data/datacache').challenges - let req: any - let res: any - let next: any - let save: any - let err: any - - beforeEach(() => { - req = { body: {}, headers: {} } - res = { json: sinon.spy() } - next = sinon.spy() - save = () => ({ - then () { } - }) - }) - - describe('"forgedFeedbackChallenge"', () => { - beforeEach(() => { - security.authenticatedUsers.put('token12345', { - data: { - id: 42, - email: 'test@juice-sh.op' - } - }) - challenges.forgedFeedbackChallenge = { solved: false, save } - }) - - it('is not solved when an authenticated user passes his own ID when writing feedback', () => { - req.body.UserId = 42 - req.headers = { authorization: 'Bearer token12345' } - - verify.forgedFeedbackChallenge()(req, res, next) - - expect(challenges.forgedFeedbackChallenge.solved).to.equal(false) - }) - - it('is not solved when an authenticated user passes no ID when writing feedback', () => { - req.body.UserId = undefined - req.headers = { authorization: 'Bearer token12345' } - - verify.forgedFeedbackChallenge()(req, res, next) - - expect(challenges.forgedFeedbackChallenge.solved).to.equal(false) - }) - - it('is solved when an authenticated user passes someone elses ID when writing feedback', () => { - req.body.UserId = 1 - req.headers = { authorization: 'Bearer token12345' } - - verify.forgedFeedbackChallenge()(req, res, next) - - expect(challenges.forgedFeedbackChallenge.solved).to.equal(true) - }) - - it('is solved when an unauthenticated user passes someones ID when writing feedback', () => { - req.body.UserId = 1 - req.headers = {} - - verify.forgedFeedbackChallenge()(req, res, next) - - expect(challenges.forgedFeedbackChallenge.solved).to.equal(true) - }) - }) - - describe('accessControlChallenges', () => { - it('"scoreBoardChallenge" is solved when the 1px.png transpixel is requested', () => { - challenges.scoreBoardChallenge = { solved: false, save } - req.url = 'http://juice-sh.op/public/images/padding/1px.png' - - verify.accessControlChallenges()(req, res, next) - - expect(challenges.scoreBoardChallenge.solved).to.equal(true) - }) - - it('"adminSectionChallenge" is solved when the 19px.png transpixel is requested', () => { - challenges.adminSectionChallenge = { solved: false, save } - req.url = 'http://juice-sh.op/public/images/padding/19px.png' - - verify.accessControlChallenges()(req, res, next) - - expect(challenges.adminSectionChallenge.solved).to.equal(true) - }) - - it('"tokenSaleChallenge" is solved when the 56px.png transpixel is requested', () => { - challenges.tokenSaleChallenge = { solved: false, save } - req.url = 'http://juice-sh.op/public/images/padding/56px.png' - - verify.accessControlChallenges()(req, res, next) - - expect(challenges.tokenSaleChallenge.solved).to.equal(true) - }) - - it('"extraLanguageChallenge" is solved when the Klingon translation file is requested', () => { - challenges.extraLanguageChallenge = { solved: false, save } - req.url = 'http://juice-sh.op/public/i18n/tlh_AA.json' - - verify.accessControlChallenges()(req, res, next) - - expect(challenges.extraLanguageChallenge.solved).to.equal(true) - }) - - it('"retrieveBlueprintChallenge" is solved when the blueprint file is requested', () => { - challenges.retrieveBlueprintChallenge = { solved: false, save } - cache.retrieveBlueprintChallengeFile = 'test.dxf' - req.url = 'http://juice-sh.op/public/images/products/test.dxf' - - verify.accessControlChallenges()(req, res, next) - - expect(challenges.retrieveBlueprintChallenge.solved).to.equal(true) - }) - - it('"missingEncodingChallenge" is solved when the crazy cat photo is requested', () => { - challenges.missingEncodingChallenge = { solved: false, save } - req.url = 'http://juice-sh.op/public/images/uploads/%F0%9F%98%BC-%23zatschi-%23whoneedsfourlegs-1572600969477.jpg' - - verify.accessControlChallenges()(req, res, next) - - expect(challenges.missingEncodingChallenge.solved).to.equal(true) - }) - - it('"accessLogDisclosureChallenge" is solved when any server access log file is requested', () => { - challenges.accessLogDisclosureChallenge = { solved: false, save } - req.url = 'http://juice-sh.op/support/logs/access.log.2019-01-15' - - verify.accessControlChallenges()(req, res, next) - - expect(challenges.accessLogDisclosureChallenge.solved).to.equal(true) - }) - }) - - describe('"errorHandlingChallenge"', () => { - beforeEach(() => { - challenges.errorHandlingChallenge = { solved: false, save } - }) - - it('is solved when an error occurs on a response with OK 200 status code', () => { - res.statusCode = 200 - err = new Error() - - verify.errorHandlingChallenge()(err, req, res, next) - - expect(challenges.errorHandlingChallenge.solved).to.equal(true) - }) - - describe('is solved when an error occurs on a response with error', () => { - const httpStatus = [402, 403, 404, 500] - httpStatus.forEach(statusCode => { - it(`${statusCode} status code`, () => { - res.statusCode = statusCode - err = new Error() - - verify.errorHandlingChallenge()(err, req, res, next) - - expect(challenges.errorHandlingChallenge.solved).to.equal(true) - }) - }) - }) - - it('is not solved when no error occurs on a response with OK 200 status code', () => { - res.statusCode = 200 - err = undefined - - verify.errorHandlingChallenge()(err, req, res, next) - - expect(challenges.errorHandlingChallenge.solved).to.equal(false) - }) - - describe('is not solved when no error occurs on a response with error', () => { - const httpStatus = [401, 402, 404, 500] - httpStatus.forEach(statusCode => { - it(`${statusCode} status code`, () => { - res.statusCode = statusCode - err = undefined - - verify.errorHandlingChallenge()(err, req, res, next) - - expect(challenges.errorHandlingChallenge.solved).to.equal(false) - }) - }) - }) - - it('should pass occured error on to next route', () => { - res.statusCode = 500 - err = new Error() - - verify.errorHandlingChallenge()(err, req, res, next) - - expect(next).to.have.been.calledWith(err) - }) - }) - - describe('databaseRelatedChallenges', () => { - describe('"changeProductChallenge"', () => { - const products = require('../../data/datacache').products - - beforeEach(() => { - challenges.changeProductChallenge = { solved: false, save } - products.osaft = { reload () { return { then (cb: any) { cb() } } } } - }) - - it(`is solved when the link in the O-Saft product goes to ${config.get('challenges.overwriteUrlForProductTamperingChallenge')}`, () => { - products.osaft.description = `O-Saft, yeah! More...` - - verify.databaseRelatedChallenges()(req, res, next) - - expect(challenges.changeProductChallenge.solved).to.equal(true) - }) - - it('is not solved when the link in the O-Saft product is changed to an arbitrary URL', () => { - products.osaft.description = 'O-Saft, nooo! More...' - - verify.databaseRelatedChallenges()(req, res, next) - - expect(challenges.changeProductChallenge.solved).to.equal(false) - }) - - it('is not solved when the link in the O-Saft product remained unchanged', () => { - let urlForProductTamperingChallenge = null - for (const product of config.get('products')) { - if (product.urlForProductTamperingChallenge !== undefined) { - urlForProductTamperingChallenge = product.urlForProductTamperingChallenge - break - } - } - products.osaft.description = `Vanilla O-Saft! More...` - - verify.databaseRelatedChallenges()(req, res, next) - - expect(challenges.changeProductChallenge.solved).to.equal(false) - }) - }) - }) - - describe('jwtChallenges', () => { - beforeEach(() => { - challenges.jwtUnsignedChallenge = { solved: false, save } - challenges.jwtForgedChallenge = { solved: false, save } - }) - - it('"jwtUnsignedChallenge" is solved when forged unsigned token has email jwtn3d@juice-sh.op in the payload', () => { - /* - Header: { "alg": "none", "typ": "JWT" } - Payload: { "data": { "email": "jwtn3d@juice-sh.op" }, "iat": 1508639612, "exp": 9999999999 } - */ - req.headers = { authorization: 'Bearer eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJkYXRhIjp7ImVtYWlsIjoiand0bjNkQGp1aWNlLXNoLm9wIn0sImlhdCI6MTUwODYzOTYxMiwiZXhwIjo5OTk5OTk5OTk5fQ.' } - - verify.jwtChallenges()(req, res, next) - - expect(challenges.jwtUnsignedChallenge.solved).to.equal(true) - }) - - it('"jwtUnsignedChallenge" is solved when forged unsigned token has string "jwtn3d@" in the payload', () => { - /* - Header: { "alg": "none", "typ": "JWT" } - Payload: { "data": { "email": "jwtn3d@" }, "iat": 1508639612, "exp": 9999999999 } - */ - req.headers = { authorization: 'Bearer eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJkYXRhIjp7ImVtYWlsIjoiand0bjNkQCJ9LCJpYXQiOjE1MDg2Mzk2MTIsImV4cCI6OTk5OTk5OTk5OX0.' } - - verify.jwtChallenges()(req, res, next) - - expect(challenges.jwtUnsignedChallenge.solved).to.equal(true) - }) - - it('"jwtUnsignedChallenge" is not solved via regularly signed token even with email jwtn3d@juice-sh.op in the payload', () => { - const token = security.authorize({ data: { email: 'jwtn3d@juice-sh.op' } }) - req.headers = { authorization: `Bearer ${token}` } - - verify.jwtChallenges()(req, res, next) - - expect(challenges.jwtForgedChallenge.solved).to.equal(false) - }) - - if (utils.isChallengeEnabled(challenges.jwtForgedChallenge)) { - it('"jwtForgedChallenge" is solved when forged token HMAC-signed with public RSA-key has email rsa_lord@juice-sh.op in the payload', () => { - /* - Header: { "alg": "HS256", "typ": "JWT" } - Payload: { "data": { "email": "rsa_lord@juice-sh.op" }, "iat": 1508639612, "exp": 9999999999 } - */ - req.headers = { authorization: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7ImVtYWlsIjoicnNhX2xvcmRAanVpY2Utc2gub3AifSwiaWF0IjoxNTgyMjIxNTc1fQ.ycFwtqh4ht4Pq9K5rhiPPY256F9YCTIecd4FHFuSEAg' } - - verify.jwtChallenges()(req, res, next) - - expect(challenges.jwtForgedChallenge.solved).to.equal(true) - }) - - it('"jwtForgedChallenge" is solved when forged token HMAC-signed with public RSA-key has string "rsa_lord@" in the payload', () => { - /* - Header: { "alg": "HS256", "typ": "JWT" } - Payload: { "data": { "email": "rsa_lord@" }, "iat": 1508639612, "exp": 9999999999 } - */ - req.headers = { authorization: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7ImVtYWlsIjoicnNhX2xvcmRAIn0sImlhdCI6MTU4MjIyMTY3NX0.50f6VAIQk2Uzpf3sgH-1JVrrTuwudonm2DKn2ec7Tg8' } - - verify.jwtChallenges()(req, res, next) - - expect(challenges.jwtForgedChallenge.solved).to.equal(true) - }) - - it('"jwtForgedChallenge" is not solved when token regularly signed with private RSA-key has email rsa_lord@juice-sh.op in the payload', () => { - const token = security.authorize({ data: { email: 'rsa_lord@juice-sh.op' } }) - req.headers = { authorization: `Bearer ${token}` } - - verify.jwtChallenges()(req, res, next) - - expect(challenges.jwtForgedChallenge.solved).to.equal(false) - }) - } - }) -}) +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import sinon = require('sinon') +import config from 'config' +import type { Product as ProductConfig } from '../../lib/config.types' +import chai = require('chai') +import sinonChai = require('sinon-chai') +const expect = chai.expect +chai.use(sinonChai) +const cache = require('../../data/datacache') +const security = require('../../lib/insecurity') +const utils = require('../../lib/utils') + +describe('verify', () => { + const verify = require('../../routes/verify') + const challenges = require('../../data/datacache').challenges + let req: any + let res: any + let next: any + let save: any + let err: any + + beforeEach(() => { + req = { body: {}, headers: {} } + res = { json: sinon.spy() } + next = sinon.spy() + save = () => ({ + then () { } + }) + }) + + describe('"forgedFeedbackChallenge"', () => { + beforeEach(() => { + security.authenticatedUsers.put('token12345', { + data: { + id: 42, + email: 'test@juice-sh.op' + } + }) + challenges.forgedFeedbackChallenge = { solved: false, save } + }) + + it('is not solved when an authenticated user passes his own ID when writing feedback', () => { + req.body.UserId = 42 + req.headers = { authorization: 'Bearer token12345' } + + verify.forgedFeedbackChallenge()(req, res, next) + + expect(challenges.forgedFeedbackChallenge.solved).to.equal(false) + }) + + it('is not solved when an authenticated user passes no ID when writing feedback', () => { + req.body.UserId = undefined + req.headers = { authorization: 'Bearer token12345' } + + verify.forgedFeedbackChallenge()(req, res, next) + + expect(challenges.forgedFeedbackChallenge.solved).to.equal(false) + }) + + it('is solved when an authenticated user passes someone elses ID when writing feedback', () => { + req.body.UserId = 1 + req.headers = { authorization: 'Bearer token12345' } + + verify.forgedFeedbackChallenge()(req, res, next) + + expect(challenges.forgedFeedbackChallenge.solved).to.equal(true) + }) + + it('is solved when an unauthenticated user passes someones ID when writing feedback', () => { + req.body.UserId = 1 + req.headers = {} + + verify.forgedFeedbackChallenge()(req, res, next) + + expect(challenges.forgedFeedbackChallenge.solved).to.equal(true) + }) + }) + + describe('accessControlChallenges', () => { + it('"scoreBoardChallenge" is solved when the 1px.png transpixel is requested', () => { + challenges.scoreBoardChallenge = { solved: false, save } + req.url = 'http://juice-sh.op/public/images/padding/1px.png' + + verify.accessControlChallenges()(req, res, next) + + expect(challenges.scoreBoardChallenge.solved).to.equal(true) + }) + + it('"adminSectionChallenge" is solved when the 19px.png transpixel is requested', () => { + challenges.adminSectionChallenge = { solved: false, save } + req.url = 'http://juice-sh.op/public/images/padding/19px.png' + + verify.accessControlChallenges()(req, res, next) + + expect(challenges.adminSectionChallenge.solved).to.equal(true) + }) + + it('"tokenSaleChallenge" is solved when the 56px.png transpixel is requested', () => { + challenges.tokenSaleChallenge = { solved: false, save } + req.url = 'http://juice-sh.op/public/images/padding/56px.png' + + verify.accessControlChallenges()(req, res, next) + + expect(challenges.tokenSaleChallenge.solved).to.equal(true) + }) + + it('"extraLanguageChallenge" is solved when the Klingon translation file is requested', () => { + challenges.extraLanguageChallenge = { solved: false, save } + req.url = 'http://juice-sh.op/public/i18n/tlh_AA.json' + + verify.accessControlChallenges()(req, res, next) + + expect(challenges.extraLanguageChallenge.solved).to.equal(true) + }) + + it('"retrieveBlueprintChallenge" is solved when the blueprint file is requested', () => { + challenges.retrieveBlueprintChallenge = { solved: false, save } + cache.retrieveBlueprintChallengeFile = 'test.dxf' + req.url = 'http://juice-sh.op/public/images/products/test.dxf' + + verify.accessControlChallenges()(req, res, next) + + expect(challenges.retrieveBlueprintChallenge.solved).to.equal(true) + }) + + it('"missingEncodingChallenge" is solved when the crazy cat photo is requested', () => { + challenges.missingEncodingChallenge = { solved: false, save } + req.url = 'http://juice-sh.op/public/images/uploads/%F0%9F%98%BC-%23zatschi-%23whoneedsfourlegs-1572600969477.jpg' + + verify.accessControlChallenges()(req, res, next) + + expect(challenges.missingEncodingChallenge.solved).to.equal(true) + }) + + it('"accessLogDisclosureChallenge" is solved when any server access log file is requested', () => { + challenges.accessLogDisclosureChallenge = { solved: false, save } + req.url = 'http://juice-sh.op/support/logs/access.log.2019-01-15' + + verify.accessControlChallenges()(req, res, next) + + expect(challenges.accessLogDisclosureChallenge.solved).to.equal(true) + }) + }) + + describe('"errorHandlingChallenge"', () => { + beforeEach(() => { + challenges.errorHandlingChallenge = { solved: false, save } + }) + + it('is solved when an error occurs on a response with OK 200 status code', () => { + res.statusCode = 200 + err = new Error() + + verify.errorHandlingChallenge()(err, req, res, next) + + expect(challenges.errorHandlingChallenge.solved).to.equal(true) + }) + + describe('is solved when an error occurs on a response with error', () => { + const httpStatus = [402, 403, 404, 500] + httpStatus.forEach(statusCode => { + it(`${statusCode} status code`, () => { + res.statusCode = statusCode + err = new Error() + + verify.errorHandlingChallenge()(err, req, res, next) + + expect(challenges.errorHandlingChallenge.solved).to.equal(true) + }) + }) + }) + + it('is not solved when no error occurs on a response with OK 200 status code', () => { + res.statusCode = 200 + err = undefined + + verify.errorHandlingChallenge()(err, req, res, next) + + expect(challenges.errorHandlingChallenge.solved).to.equal(false) + }) + + describe('is not solved when no error occurs on a response with error', () => { + const httpStatus = [401, 402, 404, 500] + httpStatus.forEach(statusCode => { + it(`${statusCode} status code`, () => { + res.statusCode = statusCode + err = undefined + + verify.errorHandlingChallenge()(err, req, res, next) + + expect(challenges.errorHandlingChallenge.solved).to.equal(false) + }) + }) + }) + + it('should pass occured error on to next route', () => { + res.statusCode = 500 + err = new Error() + + verify.errorHandlingChallenge()(err, req, res, next) + + expect(next).to.have.been.calledWith(err) + }) + }) + + describe('databaseRelatedChallenges', () => { + describe('"changeProductChallenge"', () => { + const products = require('../../data/datacache').products + + beforeEach(() => { + challenges.changeProductChallenge = { solved: false, save } + products.osaft = { reload () { return { then (cb: any) { cb() } } } } + }) + + it(`is solved when the link in the O-Saft product goes to ${config.get('challenges.overwriteUrlForProductTamperingChallenge')}`, () => { + products.osaft.description = `O-Saft, yeah! More...` + + verify.databaseRelatedChallenges()(req, res, next) + + expect(challenges.changeProductChallenge.solved).to.equal(true) + }) + + it('is not solved when the link in the O-Saft product is changed to an arbitrary URL', () => { + products.osaft.description = 'O-Saft, nooo! More...' + + verify.databaseRelatedChallenges()(req, res, next) + + expect(challenges.changeProductChallenge.solved).to.equal(false) + }) + + it('is not solved when the link in the O-Saft product remained unchanged', () => { + let urlForProductTamperingChallenge = null + for (const product of config.get('products')) { + if (product.urlForProductTamperingChallenge !== undefined) { + urlForProductTamperingChallenge = product.urlForProductTamperingChallenge + break + } + } + products.osaft.description = `Vanilla O-Saft! More...` + + verify.databaseRelatedChallenges()(req, res, next) + + expect(challenges.changeProductChallenge.solved).to.equal(false) + }) + }) + }) + + describe('jwtChallenges', () => { + beforeEach(() => { + challenges.jwtUnsignedChallenge = { solved: false, save } + challenges.jwtForgedChallenge = { solved: false, save } + }) + + it('"jwtUnsignedChallenge" is solved when forged unsigned token has email jwtn3d@juice-sh.op in the payload', () => { + /* + Header: { "alg": "none", "typ": "JWT" } + Payload: { "data": { "email": "jwtn3d@juice-sh.op" }, "iat": 1508639612, "exp": 9999999999 } + */ + req.headers = { authorization: 'Bearer eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJkYXRhIjp7ImVtYWlsIjoiand0bjNkQGp1aWNlLXNoLm9wIn0sImlhdCI6MTUwODYzOTYxMiwiZXhwIjo5OTk5OTk5OTk5fQ.' } + + verify.jwtChallenges()(req, res, next) + + expect(challenges.jwtUnsignedChallenge.solved).to.equal(true) + }) + + it('"jwtUnsignedChallenge" is solved when forged unsigned token has string "jwtn3d@" in the payload', () => { + /* + Header: { "alg": "none", "typ": "JWT" } + Payload: { "data": { "email": "jwtn3d@" }, "iat": 1508639612, "exp": 9999999999 } + */ + req.headers = { authorization: 'Bearer eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJkYXRhIjp7ImVtYWlsIjoiand0bjNkQCJ9LCJpYXQiOjE1MDg2Mzk2MTIsImV4cCI6OTk5OTk5OTk5OX0.' } + + verify.jwtChallenges()(req, res, next) + + expect(challenges.jwtUnsignedChallenge.solved).to.equal(true) + }) + + it('"jwtUnsignedChallenge" is not solved via regularly signed token even with email jwtn3d@juice-sh.op in the payload', () => { + const token = security.authorize({ data: { email: 'jwtn3d@juice-sh.op' } }) + req.headers = { authorization: `Bearer ${token}` } + + verify.jwtChallenges()(req, res, next) + + expect(challenges.jwtForgedChallenge.solved).to.equal(false) + }) + + if (utils.isChallengeEnabled(challenges.jwtForgedChallenge)) { + it('"jwtForgedChallenge" is solved when forged token HMAC-signed with public RSA-key has email rsa_lord@juice-sh.op in the payload', () => { + /* + Header: { "alg": "HS256", "typ": "JWT" } + Payload: { "data": { "email": "rsa_lord@juice-sh.op" }, "iat": 1508639612, "exp": 9999999999 } + */ + req.headers = { authorization: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7ImVtYWlsIjoicnNhX2xvcmRAanVpY2Utc2gub3AifSwiaWF0IjoxNTgyMjIxNTc1fQ.ycFwtqh4ht4Pq9K5rhiPPY256F9YCTIecd4FHFuSEAg' } + + verify.jwtChallenges()(req, res, next) + + expect(challenges.jwtForgedChallenge.solved).to.equal(true) + }) + + it('"jwtForgedChallenge" is solved when forged token HMAC-signed with public RSA-key has string "rsa_lord@" in the payload', () => { + /* + Header: { "alg": "HS256", "typ": "JWT" } + Payload: { "data": { "email": "rsa_lord@" }, "iat": 1508639612, "exp": 9999999999 } + */ + req.headers = { authorization: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7ImVtYWlsIjoicnNhX2xvcmRAIn0sImlhdCI6MTU4MjIyMTY3NX0.50f6VAIQk2Uzpf3sgH-1JVrrTuwudonm2DKn2ec7Tg8' } + + verify.jwtChallenges()(req, res, next) + + expect(challenges.jwtForgedChallenge.solved).to.equal(true) + }) + + it('"jwtForgedChallenge" is not solved when token regularly signed with private RSA-key has email rsa_lord@juice-sh.op in the payload', () => { + const token = security.authorize({ data: { email: 'rsa_lord@juice-sh.op' } }) + req.headers = { authorization: `Bearer ${token}` } + + verify.jwtChallenges()(req, res, next) + + expect(challenges.jwtForgedChallenge.solved).to.equal(false) + }) + } + }) +}) diff --git a/test/server/webhookSpec.ts b/test/server/webhookSpec.ts index 308dd10d..83c3799e 100644 --- a/test/server/webhookSpec.ts +++ b/test/server/webhookSpec.ts @@ -1,32 +1,32 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -import * as webhook from '../../lib/webhook' -import chai = require('chai') -const expect = chai.expect -const chaiAsPromised = require('chai-as-promised') -chai.use(chaiAsPromised) - -describe('webhook', () => { - const challenge = { - key: 'key', - name: 'name', - difficulty: 1 - } - - describe('notify', () => { - it('fails when no webhook URL is provided via environment variable', () => { - void expect(webhook.notify(challenge)).to.eventually.throw('options.uri is a required argument') - }) - - it('fails when supplied webhook is not a valid URL', () => { - void expect(webhook.notify(challenge, 0, 'localhorst')).to.eventually.throw('Invalid URI "localhorst"') - }) - - it('submits POST with payload to existing URL', () => { - void expect(webhook.notify(challenge, 0, 'https://enlm7zwniuyah.x.pipedream.net/')).to.eventually.not.throw() - }) - }) -}) +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +import * as webhook from '../../lib/webhook' +import chai = require('chai') +const expect = chai.expect +const chaiAsPromised = require('chai-as-promised') +chai.use(chaiAsPromised) + +describe('webhook', () => { + const challenge = { + key: 'key', + name: 'name', + difficulty: 1 + } + + describe('notify', () => { + it('fails when no webhook URL is provided via environment variable', () => { + void expect(webhook.notify(challenge)).to.eventually.throw('options.uri is a required argument') + }) + + it('fails when supplied webhook is not a valid URL', () => { + void expect(webhook.notify(challenge, 0, 'localhorst')).to.eventually.throw('Invalid URI "localhorst"') + }) + + it('submits POST with payload to existing URL', () => { + void expect(webhook.notify(challenge, 0, 'https://enlm7zwniuyah.x.pipedream.net/')).to.eventually.not.throw() + }) + }) +}) diff --git a/test/smoke/Dockerfile b/test/smoke/Dockerfile index 20df9ef0..db95160b 100644 --- a/test/smoke/Dockerfile +++ b/test/smoke/Dockerfile @@ -1,7 +1,7 @@ -FROM alpine - -RUN apk add curl - -COPY smoke-test.sh smoke-test.sh - +FROM alpine + +RUN apk add curl + +COPY smoke-test.sh smoke-test.sh + CMD ["sh", "smoke-test.sh", "http://app:3000"] \ No newline at end of file diff --git a/test/smoke/smoke-test.sh b/test/smoke/smoke-test.sh index 5bb16941..bef88bda 100644 --- a/test/smoke/smoke-test.sh +++ b/test/smoke/smoke-test.sh @@ -1,54 +1,54 @@ -#!/bin/sh - -# -# Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. -# SPDX-License-Identifier: MIT -# - -printf "Waiting 20sec for %s to launch" "$1" -sleep 5 -printf "....." -sleep 5 -printf "....." -sleep 5 -printf "....." -sleep 5 -printf ".....\n" -printf "Running smoke tests...\n" - -EXIT=0 -if curl "$1" -s | grep -q ''; then - printf "\033[0;32mIndex smoke test passed!\033[0m\n" -else - printf "\033[0;31mIndex smoke test failed!\033[0m\n" - EXIT=$((EXIT+1)) -fi - -if curl "$1/api/Challenges" -s | grep -q '"status":"success"'; then - printf "\033[0;32mAPI smoke test passed!\033[0m\n" -else - printf "\033[0;31mAPI smoke test failed!\033[0m\n" - EXIT=$((EXIT+1)) -fi - -if curl "$1/main.js" -s | grep -q 'this.applicationName="OWASP Juice Shop"'; then - printf "\033[0;32mAngular smoke test passed!\033[0m\n" -else - printf "\033[0;31mAngular smoke test failed!\033[0m\n" - EXIT=$((EXIT+1)) -fi - -if curl "$1/snippets/directoryListingChallenge" -s | grep -q 'serveIndexMiddleware'; then - printf "\033[0;32mCode snippet smoke test passed!\033[0m\n" -else - printf "\033[0;31mCode snippet smoke test failed!\033[0m\n" - EXIT=$((EXIT+1)) -fi - -printf "Smoke tests exiting with code %s (" "$EXIT" -if [ $EXIT -gt 0 ]; then - printf "\033[0;31mFAILED\033[0m)\n" -else - printf "\033[0;32mSUCCESS\033[0m)\n" -fi -exit $EXIT +#!/bin/sh + +# +# Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. +# SPDX-License-Identifier: MIT +# + +printf "Waiting 20sec for %s to launch" "$1" +sleep 5 +printf "....." +sleep 5 +printf "....." +sleep 5 +printf "....." +sleep 5 +printf ".....\n" +printf "Running smoke tests...\n" + +EXIT=0 +if curl "$1" -s | grep -q ''; then + printf "\033[0;32mIndex smoke test passed!\033[0m\n" +else + printf "\033[0;31mIndex smoke test failed!\033[0m\n" + EXIT=$((EXIT+1)) +fi + +if curl "$1/api/Challenges" -s | grep -q '"status":"success"'; then + printf "\033[0;32mAPI smoke test passed!\033[0m\n" +else + printf "\033[0;31mAPI smoke test failed!\033[0m\n" + EXIT=$((EXIT+1)) +fi + +if curl "$1/main.js" -s | grep -q 'this.applicationName="OWASP Juice Shop"'; then + printf "\033[0;32mAngular smoke test passed!\033[0m\n" +else + printf "\033[0;31mAngular smoke test failed!\033[0m\n" + EXIT=$((EXIT+1)) +fi + +if curl "$1/snippets/directoryListingChallenge" -s | grep -q 'serveIndexMiddleware'; then + printf "\033[0;32mCode snippet smoke test passed!\033[0m\n" +else + printf "\033[0;31mCode snippet smoke test failed!\033[0m\n" + EXIT=$((EXIT+1)) +fi + +printf "Smoke tests exiting with code %s (" "$EXIT" +if [ $EXIT -gt 0 ]; then + printf "\033[0;31mFAILED\033[0m)\n" +else + printf "\033[0;32mSUCCESS\033[0m)\n" +fi +exit $EXIT diff --git a/threat-model.json b/threat-model.json index ad3b0dab..00d883e6 100644 --- a/threat-model.json +++ b/threat-model.json @@ -1,1070 +1,1070 @@ -{ - "summary": { - "title": "OWASP Juice Shop", - "owner": "Björn Kimminich", - "description": "OWASP Juice Shop is probably the most modern and sophisticated insecure web application! It can be used in security trainings, awareness demos, CTFs and as a guinea pig for security tools! Juice Shop encompasses vulnerabilities from the entire OWASP Top Ten along with many other security flaws found in real-world applications!" - }, - "detail": { - "contributors": [], - "diagrams": [ - { - "title": "High Level Data Flow", - "thumbnail": "./public/content/images/thumbnail.stride.jpg", - "diagramType": "STRIDE", - "id": 0, - "$$hashKey": "object:59", - "diagramJson": { - "cells": [ - { - "type": "tm.Actor", - "size": { - "width": 160, - "height": 80 - }, - "position": { - "x": 64, - "y": 173 - }, - "angle": 0, - "id": "5c682ec9-c352-442e-b61c-2de8ed53ea22", - "z": 1, - "hasOpenThreats": false, - "attrs": { - ".element-shape": { - "class": "element-shape hasNoOpenThreats isInScope" - }, - "text": { - "text": "B2C Customer (Browser)" - }, - ".element-text": { - "class": "element-text hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Actor", - "size": { - "width": 160, - "height": 80 - }, - "position": { - "x": 68, - "y": 52 - }, - "angle": 0, - "id": "d02fa030-ca19-47ad-8920-0980cd87a351", - "z": 2, - "hasOpenThreats": false, - "outOfScope": true, - "attrs": { - ".element-shape": { - "class": "element-shape hasNoOpenThreats isOutOfScope" - }, - "text": { - "text": "Google" - }, - ".element-text": { - "class": "element-text hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Process", - "size": { - "width": 100, - "height": 100 - }, - "position": { - "x": 455, - "y": 1 - }, - "angle": 0, - "id": "064304c2-9672-44f2-9e08-982d58145bc0", - "z": 3, - "hasOpenThreats": false, - "attrs": { - ".element-shape": { - "class": "element-shape hasNoOpenThreats isInScope" - }, - "text": { - "text": "Angular\nFrontend" - }, - ".element-text": { - "class": "element-text hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Process", - "size": { - "width": 100, - "height": 100 - }, - "position": { - "x": 468, - "y": 228 - }, - "angle": 0, - "id": "edced7d1-6206-43bc-94ab-aa515977042a", - "z": 4, - "hasOpenThreats": false, - "description": "Node.js / Express", - "attrs": { - ".element-shape": { - "class": "element-shape hasNoOpenThreats isInScope" - }, - "text": { - "text": "Application\nServer" - }, - ".element-text": { - "class": "element-text hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Store", - "size": { - "width": 160, - "height": 80 - }, - "position": { - "x": 830, - "y": 393 - }, - "angle": 0, - "id": "673196a0-0797-4c56-974b-b169ec27accb", - "z": 5, - "hasOpenThreats": false, - "description": "", - "attrs": { - ".element-shape": { - "class": "element-shape hasNoOpenThreats isInScope" - }, - "text": { - "text": "SQLite Database" - }, - ".element-text": { - "class": "element-text hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Store", - "size": { - "width": 160, - "height": 80 - }, - "position": { - "x": 568, - "y": 396 - }, - "angle": 0, - "id": "38c5137f-1570-446a-9978-a98f84fe1c59", - "z": 6, - "hasOpenThreats": false, - "attrs": { - ".element-shape": { - "class": "element-shape hasNoOpenThreats isInScope" - }, - "text": { - "text": "MarsDB NoSQL DB" - }, - ".element-text": { - "class": "element-text hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Store", - "size": { - "width": 160, - "height": 80 - }, - "position": { - "x": 828, - "y": 255 - }, - "angle": 0, - "id": "00ae7380-5510-4772-8f98-d83df41035b6", - "z": 7, - "hasOpenThreats": false, - "attrs": { - ".element-shape": { - "class": "element-shape hasNoOpenThreats isInScope" - }, - "text": { - "text": "Local File System" - }, - ".element-text": { - "class": "element-text hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "5c682ec9-c352-442e-b61c-2de8ed53ea22" - }, - "target": { - "id": "064304c2-9672-44f2-9e08-982d58145bc0" - }, - "vertices": [ - { - "x": 355, - "y": 146 - } - ], - "id": "cb17d350-86bc-4f06-8858-668093987b57", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 8, - "hasOpenThreats": false, - "isPublicNetwork": true, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "064304c2-9672-44f2-9e08-982d58145bc0" - }, - "target": { - "id": "d02fa030-ca19-47ad-8920-0980cd87a351" - }, - "vertices": [ - { - "x": 337, - "y": 35 - } - ], - "id": "2d66f056-75e8-4436-bc99-a0817b3f1c19", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "OAuth2", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 9, - "hasOpenThreats": false, - "isPublicNetwork": true, - "isEncrypted": true, - "protocol": "", - "outOfScope": true, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isOutOfScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "064304c2-9672-44f2-9e08-982d58145bc0" - }, - "target": { - "id": "edced7d1-6206-43bc-94ab-aa515977042a" - }, - "vertices": [ - { - "x": 419, - "y": 204 - } - ], - "id": "46d76eab-2862-414b-bce6-c0d8fe79cf79", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "API Requests", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 10, - "hasOpenThreats": false, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "edced7d1-6206-43bc-94ab-aa515977042a" - }, - "target": { - "id": "064304c2-9672-44f2-9e08-982d58145bc0" - }, - "vertices": [ - { - "x": 514, - "y": 150 - } - ], - "id": "dc9ff0b8-2bae-4839-97f1-181f47282846", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "API Responses", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 11, - "hasOpenThreats": false, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "edced7d1-6206-43bc-94ab-aa515977042a" - }, - "target": { - "id": "00ae7380-5510-4772-8f98-d83df41035b6" - }, - "vertices": [ - { - "x": 683, - "y": 236 - } - ], - "id": "028ce073-348f-498d-ab6e-7d98e4d7ae77", - "labels": [ - { - "position": { - "distance": 0.4545744602063211, - "offset": -14.064892638757218 - }, - "attrs": { - "text": { - "text": "Invoices", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 12, - "hasOpenThreats": false, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Actor", - "size": { - "width": 160, - "height": 80 - }, - "position": { - "x": 66, - "y": 296 - }, - "angle": 0, - "id": "82095edc-bdca-448b-8c28-ed1aaba2e9e9", - "z": 13, - "hasOpenThreats": false, - "attrs": { - ".element-shape": { - "class": "element-shape hasNoOpenThreats isInScope" - }, - "text": { - "text": "B2B Customer (Browser)" - }, - ".element-text": { - "class": "element-text hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Process", - "size": { - "width": 100, - "height": 100 - }, - "position": { - "x": 307, - "y": 338 - }, - "angle": 0, - "id": "2f427832-3419-4b43-ae77-338f8636ca2b", - "z": 14, - "hasOpenThreats": false, - "attrs": { - ".element-shape": { - "class": "element-shape hasNoOpenThreats isInScope" - }, - "text": { - "text": "B2B API" - }, - ".element-text": { - "class": "element-text hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "82095edc-bdca-448b-8c28-ed1aaba2e9e9" - }, - "target": { - "id": "2f427832-3419-4b43-ae77-338f8636ca2b" - }, - "vertices": [], - "id": "f9d73d1a-e79a-4a57-bba8-c7cbc02fa348", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 15, - "hasOpenThreats": false, - "isPublicNetwork": true, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "2f427832-3419-4b43-ae77-338f8636ca2b" - }, - "target": { - "id": "edced7d1-6206-43bc-94ab-aa515977042a" - }, - "vertices": [], - "id": "1515ba33-e41b-4940-b92c-139179c14709", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "Orders", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 16, - "hasOpenThreats": false, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Actor", - "size": { - "width": 160, - "height": 80 - }, - "position": { - "x": 844, - "y": 1 - }, - "angle": 0, - "id": "0191343a-8439-45d7-b9e4-6b052f91415d", - "z": 17, - "hasOpenThreats": false, - "attrs": { - ".element-shape": { - "class": "element-shape hasNoOpenThreats isInScope" - }, - "text": { - "text": "Admin (Browser)" - }, - ".element-text": { - "class": "element-text hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Actor", - "size": { - "width": 160, - "height": 80 - }, - "position": { - "x": 847, - "y": 107 - }, - "angle": 0, - "id": "12bf3793-217c-4863-b430-718182257f1a", - "z": 18, - "hasOpenThreats": false, - "attrs": { - ".element-shape": { - "class": "element-shape hasNoOpenThreats isInScope" - }, - "text": { - "text": "Accounting (Browser)" - }, - ".element-text": { - "class": "element-text hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "12bf3793-217c-4863-b430-718182257f1a" - }, - "target": { - "id": "064304c2-9672-44f2-9e08-982d58145bc0" - }, - "vertices": [], - "id": "16ed975a-3375-47b2-ab23-dac55835961c", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "Product Inventory", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 19, - "hasOpenThreats": false, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "0191343a-8439-45d7-b9e4-6b052f91415d" - }, - "target": { - "id": "064304c2-9672-44f2-9e08-982d58145bc0" - }, - "vertices": [ - { - "x": 679, - "y": 18 - } - ], - "id": "8a3a017a-76c0-45fa-9d39-c31311f8b76f", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "User Management", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 20, - "hasOpenThreats": false, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "edced7d1-6206-43bc-94ab-aa515977042a" - }, - "target": { - "id": "673196a0-0797-4c56-974b-b169ec27accb" - }, - "vertices": [], - "id": "063a0a1a-352e-45bb-bce9-abee2be89a0d", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "all other data", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 21, - "hasOpenThreats": false, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "edced7d1-6206-43bc-94ab-aa515977042a" - }, - "target": { - "id": "38c5137f-1570-446a-9978-a98f84fe1c59" - }, - "vertices": [ - { - "x": 509, - "y": 385 - } - ], - "id": "96dee941-1600-445f-b12f-88fbb0776c16", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "Orders", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 22, - "hasOpenThreats": false, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "edced7d1-6206-43bc-94ab-aa515977042a" - }, - "target": { - "id": "38c5137f-1570-446a-9978-a98f84fe1c59" - }, - "vertices": [ - { - "x": 565, - "y": 378 - } - ], - "id": "5581ae64-5e43-4525-94e0-e020793e4136", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "Reviews", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 23, - "hasOpenThreats": false, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "edced7d1-6206-43bc-94ab-aa515977042a" - }, - "target": { - "id": "5c682ec9-c352-442e-b61c-2de8ed53ea22" - }, - "vertices": [], - "id": "e9a8981a-2243-4e43-a68b-0bdfd81f1a45", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "Invoices", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 24, - "hasOpenThreats": false, - "isPublicNetwork": true, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Boundary", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "x": 93, - "y": 19 - }, - "target": { - "x": 65, - "y": 146 - }, - "vertices": [ - { - "x": 252, - "y": 54 - }, - { - "x": 246, - "y": 143 - } - ], - "id": "e4006eb6-c6da-4056-8cad-6111ffed690a", - "z": 25, - "attrs": {} - }, - { - "type": "tm.Boundary", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "x": 183, - "y": 441 - }, - "target": { - "x": 286, - "y": 124 - }, - "vertices": [ - { - "x": 310, - "y": 320 - } - ], - "id": "a0bc0999-c102-4390-9c74-355bfea405be", - "z": 26, - "attrs": {} - }, - { - "type": "tm.Boundary", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "x": 772, - "y": 161 - }, - "target": { - "x": 784, - "y": 1 - }, - "vertices": [ - { - "x": 787, - "y": 90 - } - ], - "id": "b66d28e9-c542-452b-944c-6ea0b95d7421", - "z": 27, - "attrs": {} - }, - { - "type": "tm.Boundary", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "x": 417, - "y": 128 - }, - "target": { - "x": 616, - "y": 156 - }, - "vertices": [], - "id": "140276bc-f5b6-4199-ac4d-ea1f473c132a", - "z": 28, - "attrs": {} - }, - { - "type": "tm.Boundary", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "x": 749, - "y": 492 - }, - "target": { - "x": 753, - "y": 198 - }, - "vertices": [ - { - "x": 775, - "y": 346 - } - ], - "id": "161f7ef7-4adf-40e3-81c5-f15979ac1b5c", - "z": 29, - "attrs": {} - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "00ae7380-5510-4772-8f98-d83df41035b6" - }, - "target": { - "id": "edced7d1-6206-43bc-94ab-aa515977042a" - }, - "vertices": [ - { - "x": 663, - "y": 260 - } - ], - "id": "53b58d93-f3af-4668-989c-c15ce69268e6", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "Configuration", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 30, - "hasOpenThreats": false, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - }, - { - "type": "tm.Flow", - "size": { - "width": 10, - "height": 10 - }, - "smooth": true, - "source": { - "id": "edced7d1-6206-43bc-94ab-aa515977042a" - }, - "target": { - "id": "00ae7380-5510-4772-8f98-d83df41035b6" - }, - "vertices": [ - { - "x": 737, - "y": 306 - } - ], - "id": "8eae4755-841b-44b2-8826-bd231926a480", - "labels": [ - { - "position": 0.5, - "attrs": { - "text": { - "text": "Logging", - "font-weight": "400", - "font-size": "small" - } - } - } - ], - "z": 31, - "hasOpenThreats": false, - "attrs": { - ".marker-target": { - "class": "marker-target hasNoOpenThreats isInScope" - }, - ".connection": { - "class": "connection hasNoOpenThreats isInScope" - } - } - } - ] - }, - "size": { - "height": 590, - "width": 1425 - } - } - ] - } +{ + "summary": { + "title": "OWASP Juice Shop", + "owner": "Björn Kimminich", + "description": "OWASP Juice Shop is probably the most modern and sophisticated insecure web application! It can be used in security trainings, awareness demos, CTFs and as a guinea pig for security tools! Juice Shop encompasses vulnerabilities from the entire OWASP Top Ten along with many other security flaws found in real-world applications!" + }, + "detail": { + "contributors": [], + "diagrams": [ + { + "title": "High Level Data Flow", + "thumbnail": "./public/content/images/thumbnail.stride.jpg", + "diagramType": "STRIDE", + "id": 0, + "$$hashKey": "object:59", + "diagramJson": { + "cells": [ + { + "type": "tm.Actor", + "size": { + "width": 160, + "height": 80 + }, + "position": { + "x": 64, + "y": 173 + }, + "angle": 0, + "id": "5c682ec9-c352-442e-b61c-2de8ed53ea22", + "z": 1, + "hasOpenThreats": false, + "attrs": { + ".element-shape": { + "class": "element-shape hasNoOpenThreats isInScope" + }, + "text": { + "text": "B2C Customer (Browser)" + }, + ".element-text": { + "class": "element-text hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Actor", + "size": { + "width": 160, + "height": 80 + }, + "position": { + "x": 68, + "y": 52 + }, + "angle": 0, + "id": "d02fa030-ca19-47ad-8920-0980cd87a351", + "z": 2, + "hasOpenThreats": false, + "outOfScope": true, + "attrs": { + ".element-shape": { + "class": "element-shape hasNoOpenThreats isOutOfScope" + }, + "text": { + "text": "Google" + }, + ".element-text": { + "class": "element-text hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Process", + "size": { + "width": 100, + "height": 100 + }, + "position": { + "x": 455, + "y": 1 + }, + "angle": 0, + "id": "064304c2-9672-44f2-9e08-982d58145bc0", + "z": 3, + "hasOpenThreats": false, + "attrs": { + ".element-shape": { + "class": "element-shape hasNoOpenThreats isInScope" + }, + "text": { + "text": "Angular\nFrontend" + }, + ".element-text": { + "class": "element-text hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Process", + "size": { + "width": 100, + "height": 100 + }, + "position": { + "x": 468, + "y": 228 + }, + "angle": 0, + "id": "edced7d1-6206-43bc-94ab-aa515977042a", + "z": 4, + "hasOpenThreats": false, + "description": "Node.js / Express", + "attrs": { + ".element-shape": { + "class": "element-shape hasNoOpenThreats isInScope" + }, + "text": { + "text": "Application\nServer" + }, + ".element-text": { + "class": "element-text hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Store", + "size": { + "width": 160, + "height": 80 + }, + "position": { + "x": 830, + "y": 393 + }, + "angle": 0, + "id": "673196a0-0797-4c56-974b-b169ec27accb", + "z": 5, + "hasOpenThreats": false, + "description": "", + "attrs": { + ".element-shape": { + "class": "element-shape hasNoOpenThreats isInScope" + }, + "text": { + "text": "SQLite Database" + }, + ".element-text": { + "class": "element-text hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Store", + "size": { + "width": 160, + "height": 80 + }, + "position": { + "x": 568, + "y": 396 + }, + "angle": 0, + "id": "38c5137f-1570-446a-9978-a98f84fe1c59", + "z": 6, + "hasOpenThreats": false, + "attrs": { + ".element-shape": { + "class": "element-shape hasNoOpenThreats isInScope" + }, + "text": { + "text": "MarsDB NoSQL DB" + }, + ".element-text": { + "class": "element-text hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Store", + "size": { + "width": 160, + "height": 80 + }, + "position": { + "x": 828, + "y": 255 + }, + "angle": 0, + "id": "00ae7380-5510-4772-8f98-d83df41035b6", + "z": 7, + "hasOpenThreats": false, + "attrs": { + ".element-shape": { + "class": "element-shape hasNoOpenThreats isInScope" + }, + "text": { + "text": "Local File System" + }, + ".element-text": { + "class": "element-text hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "5c682ec9-c352-442e-b61c-2de8ed53ea22" + }, + "target": { + "id": "064304c2-9672-44f2-9e08-982d58145bc0" + }, + "vertices": [ + { + "x": 355, + "y": 146 + } + ], + "id": "cb17d350-86bc-4f06-8858-668093987b57", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 8, + "hasOpenThreats": false, + "isPublicNetwork": true, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "064304c2-9672-44f2-9e08-982d58145bc0" + }, + "target": { + "id": "d02fa030-ca19-47ad-8920-0980cd87a351" + }, + "vertices": [ + { + "x": 337, + "y": 35 + } + ], + "id": "2d66f056-75e8-4436-bc99-a0817b3f1c19", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "OAuth2", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 9, + "hasOpenThreats": false, + "isPublicNetwork": true, + "isEncrypted": true, + "protocol": "", + "outOfScope": true, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isOutOfScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "064304c2-9672-44f2-9e08-982d58145bc0" + }, + "target": { + "id": "edced7d1-6206-43bc-94ab-aa515977042a" + }, + "vertices": [ + { + "x": 419, + "y": 204 + } + ], + "id": "46d76eab-2862-414b-bce6-c0d8fe79cf79", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "API Requests", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 10, + "hasOpenThreats": false, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "edced7d1-6206-43bc-94ab-aa515977042a" + }, + "target": { + "id": "064304c2-9672-44f2-9e08-982d58145bc0" + }, + "vertices": [ + { + "x": 514, + "y": 150 + } + ], + "id": "dc9ff0b8-2bae-4839-97f1-181f47282846", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "API Responses", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 11, + "hasOpenThreats": false, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "edced7d1-6206-43bc-94ab-aa515977042a" + }, + "target": { + "id": "00ae7380-5510-4772-8f98-d83df41035b6" + }, + "vertices": [ + { + "x": 683, + "y": 236 + } + ], + "id": "028ce073-348f-498d-ab6e-7d98e4d7ae77", + "labels": [ + { + "position": { + "distance": 0.4545744602063211, + "offset": -14.064892638757218 + }, + "attrs": { + "text": { + "text": "Invoices", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 12, + "hasOpenThreats": false, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Actor", + "size": { + "width": 160, + "height": 80 + }, + "position": { + "x": 66, + "y": 296 + }, + "angle": 0, + "id": "82095edc-bdca-448b-8c28-ed1aaba2e9e9", + "z": 13, + "hasOpenThreats": false, + "attrs": { + ".element-shape": { + "class": "element-shape hasNoOpenThreats isInScope" + }, + "text": { + "text": "B2B Customer (Browser)" + }, + ".element-text": { + "class": "element-text hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Process", + "size": { + "width": 100, + "height": 100 + }, + "position": { + "x": 307, + "y": 338 + }, + "angle": 0, + "id": "2f427832-3419-4b43-ae77-338f8636ca2b", + "z": 14, + "hasOpenThreats": false, + "attrs": { + ".element-shape": { + "class": "element-shape hasNoOpenThreats isInScope" + }, + "text": { + "text": "B2B API" + }, + ".element-text": { + "class": "element-text hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "82095edc-bdca-448b-8c28-ed1aaba2e9e9" + }, + "target": { + "id": "2f427832-3419-4b43-ae77-338f8636ca2b" + }, + "vertices": [], + "id": "f9d73d1a-e79a-4a57-bba8-c7cbc02fa348", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 15, + "hasOpenThreats": false, + "isPublicNetwork": true, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "2f427832-3419-4b43-ae77-338f8636ca2b" + }, + "target": { + "id": "edced7d1-6206-43bc-94ab-aa515977042a" + }, + "vertices": [], + "id": "1515ba33-e41b-4940-b92c-139179c14709", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "Orders", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 16, + "hasOpenThreats": false, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Actor", + "size": { + "width": 160, + "height": 80 + }, + "position": { + "x": 844, + "y": 1 + }, + "angle": 0, + "id": "0191343a-8439-45d7-b9e4-6b052f91415d", + "z": 17, + "hasOpenThreats": false, + "attrs": { + ".element-shape": { + "class": "element-shape hasNoOpenThreats isInScope" + }, + "text": { + "text": "Admin (Browser)" + }, + ".element-text": { + "class": "element-text hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Actor", + "size": { + "width": 160, + "height": 80 + }, + "position": { + "x": 847, + "y": 107 + }, + "angle": 0, + "id": "12bf3793-217c-4863-b430-718182257f1a", + "z": 18, + "hasOpenThreats": false, + "attrs": { + ".element-shape": { + "class": "element-shape hasNoOpenThreats isInScope" + }, + "text": { + "text": "Accounting (Browser)" + }, + ".element-text": { + "class": "element-text hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "12bf3793-217c-4863-b430-718182257f1a" + }, + "target": { + "id": "064304c2-9672-44f2-9e08-982d58145bc0" + }, + "vertices": [], + "id": "16ed975a-3375-47b2-ab23-dac55835961c", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "Product Inventory", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 19, + "hasOpenThreats": false, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "0191343a-8439-45d7-b9e4-6b052f91415d" + }, + "target": { + "id": "064304c2-9672-44f2-9e08-982d58145bc0" + }, + "vertices": [ + { + "x": 679, + "y": 18 + } + ], + "id": "8a3a017a-76c0-45fa-9d39-c31311f8b76f", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "User Management", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 20, + "hasOpenThreats": false, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "edced7d1-6206-43bc-94ab-aa515977042a" + }, + "target": { + "id": "673196a0-0797-4c56-974b-b169ec27accb" + }, + "vertices": [], + "id": "063a0a1a-352e-45bb-bce9-abee2be89a0d", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "all other data", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 21, + "hasOpenThreats": false, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "edced7d1-6206-43bc-94ab-aa515977042a" + }, + "target": { + "id": "38c5137f-1570-446a-9978-a98f84fe1c59" + }, + "vertices": [ + { + "x": 509, + "y": 385 + } + ], + "id": "96dee941-1600-445f-b12f-88fbb0776c16", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "Orders", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 22, + "hasOpenThreats": false, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "edced7d1-6206-43bc-94ab-aa515977042a" + }, + "target": { + "id": "38c5137f-1570-446a-9978-a98f84fe1c59" + }, + "vertices": [ + { + "x": 565, + "y": 378 + } + ], + "id": "5581ae64-5e43-4525-94e0-e020793e4136", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "Reviews", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 23, + "hasOpenThreats": false, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "edced7d1-6206-43bc-94ab-aa515977042a" + }, + "target": { + "id": "5c682ec9-c352-442e-b61c-2de8ed53ea22" + }, + "vertices": [], + "id": "e9a8981a-2243-4e43-a68b-0bdfd81f1a45", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "Invoices", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 24, + "hasOpenThreats": false, + "isPublicNetwork": true, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Boundary", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "x": 93, + "y": 19 + }, + "target": { + "x": 65, + "y": 146 + }, + "vertices": [ + { + "x": 252, + "y": 54 + }, + { + "x": 246, + "y": 143 + } + ], + "id": "e4006eb6-c6da-4056-8cad-6111ffed690a", + "z": 25, + "attrs": {} + }, + { + "type": "tm.Boundary", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "x": 183, + "y": 441 + }, + "target": { + "x": 286, + "y": 124 + }, + "vertices": [ + { + "x": 310, + "y": 320 + } + ], + "id": "a0bc0999-c102-4390-9c74-355bfea405be", + "z": 26, + "attrs": {} + }, + { + "type": "tm.Boundary", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "x": 772, + "y": 161 + }, + "target": { + "x": 784, + "y": 1 + }, + "vertices": [ + { + "x": 787, + "y": 90 + } + ], + "id": "b66d28e9-c542-452b-944c-6ea0b95d7421", + "z": 27, + "attrs": {} + }, + { + "type": "tm.Boundary", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "x": 417, + "y": 128 + }, + "target": { + "x": 616, + "y": 156 + }, + "vertices": [], + "id": "140276bc-f5b6-4199-ac4d-ea1f473c132a", + "z": 28, + "attrs": {} + }, + { + "type": "tm.Boundary", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "x": 749, + "y": 492 + }, + "target": { + "x": 753, + "y": 198 + }, + "vertices": [ + { + "x": 775, + "y": 346 + } + ], + "id": "161f7ef7-4adf-40e3-81c5-f15979ac1b5c", + "z": 29, + "attrs": {} + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "00ae7380-5510-4772-8f98-d83df41035b6" + }, + "target": { + "id": "edced7d1-6206-43bc-94ab-aa515977042a" + }, + "vertices": [ + { + "x": 663, + "y": 260 + } + ], + "id": "53b58d93-f3af-4668-989c-c15ce69268e6", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "Configuration", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 30, + "hasOpenThreats": false, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + }, + { + "type": "tm.Flow", + "size": { + "width": 10, + "height": 10 + }, + "smooth": true, + "source": { + "id": "edced7d1-6206-43bc-94ab-aa515977042a" + }, + "target": { + "id": "00ae7380-5510-4772-8f98-d83df41035b6" + }, + "vertices": [ + { + "x": 737, + "y": 306 + } + ], + "id": "8eae4755-841b-44b2-8826-bd231926a480", + "labels": [ + { + "position": 0.5, + "attrs": { + "text": { + "text": "Logging", + "font-weight": "400", + "font-size": "small" + } + } + } + ], + "z": 31, + "hasOpenThreats": false, + "attrs": { + ".marker-target": { + "class": "marker-target hasNoOpenThreats isInScope" + }, + ".connection": { + "class": "connection hasNoOpenThreats isInScope" + } + } + } + ] + }, + "size": { + "height": 590, + "width": 1425 + } + } + ] + } } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 711f2b99..ff29ab2c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,41 +1,41 @@ -{ - "compilerOptions": { - "baseUrl": "./", - "outDir": "./build", - "allowJs": true, - "module": "commonjs", - "target": "es2020", - "moduleResolution": "node", - "sourceMap": true, - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "lib": [ - "es2020", - "dom" - ] - }, - "include" : [ - "cypress/**/*.ts", - "data/**/*.ts", - "lib/**/*.ts", - "lib/**/*.js", - "models/**/*.ts", - "routes/**/*.ts", - "test/**/*.ts", - "views/**/*.ts", - "views/**/*.js", - "rsn/**/*.ts", - "*.ts" - ], - "exclude": [ - "node_modules", - "frontend", - "dist", - "build", - "vagrant", - "**/*.d.ts" - ] -} +{ + "compilerOptions": { + "baseUrl": "./", + "outDir": "./build", + "allowJs": true, + "module": "commonjs", + "target": "es2020", + "moduleResolution": "node", + "sourceMap": true, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "lib": [ + "es2020", + "dom" + ] + }, + "include" : [ + "cypress/**/*.ts", + "data/**/*.ts", + "lib/**/*.ts", + "lib/**/*.js", + "models/**/*.ts", + "routes/**/*.ts", + "test/**/*.ts", + "views/**/*.ts", + "views/**/*.js", + "rsn/**/*.ts", + "*.ts" + ], + "exclude": [ + "node_modules", + "frontend", + "dist", + "build", + "vagrant", + "**/*.d.ts" + ] +} diff --git a/vagrant/Vagrantfile b/vagrant/Vagrantfile index ef4a7ddd..ed4ac459 100644 --- a/vagrant/Vagrantfile +++ b/vagrant/Vagrantfile @@ -1,14 +1,14 @@ -# Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. -# SPDX-License-Identifier: MIT - -# -*- mode: ruby -*- -# vi: set ft=ruby : - -Vagrant.configure("2") do |config| - config.vm.box = "generic/ubuntu2110" - config.vm.hostname = "juice.sh" - - config.vm.network "private_network", ip: "192.168.56.110" - config.vm.provision "file", source: "./default.conf", destination: "/tmp/juice-shop/default.conf" - config.vm.provision :shell, path: "bootstrap.sh" -end +# Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. +# SPDX-License-Identifier: MIT + +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure("2") do |config| + config.vm.box = "generic/ubuntu2110" + config.vm.hostname = "juice.sh" + + config.vm.network "private_network", ip: "192.168.56.110" + config.vm.provision "file", source: "./default.conf", destination: "/tmp/juice-shop/default.conf" + config.vm.provision :shell, path: "bootstrap.sh" +end diff --git a/vagrant/bootstrap.sh b/vagrant/bootstrap.sh index 31401945..4c9aee0f 100755 --- a/vagrant/bootstrap.sh +++ b/vagrant/bootstrap.sh @@ -1,29 +1,29 @@ -#!/bin/sh - -# -# Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. -# SPDX-License-Identifier: MIT -# - -# Exit on error -set -e - -# Add docker key and repository -curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - -sudo bash -c 'echo "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker-ce.list' - - -# Install apache and docker -apt-get update -q -apt-get upgrade -qy -apt-get install -qy apache2 docker-ce - -# Put the relevant files in place -cp /tmp/juice-shop/default.conf /etc/apache2/sites-available/000-default.conf - -# Download and start docker image with Juice Shop -docker run --restart=always -d -p 3000:3000 --name juice-shop bkimminich/juice-shop - -# Enable proxy modules in apache and restart -a2enmod proxy_http -systemctl restart apache2.service +#!/bin/sh + +# +# Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. +# SPDX-License-Identifier: MIT +# + +# Exit on error +set -e + +# Add docker key and repository +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - +sudo bash -c 'echo "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker-ce.list' + + +# Install apache and docker +apt-get update -q +apt-get upgrade -qy +apt-get install -qy apache2 docker-ce + +# Put the relevant files in place +cp /tmp/juice-shop/default.conf /etc/apache2/sites-available/000-default.conf + +# Download and start docker image with Juice Shop +docker run --restart=always -d -p 3000:3000 --name juice-shop bkimminich/juice-shop + +# Enable proxy modules in apache and restart +a2enmod proxy_http +systemctl restart apache2.service diff --git a/vagrant/default.conf b/vagrant/default.conf index 6822625d..dc4ac5b9 100644 --- a/vagrant/default.conf +++ b/vagrant/default.conf @@ -1,12 +1,12 @@ - - ServerAdmin webmaster@juice-sh.op - ServerName juice-sh.op - - ProxyPass / http://localhost:3000/ - ProxyPassReverse / http://localhost:3000 - - DocumentRoot /var/www/html - - ErrorLog /var/log/apache2/error.log - CustomLog /var/log/apache2/access.log common - + + ServerAdmin webmaster@juice-sh.op + ServerName juice-sh.op + + ProxyPass / http://localhost:3000/ + ProxyPassReverse / http://localhost:3000 + + DocumentRoot /var/www/html + + ErrorLog /var/log/apache2/error.log + CustomLog /var/log/apache2/access.log common + diff --git a/views/dataErasureForm.hbs b/views/dataErasureForm.hbs index 031bf1f6..0a211354 100644 --- a/views/dataErasureForm.hbs +++ b/views/dataErasureForm.hbs @@ -1,35 +1,35 @@ - - - - - - -
-
-

Data Erasure Request (Art. 17 GDPR)

-

We take data security, customer privacy, and legal compliance very serious. In accordance with GDPR we allow - you to request complete erasure of your account and any associated data.

-
Request Data Erasure
-
-
- - -
-
- - -
-
- -
-
-
+ + + + + + +
+
+

Data Erasure Request (Art. 17 GDPR)

+

We take data security, customer privacy, and legal compliance very serious. In accordance with GDPR we allow + you to request complete erasure of your account and any associated data.

+
Request Data Erasure
+
+
+ + +
+
+ + +
+
+ +
+
+
\ No newline at end of file diff --git a/views/dataErasureResult.hbs b/views/dataErasureResult.hbs index ae6c2b14..00470707 100644 --- a/views/dataErasureResult.hbs +++ b/views/dataErasureResult.hbs @@ -1,26 +1,26 @@ - - - - - - -
-
-

Sorry to see you leave! Your erasure request will be processed shortly.

- -
-
- \ No newline at end of file diff --git a/views/promotionVideo.pug b/views/promotionVideo.pug index 32ee1510..e5664a0b 100644 --- a/views/promotionVideo.pug +++ b/views/promotionVideo.pug @@ -1,116 +1,116 @@ -doctype html -html(lang='en') - head - title _title_ - meta(charset='utf-8') - meta(name='description', content='') - meta(name='keywords', content='') - meta(name='viewport' content='width=device-width, initial-scale=1.0') - link(rel='icon', type='image/x-icon', href='./assets/public/_favicon_') - link(rel='stylesheet', href='https://code.getmdl.io/1.3.0/material.min.css') - link(rel='stylesheet', href='https://fonts.googleapis.com/icon?family=Material+Icons') - link(rel='stylesheet', href='http://fonts.googleapis.com/css?family=Roboto:300,400,500,700', type='text/css') - script(src='//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js') - script(defer='', src='https://code.getmdl.io/1.3.0/material.min.js') - style. - video { - min-width: 320px; - width: 44vw; - display: block; - margin-left: auto; - margin-right:auto; - margin-bottom: 5px; - height: 50vh; - outline: none; - } - @media (max-width: 900px) { - .mdl-layout-title { - display: none !important; - } - } - body(style='background: _bgColor_;color:_textColor_;') - .mdl-layout.mdl-js-layout.mdl-layout--fixed-header - header.mdl-layout__header.mdl-shadow--8dp(style= 'background: _navColor_; height: auto; min-width: 100%; padding-bottom: 5px; width: 100%;') - .mdl-layout__header-row - a(href='./#/' style='color: _textColor_; text-decoration:none; margin-left: -50px;') - i(class='material-icons', style='display: block;margin-bottom: auto;margin-top: auto; margin-right: 10px;') arrow_back - a(href='./#/' style='color: _textColor_; text-decoration:none;') - span(style='margin-right: 20px;') - | Back - // Logo - a(href='./#/') - img(src='assets/public/images/JuiceShop_Logo.png', style='max-height: 60px; width: auto;', alt='_title_ Logo') - // Title - a(href='./#/' style='color: _textColor_; text-decoration:none;') - span.mdl-layout-title(style='font: 500 20px/32px Roboto,"Helvetica Neue",sans-serif;') - | _title_ - - section.section--center.mdl-grid.mdl-grid--no-spacing - .mdl-card#card.mdl-cell.mdl-cell--12-col.mdl-shadow--8dp(style='width: 45vw; min-width: 320px; height: 58vh; background: _primLight_; margin-bottom: 50px; margin-top: 110px; display: block; margin-left: auto; margin-right:auto; ') - h1(style='color: _textColor_; font-size: 24px; line-height: 32px; margin-top: 16px; margin-bottom: 16px; font-weight: 400; margin-left: 16px;') Promotion Video - video(width='85vw', height='240', controls='controls') - source(src='./video', type='video/mp4') - - script#subtitle. - - - script. - function parse_timestamp(s) { - var match = s.match(/^(?:([0-9]+):)?([0-5][0-9]):([0-5][0-9](?:[.,][0-9]{0,3})?)/); - if (match == null) { - throw 'Invalid timestamp format: ' + s; - } - var hours = parseInt(match[1] || "0", 10); - var minutes = parseInt(match[2], 10); - var seconds = parseFloat(match[3].replace(',', '.')); - return seconds + 60 * minutes + 60 * 60 * hours; - } - function quick_and_dirty_vtt_or_srt_parser(vtt) { - var lines = vtt.trim().replace('\\r\n', '\n').split(/[\r\n]/).map(function(line) { - return line.trim(); - }); - var cues = []; - var start = null; - var end = null; - var payload = null; - for (var i = 0; i < lines.length; i++) { - if (lines[i].indexOf('-->') >= 0) { - var splitted = lines[i].split(/[ \\t]+-->[ \t]+/); - if (splitted.length != 2) { - throw 'Error when splitting "-->": ' + lines[i]; - } - // Already ignoring anything past the "end" timestamp (i.e. cue settings). - start = parse_timestamp(splitted[0]); - end = parse_timestamp(splitted[1]); - } else if (lines[i] == '') { - if (start && end) { - var cue = new VTTCue(start, end, payload); - cues.push(cue); - start = null; - end = null; - payload = null; - } - } else if(start && end) { - if (payload == null) { - payload = lines[i]; - } else { - payload += '\\n' + lines[i]; - } - } - } - if (start && end) { - var cue = new VTTCue(start, end, payload); - cues.push(cue); - } - return cues; - } - function init() { - var video = document.querySelector('video'); - var subtitle = document.getElementById('subtitle'); - var track = video.addTextTrack('subtitles', subtitle.dataset.label, subtitle.dataset.lang); - track.mode = "showing"; - quick_and_dirty_vtt_or_srt_parser(subtitle.innerHTML).map(function(cue) { - track.addCue(cue); - }); - } - init(); +doctype html +html(lang='en') + head + title _title_ + meta(charset='utf-8') + meta(name='description', content='') + meta(name='keywords', content='') + meta(name='viewport' content='width=device-width, initial-scale=1.0') + link(rel='icon', type='image/x-icon', href='./assets/public/_favicon_') + link(rel='stylesheet', href='https://code.getmdl.io/1.3.0/material.min.css') + link(rel='stylesheet', href='https://fonts.googleapis.com/icon?family=Material+Icons') + link(rel='stylesheet', href='http://fonts.googleapis.com/css?family=Roboto:300,400,500,700', type='text/css') + script(src='//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js') + script(defer='', src='https://code.getmdl.io/1.3.0/material.min.js') + style. + video { + min-width: 320px; + width: 44vw; + display: block; + margin-left: auto; + margin-right:auto; + margin-bottom: 5px; + height: 50vh; + outline: none; + } + @media (max-width: 900px) { + .mdl-layout-title { + display: none !important; + } + } + body(style='background: _bgColor_;color:_textColor_;') + .mdl-layout.mdl-js-layout.mdl-layout--fixed-header + header.mdl-layout__header.mdl-shadow--8dp(style= 'background: _navColor_; height: auto; min-width: 100%; padding-bottom: 5px; width: 100%;') + .mdl-layout__header-row + a(href='./#/' style='color: _textColor_; text-decoration:none; margin-left: -50px;') + i(class='material-icons', style='display: block;margin-bottom: auto;margin-top: auto; margin-right: 10px;') arrow_back + a(href='./#/' style='color: _textColor_; text-decoration:none;') + span(style='margin-right: 20px;') + | Back + // Logo + a(href='./#/') + img(src='assets/public/images/JuiceShop_Logo.png', style='max-height: 60px; width: auto;', alt='_title_ Logo') + // Title + a(href='./#/' style='color: _textColor_; text-decoration:none;') + span.mdl-layout-title(style='font: 500 20px/32px Roboto,"Helvetica Neue",sans-serif;') + | _title_ + + section.section--center.mdl-grid.mdl-grid--no-spacing + .mdl-card#card.mdl-cell.mdl-cell--12-col.mdl-shadow--8dp(style='width: 45vw; min-width: 320px; height: 58vh; background: _primLight_; margin-bottom: 50px; margin-top: 110px; display: block; margin-left: auto; margin-right:auto; ') + h1(style='color: _textColor_; font-size: 24px; line-height: 32px; margin-top: 16px; margin-bottom: 16px; font-weight: 400; margin-left: 16px;') Promotion Video + video(width='85vw', height='240', controls='controls') + source(src='./video', type='video/mp4') + + script#subtitle. + + + script. + function parse_timestamp(s) { + var match = s.match(/^(?:([0-9]+):)?([0-5][0-9]):([0-5][0-9](?:[.,][0-9]{0,3})?)/); + if (match == null) { + throw 'Invalid timestamp format: ' + s; + } + var hours = parseInt(match[1] || "0", 10); + var minutes = parseInt(match[2], 10); + var seconds = parseFloat(match[3].replace(',', '.')); + return seconds + 60 * minutes + 60 * 60 * hours; + } + function quick_and_dirty_vtt_or_srt_parser(vtt) { + var lines = vtt.trim().replace('\\r\n', '\n').split(/[\r\n]/).map(function(line) { + return line.trim(); + }); + var cues = []; + var start = null; + var end = null; + var payload = null; + for (var i = 0; i < lines.length; i++) { + if (lines[i].indexOf('-->') >= 0) { + var splitted = lines[i].split(/[ \\t]+-->[ \t]+/); + if (splitted.length != 2) { + throw 'Error when splitting "-->": ' + lines[i]; + } + // Already ignoring anything past the "end" timestamp (i.e. cue settings). + start = parse_timestamp(splitted[0]); + end = parse_timestamp(splitted[1]); + } else if (lines[i] == '') { + if (start && end) { + var cue = new VTTCue(start, end, payload); + cues.push(cue); + start = null; + end = null; + payload = null; + } + } else if(start && end) { + if (payload == null) { + payload = lines[i]; + } else { + payload += '\\n' + lines[i]; + } + } + } + if (start && end) { + var cue = new VTTCue(start, end, payload); + cues.push(cue); + } + return cues; + } + function init() { + var video = document.querySelector('video'); + var subtitle = document.getElementById('subtitle'); + var track = video.addTextTrack('subtitles', subtitle.dataset.label, subtitle.dataset.lang); + track.mode = "showing"; + quick_and_dirty_vtt_or_srt_parser(subtitle.innerHTML).map(function(cue) { + track.addCue(cue); + }); + } + init(); diff --git a/views/themes/themes.js b/views/themes/themes.js index 91e28fe5..6d93951a 100644 --- a/views/themes/themes.js +++ b/views/themes/themes.js @@ -1,56 +1,56 @@ -/* - * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. - * SPDX-License-Identifier: MIT - */ - -exports.themes = { - 'bluegrey-lightgreen': { - bgColor: '#303030', - textColor: '#FFFFFF', - navColor: '#546E7A', - primLight: '#424242', - primDark: '#263238' - }, - 'blue-lightblue': { - bgColor: '#FAFAFA', - textColor: '#000000', - navColor: '#1976D2', - primLight: '#29B6F6', - primDark: '#0277BD' - }, - 'deeppurple-amber': { - bgColor: '#FAFAFA', - textColor: '#000000', - navColor: '#673AB7', - primLight: '#9575CD', - primDark: '#512DA8' - }, - 'indigo-pink': { - bgColor: '#FAFAFA', - textColor: '#000000', - navColor: '#3F51B5', - primLight: '#7986CB', - primDark: '#303F9F' - }, - 'pink-bluegrey': { - bgColor: '#303030', - textColor: '#FFFFFF', - navColor: '#C2185B', - primLight: '#E91E63', - primDark: '#880E4F' - }, - 'purple-green': { - bgColor: '#303030', - textColor: '#FFFFFF', - navColor: '#7B1FA2', - primLight: '#9C27B0', - primDark: '#4A148C' - }, - 'deeporange-indigo': { - bgColor: '#FAFAFA', - textColor: '#000000', - navColor: '#E64A19', - primLight: '#FF5722', - primDark: '#BF360C' - } -} +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +exports.themes = { + 'bluegrey-lightgreen': { + bgColor: '#303030', + textColor: '#FFFFFF', + navColor: '#546E7A', + primLight: '#424242', + primDark: '#263238' + }, + 'blue-lightblue': { + bgColor: '#FAFAFA', + textColor: '#000000', + navColor: '#1976D2', + primLight: '#29B6F6', + primDark: '#0277BD' + }, + 'deeppurple-amber': { + bgColor: '#FAFAFA', + textColor: '#000000', + navColor: '#673AB7', + primLight: '#9575CD', + primDark: '#512DA8' + }, + 'indigo-pink': { + bgColor: '#FAFAFA', + textColor: '#000000', + navColor: '#3F51B5', + primLight: '#7986CB', + primDark: '#303F9F' + }, + 'pink-bluegrey': { + bgColor: '#303030', + textColor: '#FFFFFF', + navColor: '#C2185B', + primLight: '#E91E63', + primDark: '#880E4F' + }, + 'purple-green': { + bgColor: '#303030', + textColor: '#FFFFFF', + navColor: '#7B1FA2', + primLight: '#9C27B0', + primDark: '#4A148C' + }, + 'deeporange-indigo': { + bgColor: '#FAFAFA', + textColor: '#000000', + navColor: '#E64A19', + primLight: '#FF5722', + primDark: '#BF360C' + } +} diff --git a/views/userProfile.pug b/views/userProfile.pug index 19d64fd9..b96d2e6c 100644 --- a/views/userProfile.pug +++ b/views/userProfile.pug @@ -1,82 +1,82 @@ -doctype html -html(lang='en') - head - title _title_ - meta(charset='utf-8') - meta(name='description', content='') - meta(name='keywords', content='') - meta(name='viewport' content='width=device-width, initial-scale=1.0') - link(rel='icon', type='image/x-icon', href='./assets/public/_favicon_') - link(rel='stylesheet', href='https://code.getmdl.io/1.3.0/material.min.css') - link(rel='stylesheet', href='https://fonts.googleapis.com/icon?family=Material+Icons') - link(rel='stylesheet', href='./assets/public/css/userProfile.css', type='text/css') - link(rel='stylesheet', href='http://fonts.googleapis.com/css?family=Roboto:300,400,500,700', type='text/css') - script(src='//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js') - script(src='https://code.getmdl.io/1.3.0/material.min.js') - style. - .mdl-textfield__input { - border-bottom: 1px solid _textColor_ !important; - font-size: 13px !important; - } - body(style='background: _bgColor_;color:_textColor_;') - .mdl-layout.mdl-js-layout.mdl-layout--fixed-header - header.mdl-layout__header.mdl-shadow--8dp(style= 'background: _navColor_; height: auto; min-width: 100%; padding-bottom: 5px; width: 100%;') - .mdl-layout__header-row - a(href='./#/' style='color: _textColor_; text-decoration:none; margin-left: -50px;') - i(class='material-icons', style='display: block;margin-bottom: auto;margin-top: auto; margin-right: 10px;') arrow_back - a(href='./#/' style='color: _textColor_; text-decoration:none;') - span(style='margin-right: 20px;') - | Back - // Logo - a(href='./#/') - img(src='assets/public/images/_logo_', style='max-height: 60px; width: auto;', alt='_title_ Logo') - // Title - a(href='./#/' style='color: _textColor_; text-decoration:none;') - span.mdl-layout-title(style='font: 500 20px/32px Roboto,"Helvetica Neue",sans-serif;') - | _title_ - - main.mdl-layout__content(style=' display: block; margin-left: auto; margin-right:auto;') - section.section--center.mdl-grid.mdl-grid--no-spacing - .mdl-card#card.mdl-cell.mdl-cell--12-col.mdl-shadow--8dp(style='height: auto; min-width: 300px; width: 40%; display: block; margin-left: auto; margin-right:auto; background: _primLight_; margin-bottom: 50px; margin-top: 110px;') - .mdl-card__supporting-text.mdl-grid.mdl-grid--no-spacing - h1.mdl-cell.mdl-cell--12-col(style='color: _textColor_; font-size: 24px; line-height: 32px; margin-top: 16px; margin-bottom: 16px; font-weight: 400;') User Profile - .mdl-cell.mdl-cell--6-col-desktop.mdl-cell--12-col-tablet.mdl-cell--12-col-phone - img.img-rounded(src=profileImage, alt='profile picture', width='90%', height='236', style='margin-right: 5%; margin-left: 5%;') - p(style='margin-top:8%; color: _textColor_; text-align: center;') _username_ - form(action='./profile/image/file' , style='margin-top:10%; width: 90%; margin-right: auto; margin-left: auto;', method='post', enctype='multipart/form-data') - .form-group - label(for='picture', style='color: _textColor_; font-size: 12px;') File Upload: - input#picture(type='file', accept='image/*', name='file', size='150', style='color: _textColor_; margin-top: 4px;', aria-label='Input for selecting the profile picture') - .mdl-tooltip(for='picture', style='width: 150px; text-align: left;') - | • Maximum file size 150Kb - br - | • All image formats are accepted - button.mdl-button.mdl-js-button.mdl-button--raised.mdl-js-ripple-effect(type='submit', style='background-color:_navColor_; color: _textColor_; margin-top: 3%; text-transform: capitalize;', aria-label='Button to upload the profile picture') Upload Picture - - .breakLine(style='margin-top: 3%; margin-bottom: 3%; width: 90%; margin-right: auto; margin-left: auto;') - .line - div - .textOnLine(style='color: _textColor_;') or - .line - div - - form(action='./profile/image/url' , style='margin-top:5%; width: 90%; margin-right: auto; margin-left: auto;', method='post') - .form-group - .mdl-textfield.mdl-js-textfield.mdl-textfield--floating-label(style='width: 100%;') - input#url.form-control.mdl-textfield__input(type='text', name='imageUrl', style='color: _textColor_;', placeholder='e.g. https://www.gravatar.com/avatar/_emailHash_', aria-label='Text field for the image link') - label.mdl-textfield__label(for='url', style='color: _textColor_;') Image URL: - button(id='submitUrl', type='submit', style='background-color:_navColor_; color: _textColor_; margin-top: -10px; text-transform: capitalize;', aria-label='Button to include image from link').mdl-button.mdl-js-button.mdl-button--raised.mdl-js-ripple-effect Link Image - p(style='margin-bottom:10%;') - - .mdl-cell.mdl-cell--6-col-desktop.mdl-cell--12-col-tablet.mdl-cell--12-col-phone - form(action='./profile', method='post', style='width: 90%; margin-right: auto; margin-left: auto;') - .form-group - .mdl-textfield.mdl-js-textfield.mdl-textfield--floating-label(style='width: 100%; opacity: 0.7') - input#email.form-control.mdl-textfield__input(type='email', name='email', value=email, disabled=true, style='color: _textColor_;', aria-label='Disabled - Text field for the email') - label.mdl-textfield__label(for='email', style='color: _textColor_;') Email: - .form-group - .mdl-textfield.mdl-js-textfield.mdl-textfield--floating-label(style='width: 100%;') - input#username.form-control.mdl-textfield__input(type='text', name='username', value=username ,style='color: _textColor_;', placeholder='e.g. SuperUser', aria-label='Text field for the username') - label.mdl-textfield__label(for='username', style='color: _textColor_;') Username: - button(id='submit', type='submit', style='background-color:_navColor_; color: _textColor_; margin-top: -10px; text-transform: capitalize;', aria-label='Button to save/set the username').mdl-button.mdl-js-button.mdl-button--raised.mdl-js-ripple-effect Set Username +doctype html +html(lang='en') + head + title _title_ + meta(charset='utf-8') + meta(name='description', content='') + meta(name='keywords', content='') + meta(name='viewport' content='width=device-width, initial-scale=1.0') + link(rel='icon', type='image/x-icon', href='./assets/public/_favicon_') + link(rel='stylesheet', href='https://code.getmdl.io/1.3.0/material.min.css') + link(rel='stylesheet', href='https://fonts.googleapis.com/icon?family=Material+Icons') + link(rel='stylesheet', href='./assets/public/css/userProfile.css', type='text/css') + link(rel='stylesheet', href='http://fonts.googleapis.com/css?family=Roboto:300,400,500,700', type='text/css') + script(src='//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js') + script(src='https://code.getmdl.io/1.3.0/material.min.js') + style. + .mdl-textfield__input { + border-bottom: 1px solid _textColor_ !important; + font-size: 13px !important; + } + body(style='background: _bgColor_;color:_textColor_;') + .mdl-layout.mdl-js-layout.mdl-layout--fixed-header + header.mdl-layout__header.mdl-shadow--8dp(style= 'background: _navColor_; height: auto; min-width: 100%; padding-bottom: 5px; width: 100%;') + .mdl-layout__header-row + a(href='./#/' style='color: _textColor_; text-decoration:none; margin-left: -50px;') + i(class='material-icons', style='display: block;margin-bottom: auto;margin-top: auto; margin-right: 10px;') arrow_back + a(href='./#/' style='color: _textColor_; text-decoration:none;') + span(style='margin-right: 20px;') + | Back + // Logo + a(href='./#/') + img(src='assets/public/images/_logo_', style='max-height: 60px; width: auto;', alt='_title_ Logo') + // Title + a(href='./#/' style='color: _textColor_; text-decoration:none;') + span.mdl-layout-title(style='font: 500 20px/32px Roboto,"Helvetica Neue",sans-serif;') + | _title_ + + main.mdl-layout__content(style=' display: block; margin-left: auto; margin-right:auto;') + section.section--center.mdl-grid.mdl-grid--no-spacing + .mdl-card#card.mdl-cell.mdl-cell--12-col.mdl-shadow--8dp(style='height: auto; min-width: 300px; width: 40%; display: block; margin-left: auto; margin-right:auto; background: _primLight_; margin-bottom: 50px; margin-top: 110px;') + .mdl-card__supporting-text.mdl-grid.mdl-grid--no-spacing + h1.mdl-cell.mdl-cell--12-col(style='color: _textColor_; font-size: 24px; line-height: 32px; margin-top: 16px; margin-bottom: 16px; font-weight: 400;') User Profile + .mdl-cell.mdl-cell--6-col-desktop.mdl-cell--12-col-tablet.mdl-cell--12-col-phone + img.img-rounded(src=profileImage, alt='profile picture', width='90%', height='236', style='margin-right: 5%; margin-left: 5%;') + p(style='margin-top:8%; color: _textColor_; text-align: center;') _username_ + form(action='./profile/image/file' , style='margin-top:10%; width: 90%; margin-right: auto; margin-left: auto;', method='post', enctype='multipart/form-data') + .form-group + label(for='picture', style='color: _textColor_; font-size: 12px;') File Upload: + input#picture(type='file', accept='image/*', name='file', size='150', style='color: _textColor_; margin-top: 4px;', aria-label='Input for selecting the profile picture') + .mdl-tooltip(for='picture', style='width: 150px; text-align: left;') + | • Maximum file size 150Kb + br + | • All image formats are accepted + button.mdl-button.mdl-js-button.mdl-button--raised.mdl-js-ripple-effect(type='submit', style='background-color:_navColor_; color: _textColor_; margin-top: 3%; text-transform: capitalize;', aria-label='Button to upload the profile picture') Upload Picture + + .breakLine(style='margin-top: 3%; margin-bottom: 3%; width: 90%; margin-right: auto; margin-left: auto;') + .line + div + .textOnLine(style='color: _textColor_;') or + .line + div + + form(action='./profile/image/url' , style='margin-top:5%; width: 90%; margin-right: auto; margin-left: auto;', method='post') + .form-group + .mdl-textfield.mdl-js-textfield.mdl-textfield--floating-label(style='width: 100%;') + input#url.form-control.mdl-textfield__input(type='text', name='imageUrl', style='color: _textColor_;', placeholder='e.g. https://www.gravatar.com/avatar/_emailHash_', aria-label='Text field for the image link') + label.mdl-textfield__label(for='url', style='color: _textColor_;') Image URL: + button(id='submitUrl', type='submit', style='background-color:_navColor_; color: _textColor_; margin-top: -10px; text-transform: capitalize;', aria-label='Button to include image from link').mdl-button.mdl-js-button.mdl-button--raised.mdl-js-ripple-effect Link Image + p(style='margin-bottom:10%;') + + .mdl-cell.mdl-cell--6-col-desktop.mdl-cell--12-col-tablet.mdl-cell--12-col-phone + form(action='./profile', method='post', style='width: 90%; margin-right: auto; margin-left: auto;') + .form-group + .mdl-textfield.mdl-js-textfield.mdl-textfield--floating-label(style='width: 100%; opacity: 0.7') + input#email.form-control.mdl-textfield__input(type='email', name='email', value=email, disabled=true, style='color: _textColor_;', aria-label='Disabled - Text field for the email') + label.mdl-textfield__label(for='email', style='color: _textColor_;') Email: + .form-group + .mdl-textfield.mdl-js-textfield.mdl-textfield--floating-label(style='width: 100%;') + input#username.form-control.mdl-textfield__input(type='text', name='username', value=username ,style='color: _textColor_;', placeholder='e.g. SuperUser', aria-label='Text field for the username') + label.mdl-textfield__label(for='username', style='color: _textColor_;') Username: + button(id='submit', type='submit', style='background-color:_navColor_; color: _textColor_; margin-top: -10px; text-transform: capitalize;', aria-label='Button to save/set the username').mdl-button.mdl-js-button.mdl-button--raised.mdl-js-ripple-effect Set Username p(style='margin-bottom:10%;') \ No newline at end of file