Safeguard
Security

@typescript-eslint/typescript-estree: A Security Review

A security review of @typescript-eslint/typescript-estree: what the parser does, where its real risk lives (its dependencies, not itself), and how to keep it safe.

Marcus Chen
DevSecOps Engineer
5 min read

@typescript-eslint/typescript-estree is the parser that turns TypeScript source into an ESLint-compatible syntax tree, and its security profile is unusual: the package itself has no known direct high-severity vulnerabilities, so its real risk lives in its dependencies and in how it is invoked. If you write TypeScript, you almost certainly run this code on every lint, whether you know it or not. Understanding where its risk actually sits keeps you from either ignoring it or worrying about the wrong thing.

What typescript-estree does

The typescript-eslint project bridges two worlds. ESLint expects an AST that follows the ESTree spec; the TypeScript compiler produces its own, different AST. @typescript-eslint/typescript-estree is the translation layer: it invokes the TypeScript compiler to parse your code, then converts the result into an ESTree-shaped tree that ESLint rules can walk.

It is a foundational package. The more familiar @typescript-eslint/parser wraps it, and the whole typescript-eslint rule ecosystem sits on top. Anyone linting TypeScript is running typescript-estree at the bottom of the stack, usually as a transitive dependency they never installed directly.

The good news, stated plainly

As of this review, public advisory databases do not list a direct, high-severity vulnerability in @typescript-eslint/typescript-estree itself. The typescript-eslint team is active, the package is heavily used and heavily scrutinized, and it is not the kind of code that handles untrusted network input at runtime in a typical setup. It is a developer-time build tool, not a request handler.

That matters for how you reason about it. A parser that runs on your own source code in CI has a smaller attack surface than a library that parses attacker-controlled input in production. The threat model is "could a malicious file I lint do something bad," and for a build tool run on your own repository that is a narrow window.

Where the real risk lives: dependencies

The interesting security question for typescript-estree is not the package but its dependency graph. Parsers of this kind pull in helper libraries, glob matchers, semver handling, and file-walking utilities, and those transitive dependencies have their own advisory histories. A vulnerability disclosed in one of them, a minimatch or semver issue, for instance, shows up as risk inherited through typescript-estree even though typescript-estree's own code is untouched.

This is the pattern to internalize: a package can be clean while its subtree is not. Checking only the top-level package for advisories misses inherited risk entirely. An SCA tool resolves the whole tree under typescript-estree and flags a vulnerable helper several levels down that no review of the parser's own source would surface. The remediation in those cases is almost always to update the parent (typescript-eslint) so it pulls the patched transitive versions, rather than patching typescript-estree directly.

The runtime consideration: parsing untrusted code

There is one scenario that changes the threat model. If you use typescript-estree outside the normal lint-your-own-code path, for example in a hosted service that parses TypeScript submitted by users, then you are feeding attacker-controlled input to a parser. Parsers can have denial-of-service edge cases where a pathological input consumes excessive CPU or memory.

If that is your use case, run the parser in a sandboxed, resource-limited worker with timeouts, treat parse failures as expected, and keep the package current so any DoS-class fixes reach you promptly. For the overwhelming majority of users who only lint their own repository, this does not apply.

Keeping it safe in practice

The practical guidance is short:

Keep typescript-eslint current. The project releases regularly and moves its transitive dependencies forward with it, so staying on a recent version is the cleanest way to inherit dependency fixes. Pin versions in a lockfile so your builds are reproducible and your scans reflect exactly what installs:

npm ls @typescript-eslint/typescript-estree

Run that to see which version resolved and via which path, then let your dependency scanner watch the subtree for newly disclosed advisories. Wire the scan into CI so a fresh advisory in a transitive dependency shows up as a failing build rather than a surprise months later. The Safeguard Academy has a short module on scanning developer-tooling dependencies, which teams often exclude from scans by mistake.

FAQ

Does @typescript-eslint/typescript-estree have known vulnerabilities?

As of this review, advisory databases list no direct high-severity vulnerability in the package itself. The realistic risk comes from its transitive dependencies, which have their own advisory histories, so scan the whole subtree rather than just the top-level package.

Is it dangerous that I run typescript-estree on every lint?

Not in the normal case. It is a build-time tool running on your own source in CI, which is a narrow attack surface. The threat model changes only if you use it to parse untrusted, user-submitted code at runtime.

How do I keep typescript-estree secure?

Keep typescript-eslint on a recent version so it carries forward patched transitive dependencies, pin everything in a lockfile, and run a dependency scan in CI so a new advisory anywhere in its subtree fails the build.

What if I parse user-supplied TypeScript with it?

Then treat it as parsing untrusted input: run it in a sandboxed worker with CPU and memory limits and timeouts, handle parse failures gracefully, and stay current on releases to pick up any denial-of-service fixes.

Never miss an update

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