Executive Summary
A critical authentication bypass vulnerability (CVE-2026-13447, CVSS 9.8) has been disclosed in MStore API – Create Native Android & iOS Apps On The Cloud, a WordPress plugin used to power mobile-app backends, affecting versions up to and including 4.20.0. The plugin's FirebasePhoneAuthHelper::verify_id_token() function decodes and checks JWT claims — algorithm, key ID, audience, issuer — but never verifies the token's cryptographic signature against Google's actual public keys.
CVSS Score: 9.8 (Critical, CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
The result: any attacker can generate their own RSA key pair, sign a Firebase-shaped JWT claiming to be any phone number, and have the plugin accept it as a legitimate, Google-issued credential.
Vulnerability Overview
| Attribute | Value |
|---|---|
| CVE ID | CVE-2026-13447 |
| CVSS Score | 9.8 (Critical) |
| Type | Improper Authentication (CWE-287) |
| Attack Vector | Network (no authentication required) |
| Privileges Required | None |
| User Interaction | None |
| Assigned By | Wordfence |
Root Cause
Firebase Phone Authentication is designed so that a client authenticates a phone number with Google, receives a signed ID token, and passes that token to the backend for verification. Verifying that token is supposed to mean checking it was actually signed by Google's certificate — via something like openssl_verify() against Google's published public keys.
MStore API's FirebasePhoneAuthHelper::verify_id_token() skips that step entirely. It decodes the JWT header and payload and validates surface-level claims (alg, kid, aud, iss), but it never calls a signature-verification function at all. A JWT that is structurally well-formed and carries the expected claim values is accepted regardless of who signed it — or whether it was signed by anything Google ever issued.
1. Attacker generates a self-signed RSA key pair
2. Attacker crafts a JWT with Firebase-shaped claims (alg, kid, aud, iss)
and a "phone_number" claim for any target account
3. Attacker signs the JWT with their own private key
4. Attacker submits the forged JWT to the MStore API auth endpoint
5. verify_id_token() checks claim shape but never validates the signature
6. Plugin treats the forged token as a valid Firebase-authenticated session
7. Attacker is logged in as — or provisions an account for — the target phone numberImpact of Successful Exploitation
| Impact | Description |
|---|---|
| Account Takeover | Impersonate any existing account tied to a phone number |
| Unauthorized Account Creation | Provision arbitrary new accounts via the mobile-app API |
| Full Auth Bypass | No credentials, OTP, or Firebase access required |
| Downstream API Abuse | Any store/API functionality gated behind login is exposed |
Remediation
As of publication, a patched release fixing the missing signature check had not yet been confirmed. Sites running MStore API should:
- Check for an update beyond 4.20.0 in the WordPress plugin repository and apply it immediately once available
- Disable Firebase Phone Auth in MStore API settings if the app doesn't strictly require it
- Restrict or monitor the auth endpoint at the WAF/reverse-proxy level for unusual JWT submission patterns
- Audit recent account activity for accounts created or logged into via phone-auth that don't match known users
# Via WP-CLI, once a fixed version is published
wp plugin update mstore-api
wp plugin get mstore-api --field=versionDetection Indicators
| Indicator | Description |
|---|---|
| Unusual phone-auth logins | Sessions established for numbers with no prior activity |
| New accounts via mobile API | Accounts created outside normal signup flow |
| Malformed or oddly-signed JWTs in logs | Tokens not matching Google's certificate key IDs |
References
- NIST NVD — CVE-2026-13447
- OffSeq Threat Radar — CVE-2026-13447 Analysis
- Wordfence Threat Intelligence — MStore API