diff --git a/.gitignore b/.gitignore index 53273a5b1..fb3ff0300 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,8 @@ /.settings/org.eclipse.wst.validation.prefs /.externalToolBuilders/ .project -/target +*/target/* +mongo-data/* .classpath .idea/ .settings/ @@ -29,6 +30,7 @@ src/main/webapp/plugin_lessons/*.jar src/main/webapp/users/*.props classes/* *.iml +pom.xml.versionsBackup /*.iml .extract/* @@ -39,3 +41,4 @@ webgoat-lessons/**/target **/*.jar **/.DS_Store webgoat-server/mongo-data/* +webgoat-lessons/vulnerable-components/dependency-reduced-pom.xml diff --git a/.travis.yml b/.travis.yml index 2543b516f..ff681acfb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,10 +7,20 @@ install: "/bin/true" script: - export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi) - echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$PR, BRANCH=$BRANCH" +- if [ ! -z "${TRAVIS_TAG}" ]; then mvn versions:set -DnewVersion=${TRAVIS_TAG:1}; fi - mvn clean install -q cache: directories: - "$HOME/.m2" +before_deploy: + - export WEBGOAT_SERVER_TARGET_DIR=$HOME/build/$TRAVIS_REPO_SLUG/webgoat-server/target + - export WEBWOLF_TARGET_DIR=$HOME/build/$TRAVIS_REPO_SLUG/webwolf/target + - export WEBGOAT_ARTIFACTS_FOLDER=$HOME/build/$TRAVIS_REPO_SLUG/Deployable_Artifacts/ + - mkdir -p $WEBGOAT_ARTIFACTS_FOLDER + - cp -fa $WEBGOAT_SERVER_TARGET_DIR/*.jar $WEBGOAT_ARTIFACTS_FOLDER/ + - cp -fa $WEBWOLF_TARGET_DIR/*.jar $WEBGOAT_ARTIFACTS_FOLDER/ + - echo "Contents of artifacts folder:" + - ls $WEBGOAT_ARTIFACTS_FOLDER deploy: - provider: script skip_cleanup: true @@ -25,10 +35,13 @@ deploy: repo: WebGoat/WebGoat branch: develop - provider: releases + skip_cleanup: true + overwrite: true api_key: #api-key from webgoat-github user secure: pJOLBnl6427PcVg/tVy/qB18JC7b8cKpffau+IP0pjdSt7KUfBdBY3QuJ7mrM65zRoVILzggLckaew2PlRmYQRdumyWlyRn44XiJ9KO4n6Bsufbz+ictB4ggtozpp9+I9IIUh1TmqypL9lhkX2ONM9dSHmyblYpAAgMuYSK8FYc= - file: "webgoat-server/target/webgoat-server*.jar" + file_glob: true + file: $WEBGOAT_ARTIFACTS_FOLDER/* on: repo: WebGoat/WebGoat tags: true diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..c9b080539 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,245 @@ +# 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/CREATE_RELEASE.MD b/CREATE_RELEASE.MD new file mode 100644 index 000000000..885c7a2fc --- /dev/null +++ b/CREATE_RELEASE.MD @@ -0,0 +1,29 @@ +## Release WebGoat + + +### Version numbers + +For WebGoat we use milestone releases first before we release the official version, we use `v8.0.0.M3` while tagging + and 8.0.0.M3 in the `pom.xml`. When we create the final release we remove the milestone release and use + `v8.0.0` and 8.0.0 in the `pom.xml` + +At the moment we use Gitflow, for a release you create a new release branch and take the following steps: + +``` +git checkout develop +git flow release start +mvn versions:set < +git commit -am "New release, updaing pom.xml" +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 +``` + +Now Travis takes over and will create the release in Github and on Docker Hub. + + diff --git a/README.MD b/README.MD index 775d9043d..67f2b3b0e 100644 --- a/README.MD +++ b/README.MD @@ -1,4 +1,4 @@ -# WebGoat: A deliberately insecure Web Application +# WebGoat 8: A deliberately insecure Web Application [![Build Status](https://travis-ci.org/WebGoat/WebGoat.svg?branch=develop)](https://travis-ci.org/WebGoat/WebGoat) [![Coverage Status](https://coveralls.io/repos/WebGoat/WebGoat/badge.svg?branch=develop&service=github)](https://coveralls.io/github/WebGoat/WebGoat?branch=master) @@ -6,10 +6,6 @@ [![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) -# Important - -This is the development version of WebGoat 8, if you are looking for a released stable version please go to: https://github.com/WebGoat/WebGoat/wiki/Running-WebGoat - # Introduction @@ -65,9 +61,23 @@ _Please note: this version may not be completely in sync with the develop branch Download the latest WebWolf release from [https://github.com/WebGoat/WebGoat/releases](https://github.com/WebGoat/WebGoat/releases) ```Shell -java -jar webwolf-<>.jar +java -jar webgoat-server-<>.jar ``` +By default WebGoat starts at port 8080 in order to change this use the following property: + +```Shell +java -jar webgoat-server-<>.jar --server.port=9090 +``` + +You can specify one of the following arguments when starting WebGoat: + +```Shell +java -jar webgoat-server-<>.jar --server.port=9090 --server.address=x.x.x.x +``` + +This will start WebGoat on a different port and/or different address. + ## 3. Run from the sources @@ -88,18 +98,19 @@ Now let's start by compiling the project. ```Shell cd WebGoat -git checkout develop +git checkout <> mvn clean install ``` Now we are ready to run the project. WebGoat 8.x is using Spring-Boot. ```Shell -mvn -pl webwolf spring-boot:run +mvn -pl webgoat-server spring-boot:run ``` ... you should be running webgoat on localhost:8080/WebGoat momentarily -To change IP addresss add the following variable to WebGoat/webgoat-container/src/main/resources/application.properties file + +To change IP address add the following variable to WebGoat/webgoat-container/src/main/resources/application.properties file ``` server.address=x.x.x.x @@ -110,8 +121,8 @@ 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 - $ vagrant up + $ cd WebGoat/webgoat-images/vagrant-users + $ vagrant up ``` Once the provisioning is complete login to the Virtualbox with username vagrant and password vagrant. @@ -120,6 +131,8 @@ The source code will be available in the home directory. # Building a new Docker image +NOTE: Travis will create a new Docker image automatically when making a new release. + WebGoat now has Docker support for x86 and ARM (raspberry pi). ### Docker on x86 On x86 you can build a container with the following commands: diff --git a/docker-compose.yml b/docker-compose.yml index 3212cae13..9b0769407 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,40 +1,15 @@ version: '2.0' services: - activemq: - image: webcenter/activemq:latest - ports: - - 8161:8161 - - 61616:61616 - - 61613:61613 - mongo: - image: mongo:latest - expose: - - "27017" - volumes: - - './mongo-data:/data/db' webgoat: build: webgoat-server/ command: "sh /home/webgoat/start.sh" ports: - "8080:8080" - depends_on: - [mongo, activemq] - environment: - WG_MONGO_PORT: 27017 - WG_MONGO_HOST: mongo - WG_MQ_HOST: activemq - WG_MQ_PORT: 61616 - WG_INTERNAL_MONGO: "false" webwolf: build: webwolf/ command: "sh /home/webwolf/start.sh" depends_on: - webgoat ports: - - "8081:8081" - environment: - WG_MONGO_PORT: 27017 - WG_MONGO_HOST: mongo - WG_MQ_HOST: activemq - WG_MQ_PORT: 61616 \ No newline at end of file + - "8081:8081" \ No newline at end of file diff --git a/pom.xml b/pom.xml index af11bbd60..ed6151f87 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.owasp.webgoat webgoat-parent pom - 8.0-SNAPSHOT + 8.0.0.M3 WebGoat Parent Pom Parent Pom for the WebGoat Project. A deliberately insecure Web Application @@ -142,7 +142,6 @@ 6.0 1.2 1.7.12 - 1.2 1.3.1 4.12 1.5.4 @@ -296,8 +295,8 @@ org.projectlombok lombok - 1.16.10 provided + true org.apache.commons diff --git a/scripts/deploy-webgoat.sh b/scripts/deploy-webgoat.sh index 70ae5346a..c0374ad37 100644 --- a/scripts/deploy-webgoat.sh +++ b/scripts/deploy-webgoat.sh @@ -4,16 +4,15 @@ docker login -u $DOCKER_USER -p $DOCKER_PASS export REPO=webgoat/webgoat-8.0 cd webgoat-server +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 -f Dockerfile -t $REPO:latest . - docker tag $REPO:${TRAVIS_TAG} + docker build --build-arg webgoat_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 -f Dockerfile -t $REPO:${TRAVIS_TAG} . - docker tag $REPO:${TRAVIS_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 . diff --git a/webgoat-container/pom.xml b/webgoat-container/pom.xml index 9d51d232a..d9682cb57 100644 --- a/webgoat-container/pom.xml +++ b/webgoat-container/pom.xml @@ -10,7 +10,7 @@ org.owasp.webgoat webgoat-parent - 8.0-SNAPSHOT + 8.0.0.M3 @@ -36,16 +36,6 @@ - - - - de.flapdoodle.embed - de.flapdoodle.embed.mongo - 2.0.0 - - - - @@ -92,29 +82,6 @@ never - - maven-clean-plugin - - - - ${project.basedir}/src/main/resources/plugin_lessons - - **/*.jar - **/*.pom - - - - ${user.home}/.webgoat/ - - **/*.jar - **/org/** - **/plugin/** - - - - - - org.apache.maven.plugins maven-jar-plugin @@ -135,14 +102,6 @@ com.fasterxml.jackson.datatype jackson-datatype-jsr310 - - org.projectlombok - lombok - - - org.projectlombok - lombok - org.springframework.boot spring-boot-starter-web @@ -152,41 +111,32 @@ spring-boot-starter-actuator - org.springframework.boot - spring-boot-starter-cache - - org.asciidoctor asciidoctorj 1.5.4 org.springframework.boot - spring-boot-starter-data-mongodb + spring-boot-starter-data-jpa org.apache.commons commons-lang3 ${commons-lang3.version} + + com.google.guava + guava + ${guava.version} + + + io.gatling.highcharts gatling-charts-highcharts ${gatling.version} test - - javax.servlet - jstl - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-jdbc - org.springframework.boot spring-boot-starter-security @@ -205,11 +155,6 @@ activation ${activation.version} - - com.h2database - h2 - ${h2.version} - org.hsqldb hsqldb @@ -224,19 +169,7 @@ org.scala-lang scala-compiler ${scala.version} - - - - - commons-fileupload - commons-fileupload - ${commons-fileupload.version} - - - - com.google.guava - guava - ${guava.version} + test @@ -259,12 +192,6 @@ ${junit.version} jar - - com.github.fakemongo - fongo - 2.1.0 - test - 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 0a0148b58..8510906f5 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java @@ -32,6 +32,7 @@ package org.owasp.webgoat; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import lombok.extern.slf4j.Slf4j; import org.asciidoctor.Asciidoctor; import org.owasp.webgoat.i18n.Language; import org.thymeleaf.TemplateProcessingParameters; @@ -41,6 +42,7 @@ import org.thymeleaf.templateresolver.TemplateResolver; import java.io.*; import java.util.Map; +import static org.apache.commons.lang3.CharEncoding.UTF_8; import static org.asciidoctor.Asciidoctor.Factory.create; /** @@ -50,6 +52,7 @@ import static org.asciidoctor.Asciidoctor.Factory.create; *
* */ +@Slf4j public class AsciiDoctorTemplateResolver extends TemplateResolver { private static final Asciidoctor asciidoctor = create(); @@ -73,11 +76,15 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver { @Override public InputStream getResourceAsStream(TemplateProcessingParameters params, String resourceName) { - InputStream is = readInputStreamOrFallbackToEnglish(resourceName, language); - try { - StringWriter writer = new StringWriter(); - asciidoctor.convert(new InputStreamReader(is), writer, createAttributes()); - return new ByteArrayInputStream(writer.getBuffer().toString().getBytes()); + try (InputStream is = readInputStreamOrFallbackToEnglish(resourceName, language)) { + if (is == null) { + log.warn("Resource name: {} not found, did you add the adoc file?", resourceName); + return new ByteArrayInputStream(new byte[0]); + } else { + StringWriter writer = new StringWriter(); + asciidoctor.convert(new InputStreamReader(is), writer, createAttributes()); + return new ByteArrayInputStream(writer.getBuffer().toString().getBytes(UTF_8)); + } } catch (IOException e) { //no html yet return new ByteArrayInputStream(new byte[0]); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/CleanupLocalProgressFiles.java b/webgoat-container/src/main/java/org/owasp/webgoat/CleanupLocalProgressFiles.java index d0667fd9f..2048dbbd7 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/CleanupLocalProgressFiles.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/CleanupLocalProgressFiles.java @@ -23,11 +23,5 @@ public class CleanupLocalProgressFiles { @PostConstruct public void clean() { - File dir = new File(webgoatHome); - //do it safe, check whether the subdir mongodb is available as subdirectory - File[] mongoDir = dir.listFiles(f -> f.isDirectory() && f.getName().contains("mongodb")); - if (mongoDir != null && mongoDir.length == 1) { - FileSystemUtils.deleteRecursively(dir); - } } } 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 bbd993c77..41758c742 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 @@ -2,6 +2,10 @@ package org.owasp.webgoat.lessons; import lombok.*; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Transient; import java.util.List; /** @@ -38,11 +42,14 @@ import java.util.List; @NoArgsConstructor @Getter @EqualsAndHashCode +@Entity public class Assignment { @NonNull + @Id private String name; @NonNull private String path; + @Transient private List hints; } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/SolutionService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/SolutionService.java deleted file mode 100644 index 2314ac6d5..000000000 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/SolutionService.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * ************************************************************************************************* - *

- *

- * This file is part of WebGoat, an Open Web Application Security Project - * utility. For details, please see http://www.owasp.org/ - *

- * Copyright (c) 2002 - 20014 Bruce Mayhew - *

- * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - *

- * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - *

- * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - *

- * Getting Source ============== - *

- * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository - * for free software projects. - */ -package org.owasp.webgoat.service; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -/** - *

SolutionService class.

- * - * @author rlawson - * @version $Id: $Id - */ -@Controller -public class SolutionService { - - /** - * Returns solution for current attack - * - * @return a {@link java.lang.String} object. - */ - @RequestMapping(path = "/service/solution.mvc", produces = "text/html") - public - @ResponseBody - String showSolution() { - //// TODO: 11/6/2016 to decide not sure about the role in WebGoat 8 - String source = getSolution(); - return source; - } - - /** - *

getSolution.

- * - * @return a {@link java.lang.String} object. - */ - protected String getSolution() { - return "Solution is not available"; - } -} diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/SourceService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/SourceService.java deleted file mode 100644 index 15267f29d..000000000 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/SourceService.java +++ /dev/null @@ -1,82 +0,0 @@ -/** - * ************************************************************************************************* - *

- *

- * This file is part of WebGoat, an Open Web Application Security Project - * utility. For details, please see http://www.owasp.org/ - *

- * Copyright (c) 2002 - 20014 Bruce Mayhew - *

- * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - *

- * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - *

- * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. - *

- * Getting Source ============== - *

- * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository - * for free software projects. - */ -package org.owasp.webgoat.service; - -import org.apache.commons.lang3.StringEscapeUtils; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -import javax.servlet.http.HttpSession; - -/** - *

SourceService class.

- * - * @author rlawson - * @version $Id: $Id - */ -@Controller -//TODO REMOVE! -public class SourceService { - - /** - * Description of the Field - */ - public final static String START_SOURCE_SKIP = "START_OMIT_SOURCE"; - - /** Constant END_SOURCE_SKIP="END_OMIT_SOURCE" */ - public final static String END_SOURCE_SKIP = "END_OMIT_SOURCE"; - - /** - * Returns source for current attack - * - * @param session a {@link javax.servlet.http.HttpSession} object. - * @return a {@link java.lang.String} object. - */ - @RequestMapping(path = "/service/source.mvc", produces = "application/text") - public - @ResponseBody - String showSource(HttpSession session) { - //// TODO: 11/6/2016 to decide not sure about the role in WebGoat 8 - String source = getSource(); - if (source == null) { - source = "No source listing found"; - } - return StringEscapeUtils.escapeHtml4(source); - } - - /** - * Description of the Method - * - * @return Description of the Return Value - */ - protected String getSource() { - return "Source code is not available for this lesson."; - } -} 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 bff30316e..d8a7d4a75 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 @@ -7,6 +7,7 @@ import lombok.Getter; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Assignment; +import javax.persistence.*; import java.util.List; import java.util.Map; import java.util.Optional; @@ -44,16 +45,20 @@ import java.util.stream.Collectors; * @version $Id: $Id * @since October 29, 2003 */ +@Entity public class LessonTracker { @Getter + @Id private String lessonName; + @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(); @Getter private int numberOfAttempts = 0; - protected LessonTracker() { - //Mongo + private LessonTracker() { + //JPA } public LessonTracker(AbstractLesson lesson) { diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserForm.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserForm.java index e5143704b..afcbd0615 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserForm.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserForm.java @@ -15,7 +15,7 @@ import javax.validation.constraints.Size; public class UserForm { @NotNull - @Size(min=6, max=10) + @Size(min=6, max=20) private String username; @NotNull @Size(min=6, max=10) diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserRepository.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserRepository.java index b836d5bfa..920109876 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserRepository.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserRepository.java @@ -1,6 +1,6 @@ package org.owasp.webgoat.users; -import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; @@ -8,7 +8,7 @@ import java.util.List; * @author nbaars * @since 3/19/17. */ -public interface UserRepository extends MongoRepository { +public interface UserRepository extends JpaRepository { WebGoatUser findByUsername(String username); 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 c139d2571..645b46258 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 @@ -5,8 +5,8 @@ import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Assignment; -import org.springframework.data.annotation.Id; +import javax.persistence.*; import java.util.List; import java.util.Map; import java.util.Optional; @@ -44,12 +44,16 @@ import java.util.stream.Collectors; * @since October 29, 2003 */ @Slf4j +@Entity public class UserTracker { @Id - private final String user; + private String user; + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private List lessonTrackers = Lists.newArrayList(); + private UserTracker() {} + public UserTracker(final String user) { this.user = user; } 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 f915154cb..a322f9d8a 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 @@ -1,12 +1,12 @@ package org.owasp.webgoat.users; -import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.jpa.repository.JpaRepository; /** * @author nbaars * @since 4/30/17. */ -public interface UserTrackerRepository extends MongoRepository { +public interface UserTrackerRepository extends JpaRepository { } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/WebGoatUser.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/WebGoatUser.java index b6e9fc776..23fcae34d 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/WebGoatUser.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/WebGoatUser.java @@ -1,13 +1,14 @@ package org.owasp.webgoat.users; import lombok.Getter; -import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.Transient; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Transient; import java.util.Collection; import java.util.Collections; @@ -16,6 +17,7 @@ import java.util.Collections; * @since 3/19/17. */ @Getter +@Entity public class WebGoatUser implements UserDetails { public static final String ROLE_USER = "WEBGOAT_USER"; diff --git a/webgoat-container/src/main/resources/application.properties b/webgoat-container/src/main/resources/application.properties index 8362f4290..83de9b5d7 100644 --- a/webgoat-container/src/main/resources/application.properties +++ b/webgoat-container/src/main/resources/application.properties @@ -4,6 +4,9 @@ server.session.timeout=600 server.contextPath=/WebGoat server.port=8080 +spring.datasource.url=jdbc:hsqldb:file:${webgoat.server.directory}/data/webgoat +spring.jpa.hibernate.ddl-auto=update + logging.level.org.springframework=WARN logging.level.org.springframework.boot.devtools=WARN @@ -28,22 +31,15 @@ webgoat.feedback.address.html=webgoat@owasp.org webgoat.database.driver=org.hsqldb.jdbcDriver webgoat.database.connection.string=jdbc:hsqldb:mem:{USER} webgoat.default.language=en -webgoat.embedded.mongo=${WG_INTERNAL_MONGO:true} -webwolf.port=8081 -webwolf.url=http://localhost:${webwolf.port}/WebWolf -webworf.url.landingpage=http://localhost:${webwolf.port}/landing -webworf.url.mail=http://localhost:${webwolf.port}/mail +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.mail=http://${webwolf.host}:${webwolf.port}/mail spring.jackson.serialization.indent_output=true spring.jackson.serialization.write-dates-as-timestamps=false -spring.activemq.brokerUrl=tcp://${WG_MQ_HOST:localhost}:${WG_MQ_PORT:61616} - -spring.data.mongodb.host=${WG_MONGO_HOST:localhost} -spring.data.mongodb.port=${WG_MONGO_PORT:27017} -spring.data.mongodb.database=webgoat -spring.mongodb.embedded.storage.databaseDir=${webgoat.user.directory}/mongodb/ - #For static file refresh ... and faster dev :D spring.devtools.restart.additional-paths=webgoat-container/src/main/resources/static/js,webgoat-container/src/main/resources/static/css 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 0ef51ad2d..65f45a63e 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 @@ -45,7 +45,6 @@ define(['jquery', this.$el.find('.attack-feedback').hide(); this.$el.find('.attack-output').hide(); this.makeFormsAjax(); - //this.ajaxifyAttackHref(); $(window).scrollTop(0); //work-around til we get the scroll down sorted out var startPageNum = this.model.get('pageNum'); this.initPagination(startPageNum); @@ -86,6 +85,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 successCallBackFunctionName = $(curForm).attr('successCallback'); + var failureCallbackFunctionName = $(curForm).attr('failureCallback'); var callbackFunction = (typeof webgoat.customjs[callbackFunctionName] === 'function') ? webgoat.customjs[callbackFunctionName] : function() {}; // var submitData = this.$form.serialize(); this.curForm = curForm; @@ -104,19 +105,18 @@ define(['jquery', //complete: function (data) { //callbackFunction(data); //} - }).then(self.onSuccessResponse.bind(self), self.onErrorResponse.bind(self)); + }).then(function(data){ + self.onSuccessResponse(data, failureCallbackFunctionName, successCallBackFunctionName)}, self.onErrorResponse.bind(self)); return false; }, - onSuccessResponse: function(data) { + onSuccessResponse: function(data, failureCallbackFunctionName, successCallBackFunctionName) { this.renderFeedback(data.feedback); this.renderOutput(data.output || ""); - var successCallBackFunctionName = this.$form.attr('successCallback'); - var failureCallbackFunctionName = this.$form.attr('failureCallback'); //var submitData = (typeof webgoat.customjs[prepareDataFunctionName] === 'function') ? webgoat.customjs[prepareDataFunctionName]() : $(curForm).serialize(); - successCallbackFunction = (typeof webgoat.customjs[successCallBackFunctionName] === 'function') ? webgoat.customjs[successCallBackFunctionName] : function() {}; - failureCallbackFunction = (typeof webgoat.customjs[failureCallbackFunctionName] === 'function') ? webgoat.customjs[failureCallbackFunctionName] : function() {}; + var successCallbackFunction = (typeof webgoat.customjs[successCallBackFunctionName] === 'function') ? webgoat.customjs[successCallBackFunctionName] : function() {}; + var failureCallbackFunction = (typeof webgoat.customjs[failureCallbackFunctionName] === 'function') ? webgoat.customjs[failureCallbackFunctionName] : function() {}; //TODO: refactor back assignmentCompleted in Java if (data.lessonCompleted || data.assignmentCompleted) { this.markAssignmentComplete(); @@ -146,14 +146,6 @@ define(['jquery', return false; }, - ajaxifyAttackHref: function() { // rewrite any links with hrefs point to relative attack URLs - var self = this; - // instruct in template to have links returned with the attack-link class - $('a.attack-link').submit(function(event){ - $.get(this.action, "json").then(self.onSuccessResponse, self.onErrorResponse); - }); - }, - renderFeedback: function(feedback) { this.$curFeedback.html(polyglot.t(feedback) || ""); this.$curFeedback.show(400) diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/plugins/TestConfig.java b/webgoat-container/src/test/java/org/owasp/webgoat/plugins/TestConfig.java deleted file mode 100644 index 5946104b4..000000000 --- a/webgoat-container/src/test/java/org/owasp/webgoat/plugins/TestConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.owasp.webgoat.plugins; - -import com.github.fakemongo.Fongo; -import com.mongodb.MongoClient; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.mongodb.config.AbstractMongoConfiguration; - -/** - * Using Fongo for embedded in memory MongoDB testing - */ -@Configuration -public class TestConfig extends AbstractMongoConfiguration { - - @Override - protected String getDatabaseName() { - return "test"; - } - - @Override - public MongoClient mongo() throws Exception { - return new Fongo(getDatabaseName()).getMongo(); - } -} \ No newline at end of file diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/users/UserRepositoryTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/users/UserRepositoryTest.java new file mode 100644 index 000000000..67b4d9bcf --- /dev/null +++ b/webgoat-container/src/test/java/org/owasp/webgoat/users/UserRepositoryTest.java @@ -0,0 +1,29 @@ +package org.owasp.webgoat.users; + +import org.assertj.core.api.Assertions; +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; + +@DataJpaTest +@RunWith(SpringRunner.class) +public class UserRepositoryTest { + + @Autowired + private UserRepository userRepository; + + @Test + public void userShouldBeSaved() { + WebGoatUser user = new WebGoatUser("test", "password"); + userRepository.saveAndFlush(user); + + user = userRepository.findByUsername("test"); + + Assertions.assertThat(user.getUsername()).isEqualTo("test"); + Assertions.assertThat(user.getPassword()).isEqualTo("password"); + } + + +} \ No newline at end of file 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 new file mode 100644 index 000000000..5c8092c13 --- /dev/null +++ b/webgoat-container/src/test/java/org/owasp/webgoat/users/UserTrackerRepositoryTest.java @@ -0,0 +1,101 @@ +package org.owasp.webgoat.users; + +import org.assertj.core.api.Assertions; +import org.assertj.core.util.Lists; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.owasp.webgoat.lessons.Assignment; +import org.owasp.webgoat.lessons.Category; +import org.owasp.webgoat.lessons.NewLesson; +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.util.List; + +@DataJpaTest +@RunWith(SpringRunner.class) +public class UserTrackerRepositoryTest { + + private class TestLesson extends NewLesson { + + @Override + public Category getDefaultCategory() { + return Category.AJAX_SECURITY; + } + + @Override + public List getHints() { + return Lists.newArrayList(); + } + + @Override + public Integer getDefaultRanking() { + return 12; + } + + @Override + public String getTitle() { + return "test"; + } + + @Override + public String getId() { + return "test"; + } + + @Override + public List getAssignments() { + Assignment assignment = new Assignment("test", "test", Lists.newArrayList()); + return Lists.newArrayList(assignment); + } + } + + @Autowired + private UserTrackerRepository userTrackerRepository; + + + @Test + public void saveUserTracker() { + UserTracker userTracker = new UserTracker("test"); + LessonTracker lessonTracker = userTracker.getLessonTracker(new TestLesson()); + + userTrackerRepository.save(userTracker); + + userTracker = userTrackerRepository.findOne("test"); + Assertions.assertThat(userTracker.getLessonTracker("test")).isNotNull(); + } + + @Test + public void solvedAssignmentsShouldBeSaved() { + UserTracker userTracker = new UserTracker("test"); + TestLesson lesson = new TestLesson(); + userTracker.getLessonTracker(lesson); + userTracker.assignmentFailed(lesson); + userTracker.assignmentFailed(lesson); + userTracker.assignmentSolved(lesson, "test"); + + userTrackerRepository.saveAndFlush(userTracker); + + userTracker = userTrackerRepository.findOne("test"); + Assertions.assertThat(userTracker.numberOfAssignmentsSolved()).isEqualTo(1); + } + + @Test + public void saveAndLoadShouldHaveCorrectNumberOfAttemtps() { + UserTracker userTracker = new UserTracker("test"); + TestLesson lesson = new TestLesson(); + userTracker.getLessonTracker(lesson); + userTracker.assignmentFailed(lesson); + userTracker.assignmentFailed(lesson); + userTrackerRepository.saveAndFlush(userTracker); + + userTracker = userTrackerRepository.findOne("test"); + userTracker.assignmentFailed(lesson); + userTracker.assignmentFailed(lesson); + userTrackerRepository.saveAndFlush(userTracker); + + Assertions.assertThat(userTracker.getLessonTracker(lesson).getNumberOfAttempts()).isEqualTo(4); + } + +} \ No newline at end of file diff --git a/webgoat-container/src/test/resources/application-test.properties b/webgoat-container/src/test/resources/application-test.properties index 3100e029a..a4e152215 100644 --- a/webgoat-container/src/test/resources/application-test.properties +++ b/webgoat-container/src/test/resources/application-test.properties @@ -1 +1,4 @@ -webgoat.user.directory=${java.io.tmpdir} \ No newline at end of file +webgoat.user.directory=${java.io.tmpdir} + +spring.datasource.url=jdbc:hsqldb:mem:test +spring.jpa.hibernate.ddl-auto=create-drop \ No newline at end of file diff --git a/webgoat-images/vagrant-training/Vagrantfile b/webgoat-images/vagrant-training/Vagrantfile new file mode 100644 index 000000000..d6c708fd5 --- /dev/null +++ b/webgoat-images/vagrant-training/Vagrantfile @@ -0,0 +1,35 @@ +# Setup a Linux box headless which will start WebGoat and WebWolf helpful image to give away during training + +Vagrant.configure(2) do |config| + config.vm.box = "ubuntu/trusty64" + config.vm.network :forwarded_port, guest: 8080, host: 8080 + config.vm.network :forwarded_port, guest: 8081, host: 8081 + config.vm.provider "virtualbox" do |vb| + vb.gui = false + vb.memory = "4096" + vb.cpus = 2 + vb.name = "WebGoat-Training" + 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-Training" + 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 + 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 & + sleep 40s + java -jar webwolf-8.0.0.M6.jar + SHELL + +end diff --git a/webgoat-lessons/auth-bypass/pom.xml b/webgoat-lessons/auth-bypass/pom.xml index fe1fca044..f0242337f 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-SNAPSHOT + 8.0.0.M3 diff --git a/webgoat-lessons/auth-bypass/src/main/resources/video/sample-video.m4v b/webgoat-lessons/auth-bypass/src/main/resources/video/sample-video.m4v deleted file mode 100644 index ff801f48b..000000000 Binary files a/webgoat-lessons/auth-bypass/src/main/resources/video/sample-video.m4v and /dev/null differ diff --git a/webgoat-lessons/bypass-restrictions/pom.xml b/webgoat-lessons/bypass-restrictions/pom.xml index 8775fdbd5..3d05db060 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-SNAPSHOT + 8.0.0.M3 diff --git a/webgoat-lessons/challenge/pom.xml b/webgoat-lessons/challenge/pom.xml index 04adf95cb..a35c0b48a 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-SNAPSHOT + 8.0.0.M3 diff --git a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge7/Assignment7.java b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge7/Assignment7.java index d7d5e20cf..2e12e14cc 100644 --- a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge7/Assignment7.java +++ b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge7/Assignment7.java @@ -45,7 +45,7 @@ public class Assignment7 extends AssignmentEndpoint { @Autowired private RestTemplate restTemplate; - @Value("${webworf.url.mail}") + @Value("${webwolf.url.mail}") private String webWolfMailURL; @GetMapping("/reset-password/{link}") diff --git a/webgoat-lessons/client-side-filtering/pom.xml b/webgoat-lessons/client-side-filtering/pom.xml index c44a2605f..6c7af20ab 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-SNAPSHOT + 8.0.0.M3 diff --git a/webgoat-lessons/cross-site-scripting/pom.xml b/webgoat-lessons/cross-site-scripting/pom.xml index c6043ff30..e4612dbe3 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-SNAPSHOT + 8.0.0.M3 diff --git a/webgoat-lessons/csrf/pom.xml b/webgoat-lessons/csrf/pom.xml index 3845faaa4..f3486e80e 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-SNAPSHOT + 8.0.0.M3 \ No newline at end of file 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 new file mode 100644 index 000000000..2fdce6958 --- /dev/null +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFFeedback.java @@ -0,0 +1,88 @@ +package org.owasp.webgoat.plugin; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.exception.ExceptionUtils; +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.UserSessionData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.Map; +import java.util.UUID; + +/** + * @author nbaars + * @since 11/17/17. + */ +@AssignmentPath("/csrf/feedback") +@AssignmentHints({"csrf-feedback-hint1", "csrf-feedback-hint2", "csrf-feedback-hint3"}) +public class CSRFFeedback extends AssignmentEndpoint { + + @Autowired + private UserSessionData userSessionData; + @Autowired + private ObjectMapper objectMapper; + + @PostMapping(value = "/message", produces = {"application/json"}) + @ResponseBody + public AttackResult completed(HttpServletRequest request, @RequestBody String feedback) { + try { + objectMapper.readValue(feedback.getBytes(), Map.class); + } catch (IOException e) { + return failed().feedback(ExceptionUtils.getStackTrace(e)).build(); + } + boolean correctCSRF = requestContainsWebGoatCookie(request.getCookies()) && request.getContentType().equals(MediaType.TEXT_PLAIN_VALUE); + correctCSRF &= hostOrRefererDifferentHost(request); + if (correctCSRF) { + String flag = UUID.randomUUID().toString(); + userSessionData.setValue("csrf-feedback", flag); + return success().feedback("csrf-feedback-success").feedbackArgs(flag).build(); + } + return failed().build(); + } + + @PostMapping(produces = "application/json") + @ResponseBody + public AttackResult flag(@RequestParam("confirmFlagVal") String flag) { + if (flag.equals(userSessionData.getValue("csrf-feedback"))) { + return trackProgress(success().build()); + } else { + return trackProgress(failed().build()); + } + } + + private boolean hostOrRefererDifferentHost(HttpServletRequest request) { + String referer = request.getHeader("referer"); + String host = request.getHeader("host"); + return !StringUtils.contains(referer, host); + } + + private boolean requestContainsWebGoatCookie(Cookie[] cookies) { + if (cookies != null) { + for (Cookie c : cookies) { + if (c.getName().equals("JSESSIONID")) { + return true; + } + } + } + return false; + } + + /** Solution +
+ +
+ + */ +} 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 new file mode 100644 index 000000000..97edff2c1 --- /dev/null +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFLogin.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.owasp.webgoat.assignments.AttackResult; +import org.owasp.webgoat.users.UserTracker; +import org.owasp.webgoat.users.UserTrackerRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * @author nbaars + * @since 11/17/17. + */ +@AssignmentPath("/csrf/login") +@AssignmentHints({"csrf-login-hint1", "csrf-login-hint2", "csrf-login-hint3"}) +public class CSRFLogin extends AssignmentEndpoint { + + @Autowired + private UserTrackerRepository userTrackerRepository; + + @PostMapping(produces = {"application/json"}) + @ResponseBody + public AttackResult completed() { + String userName = getWebSession().getUserName(); + if (userName.startsWith("csrf")) { + markAssignmentSolvedWithRealUser(userName.substring("csrf-".length())); + return trackProgress(success().feedback("csrf-login-success").build()); + } + return trackProgress(failed().feedback("csrf-login-failed").feedbackArgs(userName).build()); + } + + private void markAssignmentSolvedWithRealUser(String username) { + UserTracker userTracker = userTrackerRepository.findOne(username); + userTracker.assignmentSolved(getWebSession().getCurrentLesson(), this.getClass().getSimpleName()); + userTrackerRepository.save(userTracker); + } +} diff --git a/webgoat-lessons/csrf/src/main/resources/html/CSRF.html b/webgoat-lessons/csrf/src/main/resources/html/CSRF.html index b85568f08..0e56a7c31 100644 --- a/webgoat-lessons/csrf/src/main/resources/html/CSRF.html +++ b/webgoat-lessons/csrf/src/main/resources/html/CSRF.html @@ -2,62 +2,63 @@ -
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
+ + + +
+ +
+ +
+
+ +
+
- - + + Confirm Flag Value: + + +
-
- -
-
- -
-
- - Confirm Flag Value: - - - - -
- -
-
-
+
+
+
-
+
-
+
- - - + + + -
+
+
@@ -89,16 +90,17 @@ method="POST" name="review-form" successCallback="" action="/WebGoat/csrf/review"> - - - + + +
- - + +
    @@ -108,14 +110,144 @@
- +
+ +
+ +
+
+
+ +
+
+
+ +
+
+ + +
+
+
+
+
+
+
+
+
+
+ + +
+
+ +
+ + +
+
+
+ + +
+
+
+
+ + +
+
+
+ +
+
+
+
+
+
+
-
-
+
+
+ +
+
+ + Confirm Flag Value: + + + + +
+ +
+
- + +
+ +
+
+ +
+
+ +
+
+ + Press the button below when your are logged in as the other user
+ + + +
+ +
+
+
+
+ + +
+
+
+ + + \ No newline at end of file diff --git a/webgoat-lessons/csrf/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/csrf/src/main/resources/i18n/WebGoatLabels.properties index 84c269777..5571650f5 100644 --- a/webgoat-lessons/csrf/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/csrf/src/main/resources/i18n/WebGoatLabels.properties @@ -16,4 +16,17 @@ csrf-review.success=It appears you have submitted correctly from another site. G csrf-review-hint1=Again, you will need to submit from an external domain/host to trigger this action. While CSRF can often be triggered from the same host (e.g. via persisted payload), this doesn't work that way. csrf-review-hint2=Remember, you need to mimic the existing workflow/form. -csrf-review-hint3=This one has a weak anti-CSRF protection, but you do need to overcome (mimic) it \ No newline at end of file +csrf-review-hint3=This one has a weak anti-CSRF protection, but you do need to overcome (mimic) it + +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-invalid-json=Invalid JSON received. +csrf-feedback-success=Congratulations you have found the correct solution, the flag is: {0} + +csrf-login-hint1=First create a new account with csrf-username +csrf-login-hint2=Create a form which will log you in as this user (hint 1) and upload it to WebWolf +csrf-login-hint3=Visit this assignment again +csrf-login-success=Congratulations, now log out and login with your normal user account within WebGoat, remember the attacker knows you solved this assignment +csrf-login-failed=The solution is not correct, you are clicking the button while logged in as {0} \ No newline at end of file diff --git a/webgoat-lessons/csrf/src/main/resources/images/login-csrf.png b/webgoat-lessons/csrf/src/main/resources/images/login-csrf.png new file mode 100644 index 000000000..bdc982732 Binary files /dev/null and b/webgoat-lessons/csrf/src/main/resources/images/login-csrf.png differ diff --git a/webgoat-lessons/csrf/src/main/resources/js/feedback.js b/webgoat-lessons/csrf/src/main/resources/js/feedback.js new file mode 100644 index 000000000..242090c7b --- /dev/null +++ b/webgoat-lessons/csrf/src/main/resources/js/feedback.js @@ -0,0 +1,7 @@ +webgoat.customjs.feedback = function() { + var data = {}; + $('#csrf-feedback').find('input, textarea, select').each(function(i, field) { + data[field.name] = field.value; + }); + return JSON.stringify(data); +} 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 new file mode 100644 index 000000000..3e9f217c6 --- /dev/null +++ b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_ContentType.adoc @@ -0,0 +1,23 @@ +== CSRF and content-type + +In the previous section we saw how relying on the content-type is not a protection against +CSRF. In this section we will look into another way we can perform a CSRF attack against +a APIs which are not protected against CSRF. + +In this assignment you need to achieve to POST the following JSON message to our endpoints: + +[source] +---- +POST /csrf/feedback HTTP/1.1 + +{ + "name" : "WebGoat", + "email" : "webgoat@webgoat.org" + "content" : "WebGoat is the best!!" +} +---- + +More information can be found http://pentestmonkey.net/blog/csrf-xml-post-request[here] + +Remember you need to make the call from another origin (WebWolf can help here) and you need to be logged in into +WebGoat. \ No newline at end of file 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 new file mode 100644 index 000000000..dff9a78c1 --- /dev/null +++ b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Frameworks.adoc @@ -0,0 +1,22 @@ +=== Automatic support from frameworks + +Most frameworks now have default support for preventing CSRF. For example with Angular an interceptor reads a token +from a cookie by default XSRF-TOKEN and sets it as an HTTP header, X-XSRF-TOKEN. Since only code that runs on your domain +could read the cookie, the backend can be certain that the HTTP request came from your client application and not an attacker. + +In order for this to work the backend server sets the token in a cookie. As the value of the cookie should be read +by Angular (JavaScript) this cookie should not be marked with the http-only flag. On every request towards the server +Angular will put the token in the X-XSRF-TOKEN as a HTTP header. The server can validate whether those two tokens +match and this will ensure the server the request is running on the same domain. + +*Important: DEFINE A SEPARATE COOKIE, DO NOT REUSE THE SESSION COOKIE* + +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 +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. + + + + 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 new file mode 100644 index 000000000..bcf7be949 --- /dev/null +++ b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_JSON.adoc @@ -0,0 +1,46 @@ +**But I only have JSON APIs and no CORS enabled, how can those be susceptible to CSRF?** + +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 +request the browser will not make the call. + +To make a long answer short: this is *not* a valid protection against CSRF. + +One example why this protection is not enough can be found https://bugs.chromium.org/p/chromium/issues/detail?id=490015[here]. +Turns out `Navigator.sendBeacon()` was allowed to send POST request with an arbitrary content-type. + +[qoute, developer.mozilla.org] +____ +The navigator.sendBeacon() method can be used to asynchronously transfer a small amount of +data over HTTP to a web server. This method addresses the needs of analytics and diagnostics +code that typically attempts to send data to a web server prior to the unloading of the +document. Sending the data any sooner may result in a missed opportunity to gather data..." +____ + +{nbsp} + +For example: + +[source] +---- +function postBeacon() { + var data= new Blob([JSON.stringify({"author" :"WebGoat"})], {type : 'application/json'}); + navigator.sendBeacon("http://localhost:8083", data) +} +---- + +[quote, Eduardo Vela] +____ +I think Content-Type restrictions are useful for websites that are accidentally safe against CSRF. They are not meant to be, but they are because they happen to only accept XML or JSON payloads. + +That said, it's somewhat obvious the websites depending on this behavior should be fixed, and any reputable pentesters will point that out. The issue is whether it's the browser responsibility to act as a nanny to weak websites, or we should leave weak websites as sacrifice for great justice. Survival of the fittest. + +IMHO, the answer is somewhere in between, and a good first step would be to document all these Same Origin Policy gotchas that websites might depend upon for security. + +But wrt to this bug in specific, if it never got fixed, I don't think it would be the end of the world. But then again, on this day and age, maybe there's a way to launch nuclear missiles with a XML RPC interface, so maybe it would be the end of the world. +____ + +{nbsp} + +Both Firefox and Chrome fixed this issue, but it shows why you should implement a CSRF protection instead +of relying on the content-type of your APIs. \ No newline at end of file diff --git a/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Login.adoc b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Login.adoc new file mode 100644 index 000000000..ea480f495 --- /dev/null +++ b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Login.adoc @@ -0,0 +1,24 @@ +:blank: pass:[ +] + +== Login CSRF attack + +In a login CSRF attack, the attacker forges a login request to an honest site using the attacker’s username +and password at that site. If the forgery succeeds, the honest server responds with a `Set-Cookie` header +that instructs the browser to mutate its state by storing a session cookie, logging the user into +the honest site as the attacker. This session cookie is used to bind subsequent requests to the user’s session and hence +to the attacker’s authentication credentials. Login CSRF attacks can have serious consequences, for example +see the picture below where an attacker created an account at google.com the victim visits the malicious +website and the user is logged in as the attacker. The attacker could then later on gather information about +the activities of the user. + +{blank} + +image::images/login-csrf.png[caption="Figure: ", title="Login CSRF from Robust Defenses for Cross-Site Request Forgery", width="800", height="500", style="lesson-image" link="http://seclab.stanford.edu/websec/csrf/csrf.pdf"] + +{blank} +For more information read the following http://seclab.stanford.edu/websec/csrf/csrf.pdf[paper] + +In this assignment try to see if WebGoat is also vulnerable for a login CSRF attack. First create a user +based on your own username prefixed with csrf. So if your username is `tom` you must create +a new user called `csrf-tom` + diff --git a/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Reviews.adoc b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Reviews.adoc index 6fb15da4e..f3df9c4e6 100644 --- a/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Reviews.adoc +++ b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_Reviews.adoc @@ -1,9 +1,9 @@ == Post a review on someone else's behalf -The page below simulates a comment/review page. The difference here is that you have to inititate the submission elsewhere as you might +The page below simulates a comment/review page. The difference here is that you have to initiate the submission elsewhere as you might with a CSRF attack and like the previous exercise. It's easier than you think. In most cases, the trickier part is finding somewhere that you want to execute the CSRF attack. The classic example is account/wire transfers in someone's bank account. -But we're keepoing it simple here. In this case, you just need to trigger a review submission on behalf of the currently +But we're keeping it simple here. In this case, you just need to trigger a review submission on behalf of the currently logged in user. 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 new file mode 100644 index 000000000..98c44077f --- /dev/null +++ b/webgoat-lessons/csrf/src/test/java/org/owasp/webgoat/plugin/CSRFFeedbackTest.java @@ -0,0 +1,58 @@ +package org.owasp.webgoat.plugin; + +import org.hamcrest.core.StringContains; +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.setup.MockMvcBuilders; + +import javax.servlet.http.Cookie; + +import static org.hamcrest.core.Is.is; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * @author nbaars + * @since 11/17/17. + */ +@RunWith(SpringJUnit4ClassRunner.class) +public class CSRFFeedbackTest extends LessonTest { + + @Before + public void setup() throws Exception { + CSRF csrf = new CSRF(); + when(webSession.getCurrentLesson()).thenReturn(csrf); + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + when(webSession.getUserName()).thenReturn("unit-test"); + } + + @Test + public void postingJsonMessageThroughWebGoatShouldWork() throws Exception { + mockMvc.perform(post("/csrf/feedback/message") + .contentType(MediaType.APPLICATION_JSON) + .content("{\"name\": \"Test\", \"email\": \"test1233@dfssdf.de\", \"subject\": \"service\", \"message\":\"dsaffd\"}")) + .andExpect(status().isOk()); + } + + + @Test + 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("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/csrf/webgoat-lesson-template/getting-started.txt b/webgoat-lessons/csrf/webgoat-lesson-template/getting-started.txt deleted file mode 100644 index c0677c6b7..000000000 --- a/webgoat-lessons/csrf/webgoat-lesson-template/getting-started.txt +++ /dev/null @@ -1,55 +0,0 @@ -##### To include lesson template in build ##### -1. edit theh webgoat-server/pom.xml file and uncomment the section under ... - - -2. Also uncomment in webgoat-lessons/pom.xml where it says ... - - -##### To add a lesson to WebGoat ##### - -There are a number of moving parts and this sample lesson will help you navigate those parts. Most of your work will be done in two directories. To start though, you can copy this directory with the name of your-lesson in the webgoat-lessons directory. - -0. The POM file - a. change the ... - webgoat-lesson-template - ... line to give your lesson its own artifactId.That should be all you need to do there - -1. The Base Class ... - In webgoat-lessons/{your-lesson}/src/main/java, refactor the LessonTemplate.java class, changing ... - a. the category in which you want your lesson to be in. You can create a new category if you want, or put in an issue to have one added - b. The 'defaultRanking' will move your lesson up or down in the categories list - c. implement a new key name pair "lesson-template.title" (the key) and update the same key/value pair (your.key=your value) in src/main/resources/i18n/WebGoatLabels.properties - d. Implement a new value for the getId method, which leads us to ... - -2. The HTML content framing ... - a. Rename the provided file in src/main/resources/html using your value from the getId method in your lesson's base class (e.g. public String getId() { return "your-lesson"; } >> "your-lesson.html") - b. Modify that file following the commented instructions in there - c. In conjunction with this file you - -3. Assignment Endpoints - a. In the above html file, you will see an example of an 'attack form'. You can create endpoints to handle these attacks and provide the user feedback and simulated output. See the example file here as well as other existing lessons for ways to extend these. You will extend the AssignmentEndpoint as the example will show - b. You can also create supporting (non-assignment) endpoints, that are not evaluated/graded. - c. See other lesson examples for creating unit/integration tests for your project as well - - -4. Getting your lesson to show up - a. modify the webgoat-lessons/pom.xml to include your project in the section - - - webgoat-lesson-template - - - - b. modify the webgoat-server/pom.xml to add your project as a dependency in the section ... - - - -
-
- -
- - -
- -
- - -
-
- - - - - - 4128 3214 0002 1999 + +DOM-XSS ... + +// something like ... http://localhost:8080/WebGoat/start.mvc#test/testParam=foobar&_someVar=234902384lotslsfjdOf9889080GarbageHere%3Cscript%3Ewebgoat.customjs.phoneHome();%3C%2Fscript%3E +// or http://localhost:8080/WebGoat/start.mvc#test/testParam=foobar&_someVar=234902384lotslsfjdOf9889080GarbageHere