1

Chrome warns:

A site requested a resource from a network that it could only access because of its users' privileged network position. These requests expose devices and servers to the internet, increasing the risk of a cross-site request forgery (CSRF) attack, and/or information leakage. To mitigate these risks, Chrome will require non-public subresources to opt-into being accessed with a preflight request and will start blocking them in Chrome 101 (April 2022). To fix this issue, ensure that response to the preflight request for the private network resource has the Access-Control-Allow-Private-Network header set to true.

I am using flask, but unsure how to add this header to the preflight check. I can add a header to the responses manually, but how to add a header to the preflight check?

I am using Flask-Cors and this is the code:

app = Flask(__name__)
cors = CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'
run_the_race
  • 1,344
  • 2
  • 36
  • 62
  • I don't think Flask-Cors allows you to configure a server for Private Network Access yet. My question would be: Is it legitimate for that site to access that server only accessible on a more private network? What's the use case, exactly? – jub0bs Mar 25 '22 at 20:46
  • The use case is its a terminal, there's a python web service running locally on the terminal, that reveals certain info to the website, i.e. its serial number, the software version, the temperature of the device, and various other parameters for monitoring it. The whole purpose of the local web service is to expose data to the main online site via an API. Out of interest, homecome you interested in the use case? – run_the_race Mar 26 '22 at 08:13

1 Answers1

2

I dropped the Flask-Cors package, and made my own implementation:

""" Note:
    We need to use functools wraps, or else @route thinks all functions
    are named the same, and errors out that a route is overriding another

Test Preflight with:
    curl -i -X OPTIONS http://127.0.0.1:5000/foo/
Then test reponse with:
    curl -i http://127.0.0.1:5000/api/foo/
"""

from functools import wraps

from flask import Response, request


def add_cors_preflight_headers(response):
    allow_request = 'foo' in request.origin
    if allow_request:
        response.headers['Access-Control-Allow-Origin'] = request.origin

    if request.method == 'OPTIONS':
        response.headers['Access-Control-Allow-Methods'] = 'GET, OPTIONS'
        response.headers['Access-Control-Allow-Headers'] = 'Content-Type'
        # Allow chrome to access private network ajax requests
        response.headers['Access-Control-Allow-Private-Network'] = 'true'
    return response


def handle_cors(func):
    @wraps(func)
    def decorator(*args, **kwargs):
        if request.method == 'OPTIONS':
            response = Response()
        else:
            response = func(*args, **kwargs)
        response = add_cors_preflight_headers(response)
        return response

    return decorator

Then used as follows (note how we add options to the allowed methods):

@app.route("/api/foo/", methods=['GET', 'OPTIONS'])
@handle_cors
def get_foo():
    return Response({'foo': 'hello world!'})
run_the_race
  • 1,344
  • 2
  • 36
  • 62