Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
Jason White
2017-10-11 20:29:47 -06:00
129 changed files with 4402 additions and 221 deletions

View File

@ -1,11 +1,24 @@
package org.owasp.webgoat;
import lombok.AllArgsConstructor;
import org.owasp.webgoat.login.LoginEvent;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.users.WebGoatUser;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;
import static java.util.Optional.empty;
import static java.util.Optional.of;
/**
* *************************************************************************************************
* <p>
@ -41,19 +54,38 @@ import org.springframework.web.servlet.ModelAndView;
* @since October 28, 2003
*/
@Controller
@AllArgsConstructor
public class HammerHead {
private final Course course;
public HammerHead(Course course) {
this.course = course;
}
private JmsTemplate jmsTemplate;
/**
* Entry point for WebGoat, redirects to the first lesson found within the course.
*/
@RequestMapping(path = "/attack", method = {RequestMethod.GET, RequestMethod.POST})
public ModelAndView attack() {
public ModelAndView attack(Authentication authentication, HttpServletRequest request, HttpServletResponse response) {
sendUserLoggedInMessage(request, response, authentication);
return new ModelAndView("redirect:" + "start.mvc" + course.getFirstLesson().getLink());
}
private void sendUserLoggedInMessage(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
WebGoatUser user = (WebGoatUser) authentication.getPrincipal();
getWebGoatCookie(request).ifPresent(c -> {
jmsTemplate.convertAndSend("webgoat", new LoginEvent(user.getUsername(), c.getValue()), m -> {
m.setStringProperty("type", LoginEvent.class.getSimpleName());
return m;
}
);
});
}
private Optional<Cookie> getWebGoatCookie(HttpServletRequest request) {
for (Cookie c : request.getCookies()) {
if (c.getName().equals("JSESSIONID")) {
return of(c);
}
}
return empty();
}
}

View File

@ -0,0 +1,35 @@
package org.owasp.webgoat;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.activemq.broker.BrokerService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;
/**
* @author nbaars
* @since 8/20/17.
*/
@Configuration
public class JmsConfig {
@Bean(initMethod = "start", destroyMethod = "stop")
public BrokerService broker() throws Exception {
final BrokerService broker = new BrokerService();
broker.addConnector("tcp://localhost:61616");
broker.addConnector("vm://localhost");
broker.setPersistent(false);
return broker;
}
@Bean
public MessageConverter jacksonJmsMessageConverter(ObjectMapper objectMapper) {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setObjectMapper(objectMapper);
converter.setTypeIdPropertyName("_type");
return converter;
}
}

View File

@ -39,11 +39,9 @@ import org.owasp.webgoat.session.LabelDebugger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
@ -154,13 +152,9 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
return slr;
}
@Bean
public HammerHead hammerHead(Course course) {
return new HammerHead(course);
}
@Bean
public LabelDebugger labelDebugger() {
return new LabelDebugger();
}
}

View File

@ -30,7 +30,6 @@
*/
package org.owasp.webgoat;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.Context;
import org.owasp.webgoat.plugins.PluginEndpointPublisher;
@ -49,10 +48,8 @@ import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletCon
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.io.File;
import java.util.Arrays;
@ -70,15 +67,6 @@ public class WebGoat extends SpringBootServletInitializer {
SpringApplication.run(WebGoat.class, args);
}
@Bean
@Primary
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.indentOutput(true);
builder.serializationInclusion(JsonInclude.Include.NON_NULL);
return builder;
}
@Bean(name = "pluginTargetDirectory")
public File pluginTargetDirectory(@Value("${webgoat.user.directory}") final String webgoatHome) {
return new File(webgoatHome);
@ -93,7 +81,7 @@ public class WebGoat extends SpringBootServletInitializer {
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public UserSessionData userSessionData() {
return new UserSessionData("test","data");
return new UserSessionData("test", "data");
}
@Bean

View File

@ -31,6 +31,7 @@
package org.owasp.webgoat;
import lombok.AllArgsConstructor;
import org.owasp.webgoat.login.LogoutHandler;
import org.owasp.webgoat.users.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@ -52,6 +53,7 @@ import org.springframework.security.core.userdetails.UserDetailsService;
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserService userDetailsService;
private final LogoutHandler logoutHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
@ -69,8 +71,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.passwordParameter("password")
.permitAll();
security.and()
.logout()
.permitAll();
.logout().deleteCookies("JSESSIONID").invalidateHttpSession(true)
.permitAll().logoutSuccessHandler(logoutHandler);
security.and().csrf().disable();
http.headers().cacheControl().disable();

View File

@ -108,4 +108,8 @@ public abstract class AssignmentEndpoint extends Endpoint {
protected AttackResult.AttackResultBuilder failed() {
return AttackResult.builder(messages).lessonCompleted(false).feedback("assignment.not.solved");
}
protected AttackResult.AttackResultBuilder informationMessage() {
return AttackResult.builder(messages).lessonCompleted(false);
}
}

View File

@ -0,0 +1,47 @@
package org.owasp.webgoat.login;
import lombok.AllArgsConstructor;
import org.owasp.webgoat.users.WebGoatUser;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Optional;
/**
* @author nbaars
* @since 8/20/17.
*/
@AllArgsConstructor
@Component
public class LogoutHandler extends SimpleUrlLogoutSuccessHandler {
private JmsTemplate jmsTemplate;
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
if (authentication != null) {
WebGoatUser user = (WebGoatUser) authentication.getPrincipal();
jmsTemplate.convertAndSend("webgoat", new LogoutEvent(user.getUsername()), m -> {
m.setStringProperty("type", LogoutEvent.class.getSimpleName());
return m;
});
}
super.onLogoutSuccess(httpServletRequest, httpServletResponse, authentication);
}
private Optional<Cookie> findSessionCookie(Cookie[] cookies) {
for (Cookie cookie : cookies) {
if ("JSESSIONID".equals(cookie.getName())) {
return Optional.of(cookie);
}
}
return Optional.empty();
}
}

View File

@ -71,6 +71,7 @@ public class PluginsLoader {
NewLesson lesson = null;
try {
lesson = (NewLesson) c.newInstance();
log.trace("Lesson loaded: {}", lesson.getId());
} catch (Exception e) {
log.error("Error while loading:" + c, e);
}

View File

@ -1,16 +1,16 @@
package org.owasp.webgoat.users;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
/**
@ -32,29 +32,16 @@ public class RegistrationController {
}
@PostMapping("/register.mvc")
public String registration(@ModelAttribute("userForm") @Valid UserForm userForm, BindingResult bindingResult) {
@SneakyThrows
public String registration(@ModelAttribute("userForm") @Valid UserForm userForm, BindingResult bindingResult, HttpServletRequest request) {
userValidator.validate(userForm, bindingResult);
if (bindingResult.hasErrors()) {
return "registration";
}
userService.addUser(userForm.getUsername(), userForm.getPassword());
autologin(userForm.getUsername(), userForm.getPassword());
request.login(userForm.getUsername(), userForm.getPassword());
return "redirect:/attack";
}
private void autologin(String username, String password) {
WebGoatUser user = userService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(user, password, user.getAuthorities());
authenticationManager.authenticate(usernamePasswordAuthenticationToken);
if (usernamePasswordAuthenticationToken.isAuthenticated()) {
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
log.debug("Login for {} successfully!", username);
}
}
}

View File

@ -45,10 +45,11 @@ public class Scoreboard {
}
private List<String> challengesSolved(UserTracker userTracker) {
List<String> challenges = Lists.newArrayList("Challenge1", "Challenge2", "Challenge3", "Challenge4", "Challenge5");
List<String> challenges = Lists.newArrayList("Challenge1", "Challenge2", "Challenge3", "Challenge4", "Challenge5", "Challenge6", "Challenge7", "Challenge8", "Challenge9");
return challenges.stream()
.map(c -> userTracker.getLessonTracker(c))
.filter(l -> l.isPresent()).map(l -> l.get())
.filter(l -> l.isLessonSolved())
.map(l -> l.getLessonName())
.map(l -> toLessonTitle(l))
.collect(Collectors.toList());

View File

@ -0,0 +1,21 @@
package org.owasp.webgoat.users;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
/**
* @author nbaars
* @since 8/15/17.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class UserSession {
private WebGoatUser webGoatUser;
@Id
private String sessionId;
}

View File

@ -29,7 +29,16 @@ webgoat.database.driver=org.hsqldb.jdbcDriver
webgoat.database.connection.string=jdbc:hsqldb:mem:{USER}
webgoat.default.language=en
webwolf.port=8081
webwolf.url=http://localhost:${webwolf.port}/WebWolf
webworf.url.landingpage=http://localhost:${webwolf.port}/landing
spring.jackson.serialization.indent_output=true
spring.jackson.serialization.write-dates-as-timestamps=false
spring.activemq.brokerUrl=tcp://localhost:61616
spring.data.mongodb.port=27017
spring.data.mongodb.database=webgoat
spring.mongodb.embedded.storage.databaseDir=${webgoat.user.directory}/mongodb/

View File

@ -1,15 +0,0 @@
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd">
<changeSet author="WebGoat" id="init_schema">
<createTable tableName="web_goat_user">
<column name="username" type="varchar(32)"/>
<column name="password" type="varchar(32)"/>
<column name="role" type="varchar(32)"/>
</createTable>
<addPrimaryKey columnNames="username" constraintName="pk_user" tableName="web_goat_user"/>
</changeSet>
</databaseChangeLog>

View File

@ -24,7 +24,7 @@
#
lesson.completed=Congratulations. You have successfully completed this lesson.
assignment.solved=Congratulations. You have successfully complete the assignment.
assignment.solved=Congratulations. You have successfully completed the assignment.
assignment.not.solved=Sorry the solution is not correct, please try again.
RestartLesson=Restart this Lesson
SolutionVideos=Solution Videos

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@ -1146,7 +1146,7 @@ div.captured-flag {
}
.appseceu-banner {
background: url('img/appseceu-17.png') no-repeat 0px 0px;
background: url('img/owasp_logo.jpg') no-repeat 0px 0px;
height: 117px;
width: 1268px;
margin-bottom: 20px;

View File

@ -1,5 +1,5 @@
<div class="scoreboard-title">WebGoat Challenge - AppSec EU 2017</div>
<div class="appseceu-banner">banner here</div>
<div class="scoreboard-title">WebGoat Challenge</div>
<div class="appseceu-banner"></div>
<table class="scoreboard-table">
<% _.each(rankings, function(userRanking, index) { %>
<tr>