Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More robust path-traversal check in StaticFiles app #985

Merged
merged 5 commits into from Jul 16, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 6 additions & 6 deletions starlette/staticfiles.py
Expand Up @@ -107,12 +107,6 @@ async def get_response(self, path: str, scope: Scope) -> Response:
if scope["method"] not in ("GET", "HEAD"):
return PlainTextResponse("Method Not Allowed", status_code=405)

if path.startswith(".."):
# Most clients will normalize the path, so we shouldn't normally
# get this, but don't allow misbehaving clients to break out of
# the static files directory.
return PlainTextResponse("Not Found", status_code=404)

full_path, stat_result = await self.lookup_path(path)

if stat_result and stat.S_ISREG(stat_result.st_mode):
Expand Down Expand Up @@ -147,6 +141,12 @@ async def lookup_path(
) -> typing.Tuple[str, typing.Optional[os.stat_result]]:
for directory in self.all_directories:
full_path = os.path.join(directory, path)
if (
os.path.commonprefix([os.path.realpath(full_path), directory])
!= directory
):
# Don't allow misbehaving clients to break out of the static files directory.
continue
try:
stat_result = await aio_stat(full_path)
return (full_path, stat_result)
Expand Down