Skip to content
Open
5 changes: 4 additions & 1 deletion .trivyignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ CVE-2025-64720 exp:2026-06-05
CVE-2025-65018 exp:2026-06-05

# UID2-6385
CVE-2025-66293 exp:2026-06-15
CVE-2025-66293 exp:2026-06-15

#for test
CVE-2025-68973 exp:2026-01-09
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.uid2</groupId>
<artifactId>uid2-optout</artifactId>
<version>4.7.5</version>
<version>4.7.8-alpha-155-SNAPSHOT</version>
<name>uid2-optout</name>
<url>https://github.com/IABTechLab/uid2-optout</url>

Expand Down
86 changes: 86 additions & 0 deletions src/main/java/com/uid2/optout/vertx/GenericFailureHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.uid2.optout.vertx;

import io.vertx.core.Handler;
import io.vertx.core.http.HttpClosedException;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.RoutingContext;
import org.apache.http.impl.EnglishReasonPhraseCatalog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GenericFailureHandler implements Handler<RoutingContext> {
private static final Logger LOGGER = LoggerFactory.getLogger(GenericFailureHandler.class);

@Override
public void handle(RoutingContext ctx) {
int statusCode = ctx.statusCode();
HttpServerResponse response = ctx.response();
String url = ctx.normalizedPath();
Throwable t = ctx.failure();

// Handle case where failure() is null (e.g., when rc.fail(401) is called without exception)
// In this case, just use the status code that was set
if (t == null) {
int finalStatusCode = statusCode == -1 ? 500 : statusCode;
if (finalStatusCode >= 500 && finalStatusCode < 600) {
LOGGER.error("URL: [{}] - Error response code: [{}]", url, finalStatusCode);
} else if (finalStatusCode >= 400 && finalStatusCode < 500) {
LOGGER.warn("URL: [{}] - Error response code: [{}]", url, finalStatusCode);
}
if (!response.ended() && !response.closed()) {
response.setStatusCode(finalStatusCode)
.end(EnglishReasonPhraseCatalog.INSTANCE.getReason(finalStatusCode, null));
}
return;
}

String errorMsg = t.getMessage();
String className = t.getClass().getName();

// Handle multipart method mismatch (IllegalStateException)
if (t instanceof IllegalStateException &&
errorMsg != null &&
errorMsg.equalsIgnoreCase(
"Request method must be one of POST, PUT, PATCH or DELETE to decode a multipart request")) {
if (!response.ended() && !response.closed()) {
response.setStatusCode(400).end(errorMsg);
}
LOGGER.warn("URL: [{}] - Multipart method mismatch - Error:", url, t);
return;
}

// Handle TooManyFormFieldsException
if (className.contains("TooManyFormFieldsException")) {
if (!response.ended() && !response.closed()) {
response.setStatusCode(400)
.end("Bad Request: Too many form fields");
}
LOGGER.warn("URL: [{}] - Too many form fields - Error:", url, t);
return;
}

// Handle HttpClosedException - ignore as it's usually caused by users and has no impact
if (t instanceof HttpClosedException) {
LOGGER.warn("Ignoring exception - URL: [{}] - Error:", url, t);
if (!response.ended() && !response.closed()) {
response.end();
}
return;
}

// Handle other exceptions based on status code
// If no status code was set, default to 500
int finalStatusCode = statusCode == -1 ? 500 : statusCode;

if (finalStatusCode >= 500 && finalStatusCode < 600) { // 5xx is server error, so error
LOGGER.error("URL: [{}] - Error response code: [{}] - Error:", url, finalStatusCode, t);
} else if (finalStatusCode >= 400 && finalStatusCode < 500) { // 4xx is user error, so just warn
LOGGER.warn("URL: [{}] - Error response code: [{}] - Error:", url, finalStatusCode, t);
}

if (!response.ended() && !response.closed()) {
response.setStatusCode(finalStatusCode)
.end(EnglishReasonPhraseCatalog.INSTANCE.getReason(finalStatusCode, null));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ private Router createRouter() {
//// if enabled, this would add handler for exposing prometheus metrics
// router.route("/metrics").handler(PrometheusScrapingHandler.create());

router.route().failureHandler(new GenericFailureHandler());

return router;
}

Expand Down
Loading