0

I was playing a CTF which was about path traversal. The server code was like below:

import flask
import os

app = flask.Flask(__name__)


@app.route("/docs/<path:path>", methods=["GET"])
def challenge(path="index.html"):
    print(path)
    requested_path = app.root_path + "/files/" + path
    try:
        return open(requested_path).read()
    except PermissionError:
        flask.abort(403, requested_path)
    except FileNotFoundError:
        flask.abort(404, f"No {requested_path} from directory {os.getcwd()}")
    except Exception as e:
        flask.abort(500, requested_path + ":" + str(e))


app.run("localhost", 3000)

The first and most obvious solution came to my mind was to request a url like http://localhost:3000/docs/../../flag. But it failed and the below was the corresponding log:

127.0.0.1 - - [03/Oct/2025 23:59:52] "GET /flag HTTP/1.1" 404 -

According to the log, my request is normalized/sanitized (not sure the correct word) and from /docs/../../flag has turned into /flag.

My question is at which stage my url has been normalized? I'm not using any webserver in the middle. Does flask's dev server perform any kind of normalization on the urls?

Note that I'm not seeking to find the solution for the CTF, I've solved it, my question is only about where is my url sanitized in the above code.

4
  • What client are you using to send http://localhost:3000/docs/../../flag? When I use a browser to send that request, it's the browser that performs the normalization before the GET request is sent. Commented Oct 3 at 21:20
  • @PresidentJamesK.Polk I'm using curl Commented Oct 3 at 21:25
  • Edit your question to include that information. Commented Oct 3 at 21:37
  • curl does URI normalization. Commented Oct 3 at 21:38

1 Answer 1

1

No, Flask doesn't normalize the URL in the posted code. In your case, it's the client curl. You can disable the normalization with the command line argument --path-as-is.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.