Conditionally use request.remoteAddr instead of X-Forwarded-For

This commit is contained in:
Chris Eager
2023-11-22 17:05:50 -06:00
committed by Chris Eager
parent b1fd025ea6
commit a027c4ce1f
8 changed files with 48 additions and 16 deletions

View File

@@ -19,6 +19,7 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
@@ -27,6 +28,7 @@ import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
@@ -48,12 +50,15 @@ import org.whispersystems.textsecuregcm.util.HeaderUtils;
public class ChallengeController {
private final RateLimitChallengeManager rateLimitChallengeManager;
private final boolean useRemoteAddress;
private static final String CHALLENGE_RESPONSE_COUNTER_NAME = name(ChallengeController.class, "challengeResponse");
private static final String CHALLENGE_TYPE_TAG = "type";
public ChallengeController(final RateLimitChallengeManager rateLimitChallengeManager) {
public ChallengeController(final RateLimitChallengeManager rateLimitChallengeManager,
final boolean useRemoteAddress) {
this.rateLimitChallengeManager = rateLimitChallengeManager;
this.useRemoteAddress = useRemoteAddress;
}
@PUT
@@ -79,6 +84,7 @@ public class ChallengeController {
public Response handleChallengeResponse(@Auth final AuthenticatedAccount auth,
@Valid final AnswerChallengeRequest answerRequest,
@HeaderParam(HttpHeaders.X_FORWARDED_FOR) final String forwardedFor,
@Context HttpServletRequest request,
@HeaderParam(HttpHeaders.USER_AGENT) final String userAgent,
@Extract final ScoreThreshold captchaScoreThreshold,
@Extract final PushChallengeConfig pushChallengeConfig) throws RateLimitExceededException, IOException {
@@ -96,11 +102,13 @@ public class ChallengeController {
} else if (answerRequest instanceof AnswerRecaptchaChallengeRequest recaptchaChallengeRequest) {
tags = tags.and(CHALLENGE_TYPE_TAG, "recaptcha");
final String mostRecentProxy = HeaderUtils.getMostRecentProxy(forwardedFor).orElseThrow(() -> new BadRequestException());
final String remoteAddress = useRemoteAddress
? request.getRemoteAddr()
: HeaderUtils.getMostRecentProxy(forwardedFor).orElseThrow(BadRequestException::new);
boolean success = rateLimitChallengeManager.answerRecaptchaChallenge(
auth.getAccount(),
recaptchaChallengeRequest.getCaptcha(),
mostRecentProxy,
remoteAddress,
userAgent,
captchaScoreThreshold.getScoreThreshold());

View File

@@ -31,6 +31,7 @@ import java.util.Optional;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletionException;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.ws.rs.BadRequestException;
@@ -48,6 +49,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.ServerErrorException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@@ -116,6 +118,7 @@ public class VerificationController {
private final RateLimiters rateLimiters;
private final AccountsManager accountsManager;
private final boolean useRemoteAddress;
private final Clock clock;
public VerificationController(final RegistrationServiceClient registrationServiceClient,
@@ -125,6 +128,7 @@ public class VerificationController {
final RegistrationRecoveryPasswordsManager registrationRecoveryPasswordsManager,
final RateLimiters rateLimiters,
final AccountsManager accountsManager,
final boolean useRemoteAddress,
final Clock clock) {
this.registrationServiceClient = registrationServiceClient;
this.verificationSessionManager = verificationSessionManager;
@@ -133,6 +137,7 @@ public class VerificationController {
this.registrationRecoveryPasswordsManager = registrationRecoveryPasswordsManager;
this.rateLimiters = rateLimiters;
this.accountsManager = accountsManager;
this.useRemoteAddress = useRemoteAddress;
this.clock = clock;
}
@@ -194,10 +199,13 @@ public class VerificationController {
public VerificationSessionResponse updateSession(@PathParam("sessionId") final String encodedSessionId,
@HeaderParam(com.google.common.net.HttpHeaders.X_FORWARDED_FOR) String forwardedFor,
@HeaderParam(HttpHeaders.USER_AGENT) final String userAgent,
@Context HttpServletRequest request,
@NotNull @Valid final UpdateVerificationSessionRequest updateVerificationSessionRequest,
@NotNull @Extract final ScoreThreshold captchaScoreThreshold) {
final String sourceHost = HeaderUtils.getMostRecentProxy(forwardedFor).orElseThrow();
final String sourceHost = useRemoteAddress
? request.getRemoteAddr()
: HeaderUtils.getMostRecentProxy(forwardedFor).orElseThrow();
final Pair<String, PushNotification.TokenType> pushTokenAndType = validateAndExtractPushToken(
updateVerificationSessionRequest);