11import os
2- import pathlib
32import stat
43import tempfile
54import time
5+ from pathlib import Path
66
77import anyio
88import pytest
@@ -28,13 +28,12 @@ def test_staticfiles(tmpdir, test_client_factory):
2828 assert response .text == "<file content>"
2929
3030
31- def test_staticfiles_with_pathlib (tmpdir , test_client_factory ):
32- base_dir = pathlib .Path (tmpdir )
33- path = base_dir / "example.txt"
31+ def test_staticfiles_with_pathlib (tmp_path : Path , test_client_factory ):
32+ path = tmp_path / "example.txt"
3433 with open (path , "w" ) as file :
3534 file .write ("<file content>" )
3635
37- app = StaticFiles (directory = base_dir )
36+ app = StaticFiles (directory = tmp_path )
3837 client = test_client_factory (app )
3938 response = client .get ("/example.txt" )
4039 assert response .status_code == 200
@@ -516,3 +515,36 @@ def test_staticfiles_disallows_path_traversal_with_symlinks(tmpdir):
516515
517516 assert exc_info .value .status_code == 404
518517 assert exc_info .value .detail == "Not Found"
518+
519+
520+ def test_staticfiles_avoids_path_traversal (tmp_path : Path ):
521+ statics_path = tmp_path / "static"
522+ statics_disallow_path = tmp_path / "static_disallow"
523+
524+ statics_path .mkdir ()
525+ statics_disallow_path .mkdir ()
526+
527+ static_index_file = statics_path / "index.html"
528+ statics_disallow_path_index_file = statics_disallow_path / "index.html"
529+ static_file = tmp_path / "static1.txt"
530+
531+ static_index_file .write_text ("<h1>Hello</h1>" )
532+ statics_disallow_path_index_file .write_text ("<h1>Private</h1>" )
533+ static_file .write_text ("Private" )
534+
535+ app = StaticFiles (directory = statics_path )
536+
537+ # We can't test this with 'httpx', so we test the app directly here.
538+ path = app .get_path ({"path" : "/../static1.txt" })
539+ with pytest .raises (HTTPException ) as exc_info :
540+ anyio .run (app .get_response , path , {"method" : "GET" })
541+
542+ assert exc_info .value .status_code == 404
543+ assert exc_info .value .detail == "Not Found"
544+
545+ path = app .get_path ({"path" : "/../static_disallow/index.html" })
546+ with pytest .raises (HTTPException ) as exc_info :
547+ anyio .run (app .get_response , path , {"method" : "GET" })
548+
549+ assert exc_info .value .status_code == 404
550+ assert exc_info .value .detail == "Not Found"
0 commit comments