-
Notifications
You must be signed in to change notification settings - Fork 31
Prevent parent directory access, custom Errors #49
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
Prevent parent directory access, custom Errors #49
Conversation
ab12bbc
to
a545ca7
Compare
9b9adfc
to
bef9f76
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked at the code, but did not test it running. @anecdata, would you have a chance to test this?
Can be explicitly provided in the constructor, in ``send()`` or | ||
implicitly determined from filename in ``send_file()``. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation builder should be able to use single backticks and produce cross references to other methods/functions here. Did that fail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had problems with single ticks as it often couldn't find the member in X in module Y, not entirely sure why
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a big deal; I've also found it doesn't work under strange circumstances.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dhalbert Are there any more changes that you would like me to include?
…parent-directory-access
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Baseline testing with adafruit_httpserver 2.5.0, which allows serving static files from the filesystem root_path
without a route. An explicit route will allow accessing a file outside of root_path
.
But also, it is possible using a TCP socket to access files outside of the root_path
without a route (by adding ../
to a path, for example). Thanks @Neradoc for identifying that in Discord. Typical browsers, and curl, filter that.
The current PR disallows ".." (and backslash) in a path. Tested successfully with:
Adafruit CircuitPython 8.1.0-beta.1-31-g4e25a4f6b on 2023-04-18; Adafruit QT Py ESP32S2 with ESP32S2
. It is still possible for the user to explicitly allow "/" as the root_path
.
LGTM
Thank you for testing @anecdata. Just a note. It is still also possible to do an explicit route to serve file outside |
@@ -15,14 +15,15 @@ | |||
from adafruit_httpserver.server import HTTPServer | |||
|
|||
|
|||
ssid, password = secrets.WIFI_SSID, secrets.WIFI_PASSWORD # pylint: disable=no-member | |||
ssid = os.environ.get("WIFI_SSID") | |||
password = os.environ.get("WIFI_PASSWORD") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested this out on a Feather S2 TFT and found that I had this error raised:
File "code.py", line 18, in <module>
AttributeError: 'module' object has no attribute 'environ'
I think maybe we don't have the environ
api and instead may need to use getenv like: os.getenv('WIFI_SSID')
I tried changing the code in one of the examples to use getenv instead and I was able to execute it successfully
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Is os.getenv('WIFI_SSID')
the standard for examples now for wifi connect not via web workflow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Is
os.getenv('WIFI_SSID')
the standard for examples now for wifi connect not via web workflow?
Seems that it is, https://docs.circuitpython.org/en/latest/docs/environment.html, although libs like adafruit_requests
or adafruit_minimqtt
still use secrets
in their example(s).
My bad for using the os.environ
, I wrongly assumed that it will work the same way as in Python, already fixed in the latest commit. Thanks for testing @FoamyGuy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we may need to use a slightly different API to access the environment vars.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me at this point.
I tested the latest version successfully on a Feather S2 TFT using the examples from this repo.
Thank you for merging. I see that teh changes were released under 3.0.0 and the 3.0.1. Considering I have some more changes, improvements, some of which are not backwards compatible it might be necessary to release that the as 4.0.0. Maybe it is better to do it this way as it might take some time to review and correct everything in incoming 4.0.0 PR. |
Updating https://github.com/adafruit/Adafruit_CircuitPython_AGS02MA to 1.0.4 from 1.0.3: > Merge pull request adafruit/Adafruit_CircuitPython_AGS02MA#3 from jposada202020/docs > Add upload url to release action > Add .venv to .gitignore > Update .pylintrc for v2.15.5 > Fix release CI files > Update pylint to 2.15.5 > Updated pylint version to 2.13.0 > Switching to composite actions Updating https://github.com/adafruit/Adafruit_CircuitPython_CLUE to 3.0.14 from 3.0.13: > Merge pull request adafruit/Adafruit_CircuitPython_CLUE#59 from julianaklulo/main > Add upload url to release action > Add .venv to .gitignore > Update .pylintrc for v2.15.5 > Fix release CI files > Update pylint to 2.15.5 > Updated pylint version to 2.13.0 > Switching to composite actions Updating https://github.com/adafruit/Adafruit_CircuitPython_EPD to 2.11.0 from 2.10.8: > Merge pull request adafruit/Adafruit_CircuitPython_EPD#61 from ladyada/master > Add upload url to release action > Add .venv to .gitignore > Update .pylintrc for v2.15.5 > Fix release CI files > Update pylint to 2.15.5 > Updated pylint version to 2.13.0 > Switching to composite actions Updating https://github.com/adafruit/Adafruit_CircuitPython_MCP2515 to 1.1.1 from 1.1.0: > Merge pull request adafruit/Adafruit_CircuitPython_MCP2515#18 from adafruit/use-core-message-rtr-classes Updating https://github.com/adafruit/Adafruit_CircuitPython_framebuf to 1.6.1 from 1.6.0: > Merge pull request adafruit/Adafruit_CircuitPython_framebuf#52 from steka/improve_font_to_bin Updating https://github.com/adafruit/Adafruit_CircuitPython_HTTPServer to 3.0.1 from 2.5.0: > Merge pull request adafruit/Adafruit_CircuitPython_HTTPServer#45 from foxy82/main > Merge pull request adafruit/Adafruit_CircuitPython_HTTPServer#49 from michalpokusa/prevent-parent-directory-access Updating https://github.com/adafruit/Adafruit_CircuitPython_Pixel_Framebuf to 1.1.10 from 1.1.9: > Merge pull request adafruit/Adafruit_CircuitPython_Pixel_Framebuf#9 from RossK1/adding_type_hints > Add upload url to release action > Add .venv to .gitignore > Update .pylintrc for v2.15.5 > Fix release CI files > Update pylint to 2.15.5 > Updated pylint version to 2.13.0 > Switching to composite actions Updating https://github.com/adafruit/Adafruit_CircuitPython_TinyLoRa to 2.2.13 from 2.2.12: > Merge pull request adafruit/Adafruit_CircuitPython_TinyLoRa#49 from awordforthat/issue47/fix-short-name-errors > Add upload url to release action > Add .venv to .gitignore Updating https://github.com/adafruit/Adafruit_CircuitPython_Bundle/circuitpython_library_list.md to NA from NA: > Updated download stats for the libraries
Part of v3 Milestone, contains some minor breaking changesIf possible, please do not make it a separate "Release"
This PR prevents accessing files outside root server directory, Previously, when there was a ".." in path it was possible to do that, which was unsecure as users could access files with configuration or secrets, or any other file.
All paths are now checked by default, whether they contain
".."
or"\"
(backslash) inside. if that is teh sace a403 Forbidden
is returned.In order to keep everything readable in clean, I intruduced custom exceptions, instead of raising e.g.
RunTimeError
orValueError
with a comment, nowInvalidPathError
orResponseAlreadySentError
.Server's
root_path
is now specified in constructor, not inserver_forever
orpool
methods.Some minor refactor to separate logic for diffrent smaller tasks inside
HTTPResponse
.Updated examples to use new constructor and to use
settings.toml
instead ofsecrets.py
.