Skip to content

Commit 969fca5

Browse files
committed
security: enforce project-specific issuer validation in PhoneNumberVerification
1 parent 929335b commit 969fca5

2 files changed

Lines changed: 26 additions & 0 deletions

File tree

src/main/java/com/google/firebase/phonenumberverification/internal/FirebasePhoneNumberVerificationTokenVerifier.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ private void verifyClaims(JWTClaimsSet claims) throws FirebasePhoneNumberVerific
141141
"Firebase Phone Number Verification token has no 'iss' (issuer) claim.");
142142
}
143143

144+
String expectedIssuer = "https://fpnv.googleapis.com/projects/" + this.projectId;
145+
if (!expectedIssuer.equals(issuer)) {
146+
throw new FirebasePhoneNumberVerificationException(FirebasePhoneNumberVerificationErrorCode.INVALID_TOKEN,
147+
"Firebase Phone Number Verification token has an incorrect 'iss' (issuer) claim.");
148+
}
149+
144150
if (claims.getAudience().isEmpty() || !claims.getAudience().contains(issuer)) {
145151
throw new FirebasePhoneNumberVerificationException(FirebasePhoneNumberVerificationErrorCode.INVALID_TOKEN,
146152
"Invalid audience. Expected to contain: " + issuer + " but found: " + claims.getAudience()

src/test/java/com/google/firebase/phonenumberverification/internal/FirebasePhoneNumberVerificationTokenVerifierTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,4 +446,24 @@ public void testCreateJwtProcessor_HandlesException() throws Exception {
446446
assertTrue(cause.getCause() instanceof MalformedURLException);
447447
}
448448
}
449+
450+
@Test
451+
public void testVerifyToken_Claims_InvalidIssuerProject() throws Exception {
452+
JWTClaimsSet badIssuerClaims = new JWTClaimsSet.Builder()
453+
.issuer("https://fpnv.googleapis.com/projects/attacker-project-id")
454+
.audience("https://fpnv.googleapis.com/projects/attacker-project-id")
455+
.subject(subject)
456+
.expirationTime(new Date(System.currentTimeMillis() + 10000))
457+
.build();
458+
459+
String tokenString = createToken(header, badIssuerClaims);
460+
when(mockJwtProcessor.process(any(SignedJWT.class), any())).thenReturn(badIssuerClaims);
461+
462+
FirebasePhoneNumberVerificationException e = assertThrows(FirebasePhoneNumberVerificationException.class, () ->
463+
verifier.verifyToken(tokenString)
464+
);
465+
466+
assertEquals(FirebasePhoneNumberVerificationErrorCode.INVALID_TOKEN, e.getPhoneNumberVerificationErrorCode());
467+
assertTrue(e.getMessage().contains("incorrect 'iss' (issuer) claim"));
468+
}
449469
}

0 commit comments

Comments
 (0)