corydolphin / flask-cors

Cross Origin Resource Sharing ( CORS ) support for Flask
https://flask-cors.corydolphin.com/
MIT License
877 stars 137 forks source link

Only allow root domain (no subdomain access) #246

Open JeanClaude3 opened 5 years ago

JeanClaude3 commented 5 years ago

My backend API his hosted on api.example.com

However, when I visit api.example.com directly and visit an endpoint, I can see the returned response for pages which don't require authorization.

My current configuration of Flask-cors:

   cors = CORS(app, resources={r"/api/*": {"origins": ["example.com", "https://www.example.com", "https://example.com"]}})

I have tried many different versions of the above origins, but none prevent someone from accessing the api subdomain endpoint directly and running requests that way. I guess it makes sense because technically api.example.com is an origin of example.com

Is there a way I can only allow access to the app from the root domain (eg. example.com) and none from the direct api subdomain (eg. api.example.com) itself?

Sorry in advance if this is something obvious which I'm clearly missing. Thank you!

JeanClaude3 commented 5 years ago

I just moved my API to a separate domain eg. example2.com

however, it still can be viewed directly even though CORS is specifically configured to only allow requests from "example.com" ... really think I am missing something here.

any help would be greatly appreciated

corydolphin commented 5 years ago

Is this a browser or a command line client? In the case of a browser, the response should not have CORS headers. If you take the app based example:

"""
Flask-Cors example
===================
This is a tiny Flask Application demonstrating Flask-Cors, making it simple
to add cross origin support to your flask app!

:copyright: (c) 2016 by Cory Dolphin.
:license:   MIT/X11, see LICENSE for more details.
"""
from flask import Flask, jsonify
import logging
try:
    from flask_cors import CORS  # The typical way to import flask-cors
except ImportError:
    # Path hack allows examples to be run without installation.
    import os
    parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    os.sys.path.insert(0, parentdir)

    from flask_cors import CORS

app = Flask('FlaskCorsAppBasedExample')
logging.basicConfig(level=logging.INFO)

# To enable logging for flask-cors,
logging.getLogger('flask_cors').level = logging.DEBUG

# One of the simplest configurations. Exposes all resources matching /api/* to
# CORS and allows the Content-Type header, which is necessary to POST JSON
# cross origin.
CORS(app, resources={r'/api/*':{"origins": ["example.com"]}})

@app.route("/api/v1/users/")
def list_users():
    """
        Since the path matches the regular expression r'/api/*', this resource
        automatically has CORS headers set. The expected result is as follows:

        $ curl --include -X GET http://127.0.0.1:5000/api/v1/users/ \
            --header Origin:www.examplesite.com
        HTTP/1.0 200 OK
        Access-Control-Allow-Headers: Content-Type
        Access-Control-Allow-Origin: *
        Content-Length: 21
        Content-Type: application/json
        Date: Sat, 09 Aug 2014 00:26:41 GMT
        Server: Werkzeug/0.9.4 Python/2.7.8

        {
            "success": true
        }

    """
    return jsonify(user="joe")

You can see that no CORS headers are returned when using the wrong domain.

➜  flask-cors git:(master) ✗ curl --include -X GET http://127.0.0.1:5000/api/v1/users/ --header Origin:www.example2.com
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 20
Server: Werkzeug/0.15.4 Python/3.7.3
Date: Wed, 10 Jul 2019 15:59:19 GMT

{
  "user": "joe"
}
➜  flask-cors git:(master) ✗ curl --include -X GET http://127.0.0.1:5000/api/v1/users/ --header Origin:www.example.com
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 20
Server: Werkzeug/0.15.4 Python/3.7.3
Date: Wed, 10 Jul 2019 15:59:32 GMT

{
  "user": "joe"
}
➜  flask-cors git:(master) ✗ curl --include -X GET http://127.0.0.1:5000/api/v1/users/ --header Origin:example.com
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 20
Access-Control-Allow-Origin: example.com
Server: Werkzeug/0.15.4 Python/3.7.3
Date: Wed, 10 Jul 2019 15:59:35 GMT

{
  "user": "joe"
}
➜  flask-cors git:(master) ✗