New lesson working

This commit is contained in:
Nanne Baars 2018-05-26 15:09:18 +02:00
parent eaf68d38c5
commit f8a7a61e85
16 changed files with 172 additions and 231 deletions

View File

@ -39,7 +39,7 @@ webgoat.default.language=en
webwolf.host=${WEBWOLF_HOST:localhost} webwolf.host=${WEBWOLF_HOST:localhost}
webwolf.port=${WEBWOLF_PORT:8081} webwolf.port=${WEBWOLF_PORT:8081}
webwolf.url=http://${webwolf.host}:${webwolf.port}/WebWolf webwolf.url=http://${webwolf.host}:${webwolf.port}/WebWolf
webworf.url.landingpage=http://${webwolf.host}:${webwolf.port}/landing webwolf.url.landingpage=http://${webwolf.host}:${webwolf.port}/landing
webwolf.url.mail=http://${webwolf.host}:${webwolf.port}/mail webwolf.url.mail=http://${webwolf.host}:${webwolf.port}/mail
spring.jackson.serialization.indent_output=true spring.jackson.serialization.indent_output=true

View File

@ -15,6 +15,4 @@ public interface SolutionConstants {
String PASSWORD_LARRY = "larryknows"; String PASSWORD_LARRY = "larryknows";
String JWT_PASSWORD = "victory"; String JWT_PASSWORD = "victory";
String ADMIN_PASSWORD_LINK = "375afe1104f4a487a73823c50a9292a2"; String ADMIN_PASSWORD_LINK = "375afe1104f4a487a73823c50a9292a2";
String PASSWORD_TOM_9 = "somethingVeryRandomWhichNoOneWillEverTypeInAsPasswordForTom";
String TOM_EMAIL = "tom@webgoat-cloud.org";
} }

View File

@ -1,39 +0,0 @@
package org.owasp.webgoat.plugin.challenge9;
import com.google.common.collect.Lists;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson;
import java.util.List;
/**
* @author nbaars
* @since 3/21/17.
*/
public class Challenge9 extends NewLesson {
@Override
public Category getDefaultCategory() {
return Category.CHALLENGE;
}
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 10;
}
@Override
public String getTitle() {
return "challenge9.title";
}
@Override
public String getId() {
return "Challenge9";
}
}

View File

@ -1,109 +0,0 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:Challenge_9.adoc"></div>
<script th:src="@{/lesson_js/challenge9.js}" language="JavaScript"></script>
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<div class="container-fluid">
<div class="row">
<div class="col-md-6">
<h4 style="border-bottom: 1px solid #c5c5c5;">
<i class="glyphicon glyphicon-user"></i>
Account Access
</h4>
<div style="padding: 20px;" id="form-login">
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/challenge/9/login"
enctype="application/json;charset=UTF-8" role="form">
<fieldset>
<div class="form-group input-group">
<span class="input-group-addon"> @ </span>
<input class="form-control" placeholder="Email" name="email" type="email"
required="" autofocus=""/>
</div>
<div class="form-group input-group">
<span class="input-group-addon">
<i class="glyphicon glyphicon-lock">
</i>
</span>
<input class="form-control" placeholder="Password" name="password" type="password"
value="" required=""/>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">
Access
</button>
<p class="help-block">
<a class="pull-right text-muted" href="#" id="login">
<small>Forgot your password?</small>
</a>
</p>
</div>
</fieldset>
</form>
</div>
<div style="display: none;" id="form-login">
<h4 class="">
Forgot your password?
</h4>
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/challenge/9/create-password-reset-link"
enctype="application/json;charset=UTF-8" role="form">
<fieldset>
<span class="help-block">
Email address you use to log in to your account
<br/>
We'll send you an email with instructions to choose a new password.
</span>
<div class="form-group input-group">
<span class="input-group-addon">
@
</span>
<input class="form-control" placeholder="Email" name="email" type="email"
required=""/>
</div>
<button type="submit" class="btn btn-primary btn-block" id="btn-login">
Continue
</button>
<p class="help-block">
<a class="text-muted" href="#" id="forgot">
<small>Account Access</small>
</a>
</p>
</fieldset>
</form>
</div>
</div>
</div>
</div>
<br/>
<form class="attack-form" method="POST" name="form" action="/WebGoat/challenge/flag">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"
style="font-size:20px"></i></div>
<input type="text" class="form-control" id="flag" name="flag"
placeholder="a7179f89-906b-4fec-9d99-f15b796e7208"/>
</div>
<div class="input-group" style="margin-top: 10px">
<button type="submit" class="btn btn-primary">Submit flag</button>
</div>
</div>
</form>
<br/>
<div class="attack-feedback"></div>
<div class="attack-output"></div>
</div>
</div>
</html>

View File

@ -1,10 +0,0 @@
$(document).ready(function() {
$('#login').click(function(e) {
e.preventDefault();
$('div#form-login').toggle('500');
});
$('#forgot').click(function(e) {
e.preventDefault();
$('div#form-login').toggle('500');
});
});

View File

@ -1,3 +0,0 @@
Tom always resets his password immediately after receiving the email with the link.
Try to reset the password of Tom (tom@webgoat-cloud.org) to your own choice and login as Tom with
that password.

View File

@ -1,4 +1,4 @@
package org.owasp.webgoat.plugin.challenge9; package org.owasp.webgoat.plugin.resetlink;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;

View File

@ -1,22 +1,16 @@
package org.owasp.webgoat.plugin.challenge9; package org.owasp.webgoat.plugin.resetlink;
import com.beust.jcommander.internal.Lists;
import com.beust.jcommander.internal.Maps;
import com.google.common.collect.EvictingQueue; import com.google.common.collect.EvictingQueue;
import lombok.extern.slf4j.Slf4j; import com.google.common.collect.Maps;
import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath; import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult; import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.plugin.Email; import org.owasp.webgoat.plugin.PasswordResetEmail;
import org.owasp.webgoat.users.UserRepository;
import org.owasp.webgoat.users.WebGoatUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
@ -26,25 +20,23 @@ import java.time.LocalDateTime;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import static org.owasp.webgoat.plugin.Flag.FLAGS;
import static org.owasp.webgoat.plugin.SolutionConstants.PASSWORD_TOM_9;
import static org.owasp.webgoat.plugin.SolutionConstants.TOM_EMAIL;
import static org.springframework.web.bind.annotation.RequestMethod.POST; import static org.springframework.web.bind.annotation.RequestMethod.POST;
/** /**
* @author nbaars * @author nbaars
* @since 4/8/17. * @since 8/20/17.
*/ */
@AssignmentPath("/challenge/9") @AssignmentPath("/PasswordReset/reset")
@Slf4j public class ResetLinkAssignment extends AssignmentEndpoint {
public class Assignment9 extends AssignmentEndpoint {
private static final String PASSWORD_TOM_9 = "somethingVeryRandomWhichNoOneWillEverTypeInAsPasswordForTom";
private static final String TOM_EMAIL = "tom@webgoat-cloud.org";
private static Map<String, String> userToTomResetLink = Maps.newHashMap(); private static Map<String, String> userToTomResetLink = Maps.newHashMap();
private static Map<String, String> usersToTomPassword = Maps.newHashMap(); private static Map<String, String> usersToTomPassword = Maps.newHashMap();
private static EvictingQueue resetLinks = EvictingQueue.create(1000); private static EvictingQueue resetLinks = EvictingQueue.create(1000);
private static final String TEMPLATE = "Hi, you requested a password reset link, please use this " + private static final String TEMPLATE = "Hi, you requested a password reset link, please use this " +
"<a target='_blank' href='http://%s/WebGoat/challenge/9/reset-password/%s'>link</a> to reset your password." + "<a target='_blank' href='http://%s/WebGoat/PasswordReset/reset/reset-password/%s'>link</a> to reset your password." +
"\n \n\n" + "\n \n\n" +
"If you did not request this password change you can ignore this message." + "If you did not request this password change you can ignore this message." +
"\n" + "\n" +
@ -52,12 +44,15 @@ public class Assignment9 extends AssignmentEndpoint {
"\n\n" + "\n\n" +
"Kind regards, \nTeam WebGoat"; "Kind regards, \nTeam WebGoat";
@Autowired private final RestTemplate restTemplate;
private RestTemplate restTemplate; private final String webWolfMailURL;
@Autowired private final String webwolfLandingURL;
private UserRepository userRepository;
@Value("${webwolf.url}") public ResetLinkAssignment(RestTemplate restTemplate, @Value("${webwolf.url.mail}") String webWolfMailURL, @Value("${webwolf.url.landingpage}") String webwolfLandingURL) {
private String webWolfURL; this.restTemplate = restTemplate;
this.webWolfMailURL = webWolfMailURL;
this.webwolfLandingURL = webwolfLandingURL;
}
@RequestMapping(method = POST, value = "/create-password-reset-link") @RequestMapping(method = POST, value = "/create-password-reset-link")
@ResponseBody @ResponseBody
@ -65,7 +60,7 @@ public class Assignment9 extends AssignmentEndpoint {
String resetLink = UUID.randomUUID().toString(); String resetLink = UUID.randomUUID().toString();
resetLinks.add(resetLink); resetLinks.add(resetLink);
String host = request.getHeader("host"); String host = request.getHeader("host");
if (StringUtils.hasText(email)) { if (org.springframework.util.StringUtils.hasText(email)) {
if (email.equals(TOM_EMAIL) && host.contains("8081")) { //User indeed changed the host header. if (email.equals(TOM_EMAIL) && host.contains("8081")) { //User indeed changed the host header.
userToTomResetLink.put(getWebSession().getUserName(), resetLink); userToTomResetLink.put(getWebSession().getUserName(), resetLink);
fakeClickingLinkEmail(cookie, host, resetLink); fakeClickingLinkEmail(cookie, host, resetLink);
@ -77,18 +72,15 @@ public class Assignment9 extends AssignmentEndpoint {
} }
private void sendMailToUser(@RequestParam String email, String host, String resetLink) { private void sendMailToUser(@RequestParam String email, String host, String resetLink) {
String username; int index = email.indexOf("@");
WebGoatUser webGoatUser = userRepository.findByUsername(email.substring(0, email.indexOf("@"))); String username = email.substring(0, index == -1 ? email.length() : index);
if (webGoatUser != null) { PasswordResetEmail mail = PasswordResetEmail.builder()
username = webGoatUser.getUsername(); .title("Your password reset link")
Email mail = Email.builder() .contents(String.format(TEMPLATE, host, resetLink))
.title("Your password reset link for challenge 9") .sender("password-reset@webgoat-cloud.net")
.contents(String.format(TEMPLATE, host, resetLink)) .recipient(username)
.sender("password-reset@webgoat-cloud.net") .time(LocalDateTime.now()).build();
.recipient(username) restTemplate.postForEntity(webWolfMailURL, mail, Object.class);
.time(LocalDateTime.now()).build();
restTemplate.postForEntity(webWolfURL + "/WebWolf/mail", mail, Object.class);
}
} }
/** /**
@ -98,11 +90,9 @@ public class Assignment9 extends AssignmentEndpoint {
*/ */
private void fakeClickingLinkEmail(String cookie, String host, String resetLink) { private void fakeClickingLinkEmail(String cookie, String host, String resetLink) {
try { try {
HttpHeaders httpHeaders = new HttpHeaders(); HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.put(HttpHeaders.COOKIE, Lists.newArrayList("JSESSIONID=" + cookie));
HttpEntity httpEntity = new HttpEntity(httpHeaders); HttpEntity httpEntity = new HttpEntity(httpHeaders);
new RestTemplate().exchange(String.format("http://%s/challenge/9/reset-password/%s", host, resetLink), HttpMethod.GET, httpEntity, Void.class); new RestTemplate().exchange(String.format("http://%s/PasswordReset/reset/reset-password/%s", host, resetLink), HttpMethod.GET, httpEntity, Void.class);
} catch (Exception e) { } catch (Exception e) {
//don't care //don't care
} }
@ -116,7 +106,7 @@ public class Assignment9 extends AssignmentEndpoint {
if (passwordTom.equals(PASSWORD_TOM_9)) { if (passwordTom.equals(PASSWORD_TOM_9)) {
return failed().feedback("login_failed").build(); return failed().feedback("login_failed").build();
} else if (passwordTom.equals(password)) { } else if (passwordTom.equals(password)) {
return success().feedback("challenge.solved").feedbackArgs(FLAGS.get(9)).build(); return success().feedback("challenge.solved").feedbackArgs("test").build();
} }
} }
return failed().feedback("login_failed.tom").build(); return failed().feedback("login_failed.tom").build();
@ -137,7 +127,7 @@ public class Assignment9 extends AssignmentEndpoint {
@PostMapping("/change-password") @PostMapping("/change-password")
public String changePassword(@ModelAttribute("form") PasswordChangeForm form, BindingResult bindingResult) { public String changePassword(@ModelAttribute("form") PasswordChangeForm form, BindingResult bindingResult) {
if (!StringUtils.hasText(form.getPassword())) { if (!org.springframework.util.StringUtils.hasText(form.getPassword())) {
bindingResult.rejectValue("password", "not.empty"); bindingResult.rejectValue("password", "not.empty");
} }
if (bindingResult.hasErrors()) { if (bindingResult.hasErrors()) {
@ -156,6 +146,4 @@ public class Assignment9 extends AssignmentEndpoint {
String resetLink = userToTomResetLink.getOrDefault(getWebSession().getUserName(), "unknown"); String resetLink = userToTomResetLink.getOrDefault(getWebSession().getUserName(), "unknown");
return resetLink.equals(resetLinkFromForm); return resetLink.equals(resetLinkFromForm);
} }
} }

View File

@ -111,7 +111,8 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label>What is your favorite color?</label> <label>What is your favorite color?</label>
<input class="form-control" placeholder="Answer security question" type="text" name="securityQuestion"/> <input class="form-control" placeholder="Answer security question" type="text"
name="securityQuestion"/>
</div> </div>
<div class="form-group"> <div class="form-group">
<button type="submit" class="btn btn-primary btn-block"> Submit</button> <button type="submit" class="btn btn-primary btn-block"> Submit</button>
@ -130,5 +131,108 @@
</div> </div>
</div> </div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:PasswordReset_host_header.adoc"></div>
<div class="attack-container">
<img th:src="@{/images/wolf-enabled.png}" class="webwolf-enabled"/>
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<h4 style="border-bottom: 1px solid #c5c5c5;">
<i class="glyphicon glyphicon-user"></i>
Account Access
</h4>
<div style="padding: 20px;" id="password-login">
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/PasswordReset/reset/login"
enctype="application/json;charset=UTF-8" role="form">
<fieldset>
<div class="form-group input-group">
<span class="input-group-addon"> @ </span>
<input class="form-control" placeholder="Email" name="email" type="email"
required="" autofocus=""/>
</div>
<div class="form-group input-group">
<span class="input-group-addon">
<i class="glyphicon glyphicon-lock">
</i>
</span>
<input class="form-control" placeholder="Password" name="password" type="password"
value="" required=""/>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">
Access
</button>
<p class="help-block">
<a class="pull-right text-muted" href="#" onclick="showPasswordReset()">
<small>Forgot your password?</small>
</a>
</p>
</div>
</fieldset>
</form>
</div>
<div style="display: none;" id="password-reset">
<h4 class="">
Forgot your password?
</h4>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/PasswordReset/reset/create-password-reset-link"
enctype="application/json;charset=UTF-8" role="form">
<fieldset>
<span class="help-block">
Email address you use to log in to your account
<br/>
We'll send you an email with instructions to choose a new password.
</span>
<div class="form-group input-group">
<span class="input-group-addon">
@
</span>
<input class="form-control" placeholder="Email" name="email" type="email"
required=""/>
</div>
<button type="submit" class="btn btn-primary btn-block" id="btn-login">
Continue
</button>
<p class="help-block">
<a class="text-muted" href="#" onclick="showPassword()">
<small>Account Access</small>
</a>
</p>
</fieldset>
</form>
</div>
</div>
</div>
</div>
<br/>
<form class="attack-form" method="POST" name="form" action="/WebGoat/challenge/flag">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"
style="font-size:20px"></i></div>
<input type="text" class="form-control" id="flag" name="flag"
placeholder="a7179f89-906b-4fec-9d99-f15b796e7208"/>
</div>
<div class="input-group" style="margin-top: 10px">
<button type="submit" class="btn btn-primary">Submit flag</button>
</div>
</div>
</form>
<br/>
<div class="attack-feedback"></div>
<div class="attack-output"></div>
</div>
</div>
</html> </html>

View File

@ -7,3 +7,13 @@ password-reset-simple.email_mismatch=Of course you can send mail to user {0} how
password-questions-wrong-user=You need to find a different user you are logging in with 'webgoat'. password-questions-wrong-user=You need to find a different user you are logging in with 'webgoat'.
password-questions-unknown-user=User {0} is not a valid user. password-questions-unknown-user=User {0} is not a valid user.
password-reset-no-user=Please supply a valid e-mail address.
password-reset-solved=Congratulations you solved the assignment, please type in the following code in the e-mail field: {0}
password-reset-not-solved=Sorry but you did not redirect the reset link to WebWolf
password-reset-hint1=Try to send a password reset link to your own account at {user}@webgoat.org, you can read this e-mail in WebWolf.
password-reset-hint2=Look at the link, can you think how the server creates this link?
password-reset-hint3=Tom clicks all the links he receives in his mailbox, you can use the landing page in WebWolf to get the reset link...
password-reset-hint4=The link points to localhost:8080/PasswordReset/.... can you change the host to localhost:8081
password-reset-hint5=Intercept the request and change the host header

View File

@ -7,4 +7,16 @@ $(document).ready(function() {
e.preventDefault(); e.preventDefault();
$('div#form-olvidado').toggle('500'); $('div#form-olvidado').toggle('500');
}); });
}); });
function showPasswordReset() {
console.log("clicking")
$('#password-reset').show();
$('#password-login').hide();
}
function showPassword() {
console.log("clicking")
$('#password-login').show();
$('#password-reset').hide();
}

View File

@ -12,6 +12,7 @@ The time out is necessary to restrict the attack window, having a link opens up
== Assignment == Assignment
In this assignment Tom uses the password reset functionality, can you try to find a way to e-mail the password Tom always resets his password immediately after receiving the email with the link.
reset link to your own inbox at user@webwolf.org. Use WebWolf to read the email and paste the token in the box Try to reset the password of Tom (tom@webgoat-cloud.org) to your own choice and login as Tom with
below. that password. If you did submit is in the e-mail address and submit again.

View File

@ -9,16 +9,8 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-xs-12 col-sm-8 col-md-6 col-sm-offset-2 col-md-offset-3"> <div class="col-xs-12 col-sm-8 col-md-6 col-sm-offset-2 col-md-offset-3">
<form role="form" method="POST" action="/WebGoat/challenge/9/change-password" th:object="${form}"> <form role="form" method="POST" action="/WebGoat/PasswordReset/reset/change-password" th:object="${form}">
<h2 class="sign_up_title">Reset your password</h2> <h2 class="sign_up_title">Reset your password</h2>
<!--<div class="form-group" th:classappend="${#fields.hasErrors('email')}? 'has-error'">-->
<!--<div class="form-group">-->
<!--<label for="email" class="control-label">Email</label>-->
<!--<input autofocus="dummy_for_thymeleaf_parser" type="text" class="form-control"-->
<!--th:field="*{email}"-->
<!--id="email" placeholder="email" name='email'/>-->
<!--<span th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Email error</span>-->
<!--</div>-->
<div class="form-group" th:classappend="${#fields.hasErrors('password')}? 'has-error'"> <div class="form-group" th:classappend="${#fields.hasErrors('password')}? 'has-error'">
<input type="hidden" name="resetLink" th:field="*{resetLink}" /> <input type="hidden" name="resetLink" th:field="*{resetLink}" />
<label for="password" class="control-label" th:text="#{password}">Password</label> <label for="password" class="control-label" th:text="#{password}">Password</label>
@ -26,14 +18,6 @@
name='password' th:value="*{password}"/> name='password' th:value="*{password}"/>
<span th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Password error</span> <span th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Password error</span>
</div> </div>
<!---->
<!--<div class="form-group">-->
<!--<input type="email" required="" autofocus="" name="email" id="email" class="form-control input-lg" placeholder="Email"-->
<!--tabindex="4"/>-->
<!--<input type="newPassword" required="" autofocus="" name="newPassword" id="newPassword" class="form-control input-lg" placeholder="New password"-->
<!--tabindex="4"/>-->
<!--</div>-->
<div class="row"> <div class="row">
<div class="col-xs-12 col-md-12"> <div class="col-xs-12 col-md-12">
<button type="submit" class="btn btn-success btn-block btn-lg">Save</button> <button type="submit" class="btn btn-success btn-block btn-lg">Save</button>

View File

@ -20,6 +20,7 @@ import java.util.*;
public class WebWolfTraceRepository implements TraceRepository { public class WebWolfTraceRepository implements TraceRepository {
private final EvictingQueue<Trace> traces = EvictingQueue.create(10000); private final EvictingQueue<Trace> traces = EvictingQueue.create(10000);
private List<String> exclusionList = Lists.newArrayList("/WebWolf/mail","/WebWolf/files", "/login", "/favicon.ico", "/js/", "/webjars/", "/WebWolf/requests", "/css/");
@Override @Override
public List<Trace> findAll() { public List<Trace> findAll() {
@ -33,11 +34,15 @@ public class WebWolfTraceRepository implements TraceRepository {
return Lists.newArrayList(traces); return Lists.newArrayList(traces);
} }
private boolean isInExclusionList(String path) {
return exclusionList.stream().anyMatch(e -> path.contains(e));
}
@Override @Override
public void add(Map<String, Object> map) { public void add(Map<String, Object> map) {
Optional<String> host = getFromHeaders("host", map); Optional<String> host = getFromHeaders("host", map);
String path = (String) map.getOrDefault("path", ""); String path = (String) map.getOrDefault("path", "");
if (host.isPresent() && path.contains("/landing")) { if (host.isPresent() && !isInExclusionList(path)) {
traces.add(new Trace(new Date(), map)); traces.add(new Trace(new Date(), map));
} }
} }