Safeguard
Application Security•

CWE-46 Trailing Space Path Equivalence and %20 Bypasses

A trailing space, or its encoded form %20, can make a server hand over source code. How CWE-46 works and how to prevent it.

Safeguard Security Team
3 min read

A space at the end of a filename is invisible in a log and easy to overlook in a rule. CWE-46 is path equivalence using a trailing space, as in filedir . The product accepts such input without appropriate validation, which leads to ambiguous path resolution.

It belongs to the same family as CWE-42, the trailing dot, under CWE-41. MITRE lists Web Based among the platforms, and the examples bear that out.

How it happens

On the web, a trailing space usually arrives as %20 in the URL. The server decodes it, then checks a rule against the string, or the check happens before decoding and the open happens after. In either order, the rule sees a name that does not match, while the file system treats the name with the space as the original file.

The record has four source disclosure cases using a trailing encoded space: CVE-2001-0693, CVE-2001-0778, CVE-2001-1248 and CVE-2004-0280. A request for a script with a space on the end produced the script text rather than its output. That is the same pattern as with trailing dots, which suggests the lesson is general: whenever an extension decides what happens to a file, every variant of the extension matters.

# Vulnerable: decode, then match the extension on the decoded string
name = unquote(request_path)               # "login.php " with trailing space
if name.endswith(".php"):
    run(name)
else:
    send_file(name)                        # source is sent

What an attacker gains

MITRE lists reading and modifying files and directories. In the examples the effect is disclosure of source, which exposes logic, comments and any secrets inside the code.

How to find it

In a test environment, request each executable resource with a trailing space and with %20, and compare to the clean request. Review any code that decides how to handle a file by its extension.

How to fix it

  • Canonicalize first, then decide.
  • Reject names that end or begin with whitespace.
  • Map extensions to handlers with a default of deny, not a default of send.
  • Keep source files outside the document root.
name = unquote(request_path)
if name != name.strip() or not ALLOWED.fullmatch(name):
    return deny()

Patch web servers and frameworks promptly. A free scan at gold.safeguard.sh/scan can show known issues in the dependencies you ship, no login.

Quick check

How does a space reach the server in a URL?

As the encoded sequence %20. After decoding it becomes a real trailing space, which some rules do not account for.

What was the usual impact in the record?

Source code disclosure, because the rule that would run the script did not match the altered name.

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.