Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Owasp zap #311

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

<properties>
<java.version>1.8</java.version>
<test_containers.version>1.19.0</test_containers.version>
<selenium.version>4.10.0</selenium.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -172,6 +174,57 @@
<version>1.0.0</version>
</dependency>

<!-- OWASP Zap begin -->
<dependency>
<groupId>com.redis.testcontainers</groupId>
<artifactId>testcontainers-redis</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.zaproxy</groupId>
<artifactId>zap-clientapi</artifactId>
<version>1.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>${selenium.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.asynchttpclient</groupId>
<artifactId>async-http-client</artifactId>
<version>2.12.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.7.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
<!-- OWASP Zap end -->

</dependencies>

<build>
Expand Down
54 changes: 34 additions & 20 deletions src/main/java/com/nonononoki/alovoa/component/AuthFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
Expand All @@ -12,24 +13,37 @@

public class AuthFilter extends UsernamePasswordAuthenticationFilter {

private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static final String CAPTCHA_ID = "captchaId";
private static final String CAPTCHA_TEXT = "captchaText";
public static final String REDIRECT_URL = "redirect-url";

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {

String username = request.getParameter(USERNAME);
String password = request.getParameter(PASSWORD);
long captchaId = Long.parseLong(request.getParameter(CAPTCHA_ID));
String captchaText = request.getParameter(CAPTCHA_TEXT);
request.getSession().setAttribute(REDIRECT_URL, request.getParameter(REDIRECT_URL));

AuthToken auth = new AuthToken(username, password, captchaId, captchaText);
AuthenticationManager am = this.getAuthenticationManager();
return am.authenticate(auth);
}
private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static final String CAPTCHA_ID = "captchaId";
private static final String CAPTCHA_TEXT = "captchaText";
public static final String REDIRECT_URL = "redirect-url";

@Value("${app.captcha.login.enabled}")
private String captchaLoginEnabled;

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
long captchaId;
String captchaText;

String username = request.getParameter(USERNAME);
String password = request.getParameter(PASSWORD);

if (Boolean.parseBoolean(captchaLoginEnabled)) {
captchaId = Long.parseLong(request.getParameter(CAPTCHA_ID));
captchaText = request.getParameter(CAPTCHA_TEXT);
} else {
captchaId = -1;
captchaText = null;
}

request.getSession().setAttribute(REDIRECT_URL, request.getParameter(REDIRECT_URL));

AuthToken auth = new AuthToken(username, password, captchaId, captchaText);
AuthenticationManager am = this.getAuthenticationManager();
return am.authenticate(auth);

}
}
25 changes: 17 additions & 8 deletions src/main/java/com/nonononoki/alovoa/component/AuthProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
Expand Down Expand Up @@ -37,7 +38,10 @@ public class AuthProvider implements AuthenticationProvider {

@Autowired
private PasswordEncoder passwordEncoder;


@Value("${app.captcha.login.enabled}")
private String captchaEnabled;

@SuppressWarnings("unused")
private static final Logger logger = LoggerFactory.getLogger(AuthProvider.class);

Expand All @@ -50,15 +54,20 @@ public Authentication authenticate(Authentication authentication) throws Authent
long captchaId = a.getCaptchaId();
String captchaText = a.getCaptchaText();

Captcha c = captchaRepo.findById(captchaId).orElse(null);
if (c == null) {
throw new BadCredentialsException("");
}
if (Boolean.parseBoolean(captchaEnabled)) {
logger.debug("Captcha enabled, so check captcha");
Captcha c = captchaRepo.findById(captchaId).orElse(null);
if (c == null) {
throw new BadCredentialsException("");
}

captchaRepo.delete(c);
captchaRepo.delete(c);

if (!c.getText().equalsIgnoreCase(captchaText)) {
throw new BadCredentialsException("");
if (!c.getText().equalsIgnoreCase(captchaText)) {
throw new BadCredentialsException("");
}
} else {
logger.debug("Captcha disabled, so we do not care about it");
}

User user = userRepo.findByEmail(email);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public class DeleteAccountResource {
@Value("${app.user.delete.duration.valid}")
private long accountDeleteDuration;

@Value("${app.captcha.delete.enabled}")
private String captchaDeleteEnabled;

@GetMapping("/delete-account/{tokenString}")
public ModelAndView deleteAccount(@PathVariable String tokenString) throws AlovoaException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException,
Expand All @@ -57,6 +60,7 @@ public ModelAndView deleteAccount(@PathVariable String tokenString) throws Alovo
active = true;
}
mav.addObject("active", active);
mav.addObject("captchaEnabled", Boolean.valueOf(captchaDeleteEnabled));

return mav;
}
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/nonononoki/alovoa/html/ImprintResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ public class ImprintResource {
@Value("${app.company.name}")
private String companyName;

@Value("${app.captcha.imprint.enabled}")
private String captchaImprintEnabled;

@GetMapping("/imprint")
public ModelAndView imprint() {

ModelAndView mav = new ModelAndView("imprint");
mav.addObject("companyName", companyName);
mav.addObject("captchaEnabled", Boolean.valueOf(captchaImprintEnabled));

return mav;
}
}
6 changes: 5 additions & 1 deletion src/main/java/com/nonononoki/alovoa/html/LoginResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ public class LoginResource {

@Value("${app.privacy.update-date}")
private String privacyDate;


@Value("${app.captcha.login.enabled}")
private String captchaEnabled;

public static final String URL = "/login";

@GetMapping(URL)
Expand All @@ -30,6 +33,7 @@ public ModelAndView login() throws AlovoaException {
}

ModelAndView mav = new ModelAndView("login");
mav.addObject("captchaEnabled", Boolean.valueOf(captchaEnabled));
return mav;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.nonononoki.alovoa.service.AuthService;
import com.nonononoki.alovoa.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand Down Expand Up @@ -34,13 +35,17 @@ public class PasswordResource {
@Autowired
private TextEncryptorConverter textEncryptor;

@Value("${app.captcha.password.enabled}")
private String captchaPasswordEnabled;

@GetMapping("/reset")
public ModelAndView passwordReset() throws AlovoaException, InvalidKeyException, IllegalBlockSizeException,
BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException,
UnsupportedEncodingException {
ModelAndView mav = new ModelAndView("password-reset");
User user = authService.getCurrentUser();
mav.addObject("user", UserDto.userToUserDto(user, user, userService, textEncryptor, UserDto.NO_MEDIA));
mav.addObject("captchaEnabled", Boolean.valueOf(captchaPasswordEnabled));
return mav;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.nonononoki.alovoa.html;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand All @@ -27,7 +28,10 @@ public class RegisterResource {

@Autowired
private AuthService authService;


@Value("${app.captcha.register.enabled}")
private String captchaRegisterEnabled;

public static final String URL = "/register";

@GetMapping(URL)
Expand All @@ -40,6 +44,7 @@ public ModelAndView register() throws AlovoaException {
ModelAndView mav = new ModelAndView("register");
mav.addObject("genders", genderRepo.findAll());
mav.addObject("intentions", userIntentionRepo.findAll());
mav.addObject("captchaRegisterEnabled", Boolean.parseBoolean(captchaRegisterEnabled));
return mav;
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/java/com/nonononoki/alovoa/model/RegisterDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ public class RegisterDto {

private boolean termsConditions;
private boolean privacy;

private String captchaText;
private long captchaId;
}
12 changes: 9 additions & 3 deletions src/main/java/com/nonononoki/alovoa/service/ImprintService.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.nonononoki.alovoa.entity.Contact;
Expand All @@ -24,11 +25,16 @@ public class ImprintService {
@Autowired
private ContactRepository contactRepo;

@Value("${app.captcha.imprint.enabled}")
private String captchaImprintEnabled;

public Contact contact(ContactDto dto)
throws UnsupportedEncodingException, NoSuchAlgorithmException, AlovoaException {
boolean isValid = captchaService.isValid(dto.getCaptchaId(), dto.getCaptchaText());
if (!isValid) {
throw new AlovoaException(publicService.text("backend.error.captcha.invalid"));
if (Boolean.parseBoolean(captchaImprintEnabled)) {
boolean isValid = captchaService.isValid(dto.getCaptchaId(), dto.getCaptchaText());
if (!isValid) {
throw new AlovoaException(publicService.text("backend.error.captcha.invalid"));
}
}

Contact c = new Contact();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,19 @@ public class PasswordService {
@Value("${app.user.password-reset.duration.valid}")
private int userPasswordResetDuration;

@Value("${app.captcha.password.enabled}")
private String captchaPasswordEnabled;

public UserPasswordToken resetPassword(PasswordResetDto dto)
throws AlovoaException, NoSuchAlgorithmException, MessagingException, IOException {

User u = authService.getCurrentUser();

if (u == null) {
if (!captchaService.isValid(dto.getCaptchaId(), dto.getCaptchaText())) {
throw new AlovoaException("captcha_invalid");
if (Boolean.parseBoolean(captchaPasswordEnabled)) {
if (!captchaService.isValid(dto.getCaptchaId(), dto.getCaptchaText())) {
throw new AlovoaException("captcha_invalid");
}
}
u = userRepo.findByEmail(Tools.cleanEmail(dto.getEmail()));

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/nonononoki/alovoa/service/RegisterService.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ public class RegisterService {
@Autowired
private TextEncryptorConverter textEncryptor;

@Value("${app.captcha.register.enabled}")
private String captchaRegisterEnabled;

private static final int MIN_PASSWORD_SIZE = 7;

private static final Logger logger = LoggerFactory.getLogger(RegisterService.class);
Expand All @@ -121,6 +124,13 @@ public String register(RegisterDto dto)
throw new AlovoaException("email_invalid");
}

if (Boolean.parseBoolean(captchaRegisterEnabled)) {
boolean isValid = captchaService.isValid(dto.getCaptchaId(), dto.getCaptchaText());
if (!isValid) {
throw new AlovoaException(publicService.text("backend.error.captcha.invalid"));
}
}

if (!profile.equals(Tools.DEV)) {
dto.setEmail(Tools.cleanEmail(dto.getEmail()));
if (plusAddressing && dto.getEmail().contains("+")) {
Expand Down
Loading