Safeguard
Vulnerabilities

CVE-2021-29425: The Commons IO Path Traversal Bug

CVE-2021-29425 shows how a single unhandled case in Apache Commons IO's path normalization let attackers slip past directory checks that assumed a canonicalized path was actually safe.

Safeguard Research Team
Research
4 min read

CVE-2021-29425 is a path traversal vulnerability in Apache Commons IO before version 2.7, affecting the FilenameUtils.normalize method. When passed an improperly formed input like a path beginning with //../ or \\..\, the method could return the same value unchanged, rather than correctly canonicalizing it — which meant code relying on normalize to sanitize a path before a security check could be tricked into treating a traversal payload as already safe.

Why does path normalization matter for security checks?

Path normalization matters because a lot of application code follows the same pattern: take a user-supplied filename, normalize it, then check whether the result stays inside an allowed directory before opening the file. If the normalization step itself doesn't correctly collapse traversal sequences like ../, the downstream check operates on a value that looks safe but isn't. Commons IO's FilenameUtils.normalize is exactly the kind of utility this pattern depends on — it's meant to be the trusted canonicalization step, so a bug in it undermines every security check built on top of it.

What made this specific input dangerous?

Specifically crafted inputs like //../foo or \\..\foo — with doubled leading separators before the traversal sequence — weren't correctly resolved by the vulnerable version, so the method returned a value that still contained an effective directory traversal rather than a properly normalized, contained path. An application that trusted this output as "already safe" and used it in a file-read or file-write operation could be tricked into accessing a location outside its intended directory. This is a subtle bug precisely because it only manifests on specific malformed inputs, not on ordinary traversal attempts, which is part of why it went unnoticed for a while.

How does this differ from other Commons libraries' vulnerabilities?

It's worth distinguishing this from unrelated CVEs in other Apache Commons projects — Commons Collections' deserialization issues, for instance, are a completely different vulnerability class (unsafe deserialization, not path handling) that happened to affect a library with a similar name. Teams doing dependency triage should confirm which specific Commons artifact and CVE they're looking at, since "Commons" covers dozens of separate libraries with independent release cycles and vulnerability histories, and conflating them leads to wasted remediation effort on the wrong artifact.

How would this get caught before shipping?

A software composition analysis scan against your dependency manifest flags the vulnerable Commons IO version directly, which is the fastest path to catching it — but pairing that with static analysis on how your own code actually uses FilenameUtils.normalize output tells you whether the vulnerable code path is reachable in your application at all. A codebase that pulls in Commons IO transitively but never calls normalize directly on user-controlled input carries the CVE on paper without the practical exploitability that would make it urgent.

How is it fixed?

Upgrade to Apache Commons IO 2.7 or later, where the normalization logic was corrected to properly resolve these malformed traversal sequences instead of passing them through unchanged.

FAQ

Does CVE-2021-29425 affect every application using Commons IO?

No — only code paths that call the vulnerable FilenameUtils.normalize method (directly or through another library that wraps it) on attacker-influenceable input are actually exploitable. Simply having the library as a transitive dependency doesn't guarantee reachability.

Is this the same issue as Commons Collections deserialization CVEs?

No, they're unrelated. Commons IO's CVE-2021-29425 is a path traversal issue in filename normalization; Commons Collections' well-known CVEs involve unsafe object deserialization — different libraries, different vulnerability classes.

What version of Commons IO fixes this?

Version 2.7 and later. Anything pinned to 2.6 or earlier remains affected.

Can a web application firewall mitigate this instead of upgrading?

A WAF might catch some obvious traversal payloads at the HTTP layer, but it's not a reliable substitute for fixing the underlying library, since the vulnerable normalization logic can be reached through paths a WAF signature doesn't anticipate.

Never miss an update

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