flawopen.com/Path Traversal/Python os.path.join()
No, and there's a second Python-specific trap: if the second argument is an absolute path, os.path.join() discards the first argument entirely, which is an easy way to accidentally bypass an intended base directory completely.
os.path.join("/var/uploads", "/etc/passwd")
# returns "/etc/passwd" — the base
# directory is silently discardedfull = os.path.realpath(
os.path.join(base_dir, user_filename)
)
if not full.startswith(
os.path.realpath(base_dir) + os.sep
):
raise ValueError("Invalid path")../ sequences let a relative filename walk upward out of the intended directory, the same issue as in every language. Python's os.path.join() adds a second, distinct trap: if the untrusted value is itself an absolute path (starting with /), join() ignores every argument before it — a filename of /etc/passwd passed as the "filename" completely replaces the intended base directory, with no traversal sequence involved at all.
Yes — Path(base) / user_input has the identical absolute-path-discards-base behavior as os.path.join(). The same resolved-path verification is needed regardless of which API builds the path.