Spaces in the middle of a filename sound like an annoyance, not a vulnerability. CWE-48 is path equivalence using internal whitespace, file name, where the product accepts such input without appropriate validation and ends up with ambiguous path resolution.
It sits in the same family as CWE-41. What makes the internal space case distinctive in the record is that it shows up in two very different ways.
How it happens
First, unquoted names. CVE-2000-0293 is recorded as filenames with spaces allowing arbitrary file deletion when the product does not properly quote them, with some overlap with path traversal. If a program builds a command line or a path list from a name and splits on whitespace, one filename becomes two arguments. A file called report final.txt turns into report and final.txt, and an attacker who names a file x /etc/important can point an operation at a path of their choosing.
Second, URL decoding. CVE-2001-1567 is a case where + characters in a query string were converted to spaces before a sensitive file or extension was checked, which let an attacker bypass access restrictions on the file. The access rule saw one string and the later step saw another.
# Vulnerable: shell string built from a name with spaces
import os
os.system("rm /srv/tmp/" + filename) # "a /etc/passwd" deletes two things
What an attacker gains
MITRE lists reading and modifying files and directories. The deletion example above shows integrity and availability impact, and the query string example shows access control bypass.
How to find it
Grep for code that builds shell commands or argument strings from filenames. Test endpoints with names that contain spaces and with + and %20 in the query string. Compare the access decision for each spelling against the plain name.
How to fix it
- Never build commands by string concatenation. Pass arguments as a list or use the language's file API directly.
- Apply access rules after URL decoding, never before.
- Validate names against an allowlist that excludes whitespace unless it is truly required.
import os
os.remove(os.path.join("/srv/tmp", filename)) # no shell, one path
If you must call an external program, pass the name as a separate argument, for example with subprocess.run(["rm", "--", path]), so it is never re-split.
Quick check
How can a space cause a deletion bug?
An unquoted name is split into several arguments by the shell or a parser, so the command acts on a path the attacker supplied inside the name.
What is the fix for the plus sign case?
Decode the query first, then run the access check on the decoded value, so the rule sees the same string the file layer will use.