Safeguard
Application Security•

CWE-38 Backslash Absolute Path Traversal Explained

CWE-38 is the backslash form of absolute path traversal. A short guide to what it is, where it hides and how to close it.

Safeguard Security Team
2 min read

CWE-38 describes a product that accepts input in the form of a backslash absolute path, \absolute\pathname\here, without appropriate validation. That can let an attacker reach unintended locations or read and write arbitrary files.

It is the Windows flavored sibling of CWE-37. The weakness is language independent. What matters is that the code or the operating system treats a backslash as a path separator, and that nobody checked.

How it happens

A filter written with Unix paths in mind often only looks at forward slashes. The attacker sends a backslash form instead and the file API on a Windows host accepts it. The record's examples:

  • A mail client allowed remote attackers to overwrite arbitrary files via an e-mail message containing a uuencoded attachment that specified the full pathname for the file (CVE-1999-1263).
  • Remote attackers could read arbitrary files via a full pathname in a config parameter (CVE-2003-0753).
  • Remote attackers could read arbitrary files via an absolute pathname (CVE-2002-1525).

These are old, but the shape has not changed. Attachment names, archive entries and request parameters all carry paths.

What an attacker gains

MITRE lists read access and modification of files and directories, so both confidentiality and integrity are affected.

How to find it

Static analysis can trace external input into file operations, per MITRE. Review any validation code and ask whether it handles both separators. Test file handling endpoints with backslash forms in a test environment.

How to fix it

Allowlist known good names, reject any separator character in a filename, then resolve the final path and confirm it sits inside the base directory. Never validate only the forward slash form.

from pathlib import Path

BASE = Path("C:/data/exports").resolve()

def safe_open(name: str):
    if "/" in name or "\\" in name or Path(name).is_absolute():
        raise ValueError("bad name")
    target = (BASE / name).resolve()
    if BASE not in target.parents:
        raise ValueError("outside base")
    return open(target, "rb")

Keep libraries that handle attachments and archives up to date. A free scan at gold.safeguard.sh/scan lists known issues in your dependency file without a login.

Quick check

Why is a forward slash check not enough?

Windows accepts backslash as a separator, so input in the form of a backslash absolute path passes a filter that only looks for forward slashes.

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.