Safeguard
Security

Mobile Number Validation in JavaScript: A Security-Aware Guide

Mobile number validation in JavaScript is easy to get wrong with a naive regex. Here is how to validate phone numbers correctly, safely, and without ReDoS.

Yukti Singhal
Platform Engineer
5 min read

Mobile number validation in JavaScript should be treated as a security control, not just a form-formatting nicety, which means validating on the server with a bounded pattern or a proper library rather than trusting a clever client-side regex. Phone-number fields feed SMS gateways, account recovery flows, and billing, so a weak validator is both a data-quality problem and a small attack surface.

This guide covers how to validate mobile numbers in JavaScript correctly, the traps that bite people, and where to draw the line between a quick regex and a real library.

Start with what you actually need

Before writing any pattern, decide what "valid" means for your application. A common mistake is trying to validate every phone number on earth with one regular expression. Numbering plans differ wildly by country in length, prefixes, and grouping. If you serve a single region, validate for that region. If you serve many, reach for a library that encodes the rules rather than inventing them.

A second decision: are you validating format or reachability? A regex confirms a string looks like a phone number. It cannot confirm the number is assigned or that a real handset will receive an SMS. Only a verification code sent to the number proves reachability. Keep those goals separate; do not expect a validator to do the verifier's job.

A safe basic pattern

For simple cases, normalize first, then validate. Strip formatting characters and validate the digits:

function validateMobile(raw) {
  if (typeof raw !== 'string') return false;
  // Keep a leading + and digits only
  const cleaned = raw.replace(/[\s().-]/g, '');
  // E.164-ish: optional +, then 8 to 15 digits
  return /^\+?[1-9]\d{7,14}$/.test(cleaned);
}

That pattern accepts the E.164 shape (a leading country code digit followed by up to 15 total digits), which is a reasonable superset for international numbers. It is deliberately simple and, importantly, it is not vulnerable to catastrophic backtracking.

The ReDoS trap

Here is the security-specific hazard that most phone-validation tutorials ignore. A regular expression with nested or overlapping quantifiers can be forced into exponential backtracking by a crafted input, hanging the thread that runs it. Because JavaScript regex on the main thread or the Node event loop is single-threaded, one malicious input can freeze request handling. That is a regular-expression denial-of-service, or ReDoS.

Patterns that combine ambiguous groups like (\d+)+ or (\d*)* are the danger. The safe pattern above avoids this by using a single character class with a bounded quantifier (\d{7,14}), which cannot backtrack pathologically. The rule of thumb: keep phone patterns linear and bounded, and never accept unbounded repetition of an overlapping group. If you inherit a validator with a suspicious nested quantifier, test it with long adversarial inputs and rewrite it.

Use a library when accuracy matters

For anything beyond a single-region best-effort check, use Google's libphonenumber via a JavaScript port such as libphonenumber-js:

import { isValidPhoneNumber } from 'libphonenumber-js';

const ok = isValidPhoneNumber('+14155552671', 'US');

The library knows real numbering plans, valid prefixes, and lengths per country, so it rejects strings that pass a naive regex but are not assignable numbers. It also parses and formats to E.164 for consistent storage. The trade-off is a dependency, which means you now own keeping it patched, but the accuracy gain over hand-rolled regex is substantial for multi-region apps.

Validate on the server, store canonically

Two closing rules that matter for security and data quality:

Server-side is the real validation. Client-side checks give users fast feedback, but an attacker posts straight to your API. Every rule that matters must run server-side on received data. A client regex that is not mirrored on the server is decoration.

Store in E.164. Normalize accepted numbers to the canonical +<countrycode><number> form before persisting. Consistent storage prevents duplicate accounts, makes lookups reliable, and keeps your SMS integration from choking on formatting variance.

Phone validation sits inside the broader discipline of input validation, and the same principles apply: prefer bounded patterns, validate at the trust boundary, and treat the parsing library as a dependency you keep current. If you use libphonenumber-js or any validation library, include it in your software composition analysis so a future advisory does not go unnoticed. The Safeguard academy covers input validation as a defensive layer more broadly.

FAQ

What is the best way to validate a mobile number in JavaScript?

For a single region, normalize the input and test it against a bounded pattern such as an E.164-style regex. For multiple regions or where accuracy matters, use libphonenumber-js, which encodes real numbering plans. Always enforce the check server-side, not only in the browser.

Can a phone-number regex cause a security problem?

Yes. A regex with nested or overlapping quantifiers can be pushed into exponential backtracking by a crafted input, freezing the single-threaded event loop in a ReDoS attack. Use bounded patterns like \d{7,14} with a single character class, and avoid ambiguous groups such as (\d+)+.

Does validating a mobile number confirm it is real?

No. A validator confirms the string is well-formed; it cannot confirm the number is assigned or reachable. Only sending a verification code to the number and receiving it back proves reachability. Keep format validation and reachability verification as separate steps.

Should I store phone numbers in a specific format?

Yes, normalize accepted numbers to E.164 (+<countrycode><number>) before storing. Canonical storage prevents duplicate accounts, makes lookups consistent, and keeps SMS and telephony integrations from failing on formatting differences.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.