Safeguard
Application Security•

CWE-28 Path Traversal with '..\\filedir' on Windows Systems

Backslash dot-dot sequences are the native traversal on Windows and a bypass elsewhere. How CWE-28 works, with observed cases and a fix that handles both separators.

Safeguard Security Team
3 min read

CWE-28 is path traversal using ".." sequences. The product builds a pathname from external input that should stay inside a restricted directory, and does not neutralize ".." so the path can resolve outside it.

MITRE describes ".." as the canonical manipulation for operating systems that use the backslash as a directory separator, such as Windows. It is also useful for bypassing protection schemes that assume the forward slash is the only valid separator.

How it happens

Most traversal advice talks about "../". A developer protects against that, tests on a Linux laptop, and ships. On Windows the backslash form walks right through.

There are two ways the gap opens:

  • The service runs on Windows and the code never considered the native separator.
  • The service runs elsewhere, but a downstream component accepts backslashes and converts them, so a denylist of "/" misses what the component accepts.

MITRE lists several observed cases, all from the early 2000s, which shows how old the pattern is:

  • CVE-2002-0661: the backslash was not in a web server's denylist, allowing traversal when the server runs on Windows and other operating systems.
  • CVE-2002-0946: arbitrary files could be read through ".." sequences in an HTTP request.
  • CVE-2002-1042: a search engine for a web server allowed reading arbitrary files through ".." sequences in queries.
  • CVE-2002-1209: an FTP server allowed reading arbitrary files via ".." sequences in a GET request.

The age is the point. A weakness this well known still appears in new code because each new codebase has to learn it again.

What an attacker gains

The record lists reading files or directories and modifying files or directories. In the cases above the result was arbitrary file reads from web, search and FTP services.

How to find it

Static analysis can follow external input to file operations and show paths that reach them unresolved. When testing by hand, run every traversal test twice, once with slashes and once with backslashes, and also try mixed separators.

How to fix it

Treat both separators as separators, and let the platform resolve the path.

import java.nio.file.*;

Path base = Paths.get("C:/app/files").toRealPath();
Path target = base.resolve(userInput).normalize();
if (!target.startsWith(base)) {
    throw new SecurityException("path escapes base directory");
}

Path.startsWith compares path components, not raw text, so it avoids false matches. normalize removes the dot-dot parts before the comparison. For stronger protection against links, resolve the final target with toRealPath after confirming it exists.

Additional steps:

  1. Do not keep a denylist that lists only one separator.
  2. Prefer IDs that you map to file names on the server.
  3. Grant the service account access to the content directory and nothing else.
  4. Reject input containing separators when only a bare file name is expected.

Quick check

Why does a Linux tested filter fail on Windows?

It looks for "../" only. Windows treats the backslash as a separator, so ".." climbs directories while passing the filter.

Sources

Never miss an update

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

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.