Search code examples
pythonflaskip-address

How to limit access to Flask for a single IP address?


I'm developing a website using the Python Flask framework and I now do some devving, pushing my changes to a remote dev server. I set this remote dev server up to serve the website publically using app.run(host='0.0.0.0').

This works fine, but I just don't want other people to view my website yet. For this reason I somehow want to whitelist my ip so that the dev server only serves the website to my own ip address, giving no response, 404's or some other non-useful response to other ip addresses. I can of course set up the server to use apache or nginx to actually serve the website, but I like the automatic reloading of the website on code changes for devving my website

So does anybody know of a way to do this using the built in Flask dev server? All tips are welcome!


Solution

  • Using just the features of Flask, you could use a before_request() hook testing the request.remote_addr attribute:

    from flask import abort, request
    
    @app.before_request
    def limit_remote_addr():
        if request.remote_addr != '10.20.30.40':
            abort(403)  # Forbidden
    

    but using a firewall rule on the server is probably the safer and more robust option.

    Note that the Remote_Addr can be masked if there is a reverse proxy in between the browser and your server; be careful how you limit this and don't lock yourself out. If the proxy lives close to the server itself (like a load balancer or front-end cache), you can inspect the request.access_route list to access the actual IP address. Do this only if remote_addr itself is a trusted IP address too:

    trusted_proxies = ('42.42.42.42', '82.42.82.42', '127.0.0.1')
    
    def limit_remote_addr():
        remote = request.remote_addr
        route = list(request.access_route)
        while remote in trusted_proxies:
            remote = route.pop()
    
        if remote != '10.20.30.40':
            abort(403)  # Forbidden