Merge remote-tracking branch 'upstream/develop' into develop
This commit is contained in:
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
@ -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/
|
||||
|
||||
|
@ -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>
|
@ -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 |
@ -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;
|
||||
|
@ -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>
|
||||
|
Reference in New Issue
Block a user