Safeguard
Application Security•

CWE-49 Trailing Slash Path Equivalence: Auth Bypass Cases

Append a slash to a URL and some servers return source code or skip authentication. How CWE-49 works and how to prevent it.

Safeguard Security Team
3 min read

Is /reports the same resource as /reports/? To a person, nearly. To a router, an access rule and a file system, it depends. CWE-49 is path equivalence using a trailing slash, filedir/, accepted without appropriate validation.

It belongs under CWE-41. MITRE lists web based platforms, and the examples are web servers.

How it happens

A rule is attached to one form of the path. Authentication might be configured for /private/file.html while the request arrives as /private/file.html/. A server may still resolve the request to the same file, so the rule never applies. The record lists these cases:

  • An application server allowed remote attackers to read source code for .jsp files by appending a / to the requested URL (CVE-2001-0446).
  • A bypass of Basic Authentication for files using a trailing / (CVE-2004-0334).
  • Reading sensitive files with a trailing / (CVE-2001-0893).
  • CVE-2002-0253, noted as overlapping with an information leak.

The shared cause is a gap between route matching, access control and file resolution. Each layer has its own idea of what the path is.

# Vulnerable: exact string match on the protected route
PROTECTED = {"/admin/export.csv"}
if request.path in PROTECTED and not user.is_admin:
    abort(403)
# "/admin/export.csv/" is not in the set but may still resolve

What an attacker gains

MITRE lists reading and modifying files and directories. The record shows source disclosure and authentication bypass, so expect exposed code and exposed data behind a login.

How to find it

Request every protected route with a trailing slash in a test environment and compare to the plain request. If the response differs in status or content, you have found a gap. Also check what your framework does with strict slash settings, as some redirect and some silently match both.

How to fix it

  • Normalize the path in one place, early, and make every later check use the normalized value.
  • Protect by prefix or by directory, not by exact string, so variants fall under the same rule.
  • Deny by default. Require authentication for the whole area and open specific routes on purpose.
  • Keep source and secrets outside the document root.
from posixpath import normpath
path = normpath(request.path)               # collapses trailing and repeated slashes
if path.startswith("/admin") and not user.is_admin:
    abort(403)

A free scan at gold.safeguard.sh/scan checks dependency files for known issues in your servers and frameworks, with no login.

Quick check

Why is protecting an exact path risky?

Variants such as a trailing slash do not match the exact string yet may resolve to the same file, so the rule is skipped.

What is a safer rule shape?

A prefix or directory based rule applied to the normalized path, with deny as the default.

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.