The ajv npm package is a fast, standards-compliant JSON Schema validator that is safe for the vast majority of applications, provided you keep it patched and are careful with the $data option. It ships as a transitive dependency of thousands of tools, so understanding its risk profile is worthwhile even if you never import it directly.
This review covers what ajv does, the notable vulnerabilities that have affected it, and the configuration choices that keep validation from becoming an attack surface.
What Ajv Does and Why It Is Everywhere
Ajv, short for "Another JSON Schema Validator," compiles JSON Schema definitions into optimized JavaScript validation functions. Instead of interpreting a schema on every call, it generates code once and reuses it, which is why it is one of the fastest validators available.
That performance made it the default choice deep inside the toolchain. If you use ESLint, webpack, or a framework that validates configuration, you almost certainly have npm ajv installed transitively.
npm ls ajv
Run that in a real project and you will usually find several versions pulled in by different dependencies. This matters because a vulnerability in ajv is not something you can ignore just because you never wrote require("ajv") yourself.
import Ajv from "ajv";
const ajv = new Ajv();
const validate = ajv.compile({
type: "object",
properties: { email: { type: "string", format: "email" } },
required: ["email"],
additionalProperties: false,
});
if (!validate(input)) {
console.error(validate.errors);
}
Prototype Pollution: The Classic Ajv Risk
The most historically significant ajv vulnerability is prototype pollution, tracked as CVE-2020-15366. In affected versions, a carefully crafted schema could reach into Object.prototype and modify properties shared by every object in the runtime, which can escalate into denial of service or, in the wrong context, code execution. The fix landed in ajv 6.12.3, so any project pinned below that on the 6.x line should upgrade.
Prototype pollution is a recurring theme across the npm ecosystem, not a one-off. The takeaway is not "ajv is dangerous" but "validators that parse attacker-influenced schemas need to be current." If you accept schemas from users rather than shipping fixed schemas, treat that as a heightened-risk pattern regardless of the library.
ReDoS via the $data Option
A more recent issue is a regular-expression denial-of-service vulnerability, tracked as CVE-2025-69873, affecting ajv through version 8.17.1 when the $data option is enabled. With $data on, the pattern keyword can accept a regular expression supplied at runtime through a JSON Pointer reference, and that expression reaches the RegExp constructor without sanitization. An attacker who controls that value can supply a pathological pattern that pins a CPU core with catastrophic backtracking.
The practical mitigation is straightforward: only enable $data if you genuinely need runtime-referenced values, and never let untrusted input flow into the position that becomes a regex pattern. Most applications do not need $data at all, and it is off by default.
// Only enable this if you truly need runtime $data references
const ajv = new Ajv({ $data: true });
Always confirm the current fixed version against the ajv releases page and the NVD entry before you rely on a specific patch level, since advisories evolve.
Configuring Ajv Defensively
Good defaults turn ajv from a potential liability into a security control.
Set additionalProperties: false on object schemas so unexpected fields are rejected rather than silently accepted. This closes mass-assignment style problems where an attacker sends extra keys.
Use removeAdditional deliberately. Ajv can strip unknown properties, which is useful, but understand that stripping is not the same as rejecting; choose the behavior that matches your threat model.
Compile schemas once at startup, not per request. Beyond performance, compiling fixed schemas rather than user-supplied ones removes the entire class of schema-injection risk.
Keep strict mode on. Ajv's strict mode catches ambiguous or invalid schema constructs early, which reduces the chance of a schema behaving differently than you assume.
Keeping the Dependency Healthy
Because ajv usually arrives transitively, your defense is dependency management, not direct upgrades.
npm audit
npm outdated ajv
npm audit will surface known advisories, but it only sees what is in the advisory database and it can miss version ranges that resolve indirectly. A dedicated SCA tool such as Safeguard resolves the full transitive tree and can flag a vulnerable ajv brought in three levels deep by a build tool, which is exactly where manual review tends to miss it. Our software composition analysis product explains how that transitive resolution works in a CI gate.
The maintenance-status question is easy to answer here: ajv is actively maintained, with regular releases and prompt security fixes, so staying current is a matter of your own upgrade cadence rather than waiting on an abandoned project.
FAQ
Is the ajv npm package safe to use?
Yes, for the overwhelming majority of applications. Keep it on a patched version, avoid compiling schemas supplied by untrusted users, and leave the $data option off unless you specifically need it.
What is the most serious ajv vulnerability?
Historically, prototype pollution in versions before 6.12.3 (CVE-2020-15366) is the most cited. More recently a ReDoS issue affecting versions through 8.17.1 when $data is enabled (CVE-2025-69873) is worth patching against.
How do I check which version of npm ajv I have?
Run npm ls ajv to see every version in your dependency tree, including transitive copies pulled in by other packages. Then use npm audit or an SCA scanner to check them against known advisories.
Do I need to worry about ajv if I never imported it?
Possibly. Ajv is a common transitive dependency of build tools and frameworks, so it can be present even if you never installed it directly. Scan your full dependency tree rather than only your direct dependencies.