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

Respond with 400 instead of 500 when CSTG request validation fails #633

Merged
merged 3 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
34 changes: 14 additions & 20 deletions src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,10 @@ else if(emailHash != null) {
input = InputUtil.normalizePhoneHash(phoneHash);
}

if (checkTokenInput(input, rc)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (checkTokenInput) makes it seem like it succeeded. How about we rename this method to checkForInvalidTokenInput?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rename checkTokenInput to checkForInvalidTokenInput. true for invalid input, false for valid input.

return;
}

PrivacyBits privacyBits = new PrivacyBits();
privacyBits.setLegacyBit();
privacyBits.setClientSideTokenGenerate();
Expand Down Expand Up @@ -893,7 +897,7 @@ private void handleTokenRefreshV2(RoutingContext rc) {
private void handleTokenValidateV1(RoutingContext rc) {
try {
final InputUtil.InputVal input = this.phoneSupport ? getTokenInputV1(rc) : getTokenInput(rc);
if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) {
if (checkTokenInput(input, rc)) {
return;
}
if ((Arrays.equals(ValidateIdentityForEmailHash, input.getIdentityInput()) && input.getIdentityType() == IdentityType.Email)
Expand Down Expand Up @@ -924,7 +928,7 @@ private void handleTokenValidateV2(RoutingContext rc) {
final JsonObject req = (JsonObject) rc.data().get("request");

final InputUtil.InputVal input = getTokenInputV2(req);
if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) {
if (checkTokenInput(input, rc)) {
return;
}
if ((input.getIdentityType() == IdentityType.Email && Arrays.equals(ValidateIdentityForEmailHash, input.getIdentityInput()))
Expand Down Expand Up @@ -956,7 +960,7 @@ private void handleTokenGenerateV1(RoutingContext rc) {
try {
final InputUtil.InputVal input = this.phoneSupport ? this.getTokenInputV1(rc) : this.getTokenInput(rc);
platformType = getPlatformType(rc);
if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) {
if (checkTokenInput(input, rc)) {
return;
} else {
final IdentityTokens t = this.idService.generateIdentity(
Expand All @@ -983,7 +987,7 @@ private void handleTokenGenerateV2(RoutingContext rc) {
platformType = getPlatformType(rc);

final InputUtil.InputVal input = this.getTokenInputV2(req);
if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) {
if (checkTokenInput(input, rc)) {
return;
} else {
final String apiContact = getApiContact(rc);
Expand Down Expand Up @@ -1258,7 +1262,7 @@ private void handleBucketsV2(RoutingContext rc) {

private void handleIdentityMapV1(RoutingContext rc) {
final InputUtil.InputVal input = this.phoneSupport ? this.getTokenInputV1(rc) : this.getTokenInput(rc);
if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) {
if (checkTokenInput(input, rc)) {
return;
}
try {
Expand Down Expand Up @@ -1389,24 +1393,14 @@ private InputUtil.InputVal getTokenInputV1(RoutingContext rc) {

private boolean checkTokenInput(InputUtil.InputVal input, RoutingContext rc) {
if (input == null) {
ResponseUtil.ClientError(rc, "Required Parameter Missing: exactly one of email or email_hash must be specified");
return false;
} else if (!input.isValid()) {
ResponseUtil.ClientError(rc, "Invalid Identifier");
return false;
}
return true;
}

private boolean checkTokenInputV1(InputUtil.InputVal input, RoutingContext rc) {
if (input == null) {
ResponseUtil.ClientError(rc, "Required Parameter Missing: exactly one of [email, email_hash, phone, phone_hash] must be specified");
return false;
String message = this.phoneSupport ? "Required Parameter Missing: exactly one of [email, email_hash, phone, phone_hash] must be specified" : "Required Parameter Missing: exactly one of email or email_hash must be specified";
ResponseUtil.ClientError(rc, message);
return true;
} else if (!input.isValid()) {
ResponseUtil.ClientError(rc, "Invalid Identifier");
return false;
return true;
}
return true;
return false;
}

private InputUtil.InputVal[] getIdentityBulkInput(RoutingContext rc) {
Expand Down
28 changes: 28 additions & 0 deletions src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4162,6 +4162,34 @@ void cstgNoActiveKey(Vertx vertx, VertxTestContext testContext) throws NoSuchAlg
});
}

@ParameterizedTest
@CsvSource({
"email_hash,[email protected]",
"phone_hash,1234567890",
})
void cstgInvalidInput(String identityType, String rawUID, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException {
setupCstgBackend("cstg.co.uk");
setupKeys(true);

JsonObject identity = new JsonObject();
identity.put(identityType, getSha256(rawUID) + getSha256(rawUID));
identity.put("optout_check", 1);
Tuple.Tuple2<JsonObject, SecretKey> data = createClientSideTokenGenerateRequestWithPayload(identity, Instant.now().toEpochMilli(), null);

sendCstg(vertx,
"v2/token/client-generate",
"http://cstg.co.uk",
data.getItem1(),
data.getItem2(),
400,
testContext,
respJson -> {
assertFalse(respJson.containsKey("body"));
assertEquals("Invalid Identifier", respJson.getString("message"));
testContext.completeNow();
});
}

private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToken, RefreshToken refreshToken, int siteId, IdentityType identityType, String identity,
boolean expectClientSideTokenGenerateOptoutResponse) {
assertAreClientSideGeneratedTokens(advertisingToken,
Expand Down