|
| 1 | +# AI Coding Agent Guidelines: Firebase Phone Number Verification |
| 2 | + |
| 3 | +This document outlines crucial security constraints, robustness patterns, and layout formatting styles that must be followed when modifying or enhancing the Firebase Phone Number Verification component in this SDK. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## 🔒 Critical Security Rules |
| 8 | + |
| 9 | +### 1. Project-Specific Issuer Validation |
| 10 | +When verifying Phone Number Verification JWT tokens, **always explicitly validate the project ID in the issuer (`iss`) claim**. |
| 11 | +- Public keys are fetched from a global Google JWKS endpoint (`https://fpnv.googleapis.com/v1beta/jwks`) which returns signature keys for all valid tokens across all projects. |
| 12 | +- Failing to check that the token's issuer matches the application's specific project ID (`https://fpnv.googleapis.com/projects/[PROJECT_ID]`) will lead to a **cross-project token reuse vulnerability**. |
| 13 | + |
| 14 | +Ensure the following check remains intact during claim validation: |
| 15 | +```java |
| 16 | +String expectedIssuer = "https://fpnv.googleapis.com/projects/" + this.projectId; |
| 17 | +if (!expectedIssuer.equals(issuer)) { |
| 18 | + throw new FirebasePhoneNumberVerificationException( |
| 19 | + FirebasePhoneNumberVerificationErrorCode.INVALID_TOKEN, |
| 20 | + "Firebase Phone Number Verification token has an incorrect 'iss' (issuer) claim." |
| 21 | + ); |
| 22 | +} |
| 23 | +``` |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +## 🛡️ Robustness & Claim Type Safeguards |
| 28 | + |
| 29 | +### 2. Heterogeneous Map Types for Timestamps |
| 30 | +Do not cast numeric token claims (like `exp` or `iat`) directly to `java.util.Date` objects. When maps are instantiated from raw JSON objects or direct values, claims may be returned as numbers (`Long` or `Integer`). |
| 31 | +Always safely handle both types: |
| 32 | +```java |
| 33 | +Object exp = claims.get("exp"); |
| 34 | +if (exp instanceof java.util.Date) { |
| 35 | + return ((java.util.Date) exp).getTime() / 1000L; |
| 36 | +} |
| 37 | +return exp instanceof Number ? ((Number) exp).longValue() : 0L; |
| 38 | +``` |
| 39 | + |
| 40 | +--- |
| 41 | + |
| 42 | +## 🎨 Code Style & Checkstyle Compliance |
| 43 | + |
| 44 | +### 3. Strict 100-Character Line Limit |
| 45 | +This repository enforces standard Google Java Checkstyle constraints via Maven validation. **No line of code, Javadoc comment, or string concatenation string block may exceed 100 characters.** |
| 46 | +- When adding long exception text or assertion descriptions, break them up into contiguous segments or utilize line wraps. |
| 47 | +- Wrap deep generic types and anonymous lambda expressions inside test statements onto separate lines to stay well within the 100-character bounds. |
0 commit comments