{"id":632,"library":"flask-cors","title":"Flask-CORS","description":"Flask-CORS is a Flask extension that simplifies the implementation of Cross-Origin Resource Sharing (CORS) in Flask applications, enabling cross-origin AJAX requests. It supports global, resource-specific, and route-specific CORS configurations. The current version is 6.0.2, and it maintains an active release cadence with regular updates and security patches.","status":"active","version":"6.0.2","language":"python","source_language":"en","source_url":"https://github.com/corydolphin/flask-cors","tags":["flask","cors","web development","http","security","api"],"install":[{"cmd":"pip install Flask-CORS","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Core dependency for a Flask extension.","package":"Flask"},{"reason":"Requires Python versions >=3.9,<4.0.","package":"Python","optional":false}],"imports":[{"note":"The `flask.ext` prefix was deprecated and removed in Flask 0.11. Direct import from `flask_cors` is the correct approach.","wrong":"from flask.ext.cors import CORS","symbol":"CORS","correct":"from flask_cors import CORS"},{"symbol":"cross_origin","correct":"from flask_cors import cross_origin"}],"quickstart":{"code":"from flask import Flask\nfrom flask_cors import CORS\nimport os\n\napp = Flask(__name__)\nCORS(app) # Enable CORS for all routes, for all origins and methods\n\n@app.route(\"/\")\ndef hello_world():\n    return \"Hello, cross-origin-world!\"\n\n# Example of specific CORS for an API endpoint\n@app.route(\"/api/data\")\n@cross_origin(origins=\"http://localhost:3000\", methods=[\"GET\", \"POST\"], supports_credentials=True)\ndef get_data():\n    return {\"message\": \"Data from API!\"}\n\nif __name__ == '__main__':\n    app.run(debug=True, port=int(os.environ.get('PORT', 5000)))\n","lang":"python","description":"This quickstart demonstrates enabling CORS globally for an entire Flask application and also for a specific route using the `@cross_origin` decorator. Global enablement is done by initializing `CORS(app)`. For fine-grained control, the `@cross_origin` decorator allows specifying allowed origins, methods, and credential support for individual routes."},"warnings":[{"fix":"Review your CORS configurations, especially those with multiple resource paths, to ensure they match the new specificity order. Test cross-origin requests thoroughly to confirm expected behavior. Ensure your application's request paths are consistently cased if matching rules rely on it.","message":"In version 6.0.0, the path specificity ordering for CORS rules changed to improve specificity. This might alter how CORS rules are applied if your application relied on the previous, less specific ordering. Additionally, `urllib.unquote_plus` was replaced with `urllib.unquote`, and request path matching became case-sensitive.","severity":"breaking","affected_versions":"6.0.0 and higher"},{"fix":"If your application requires private network access, consult the Flask-CORS documentation for the specific configuration option to re-enable it. Typically, this involves setting a configuration flag.","message":"Version 5.0.0 introduced a breaking change by defaulting to disable private network access. This was a security enhancement. If your application needs to make requests to private network resources from a public-facing origin, you will need to explicitly re-enable this functionality.","severity":"breaking","affected_versions":"5.0.0 and higher"},{"fix":"Upgrade your Python environment to 3.8 or newer before upgrading to Flask-CORS 4.0.0+.","message":"Version 4.0.0 dropped support for Python versions older than 3.8. Applications running on Python 3.7 or earlier will not be able to upgrade to Flask-CORS 4.0.0 or newer.","severity":"breaking","affected_versions":"4.0.0 and higher"},{"fix":"Implement CSRF protection (e.g., Flask-WTF CSRFProtect) when `supports_credentials=True` is enabled. Carefully define `origins` to restrict access to trusted domains only.","message":"Enabling `supports_credentials=True` allows browsers to send cookies and HTTP authentication headers with cross-origin requests. While necessary for authenticated requests, it introduces security implications and should always be used in conjunction with robust CSRF protection.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always specify a list of explicit, trusted `origins` (e.g., `origins=['http://localhost:3000', 'https://your-frontend.com']`) instead of `*` in production deployments.","message":"Using `origins='*'` (allowing all origins) is generally not recommended for production environments due to security risks. It can expose your API to unintended access.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always provide complete origin URLs, including schema and port, in the `origins` list or string.","message":"When specifying `origins` in `CORS` or `@cross_origin`, ensure you include the full schema (http/https) and the port number (if not the default 80 or 443). For example, `http://localhost:8000` is correct, while `localhost:8000` or `http://localhost` (if on a non-default port) might not work.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure `cross_origin` is imported from `flask_cors` (e.g., `from flask_cors import cross_origin`).","message":"The `cross_origin` decorator/function must be explicitly imported from `flask_cors` before use, otherwise a `NameError` will occur.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure that `from flask_cors import cross_origin` is included at the top of any file where the `@cross_origin` decorator is used.","message":"The `cross_origin` decorator must be explicitly imported from `flask_cors` before use. Failing to import it (e.g., `from flask_cors import cross_origin`) will result in a `NameError`.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T17:01:40.967Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Install the package using pip: `pip install flask-cors`","cause":"The 'flask-cors' package has not been installed in your Python environment or is not accessible in the environment where your Flask application is running.","error":"ModuleNotFoundError: No module named 'flask_cors'"},{"fix":"Initialize Flask-CORS on your Flask app, specifying the allowed origins. For all origins (development): `from flask_cors import CORS; CORS(app)`. For specific origins: `CORS(app, origins=['http://your-frontend.com'])`","cause":"Your Flask server is not configured to send the 'Access-Control-Allow-Origin' header, which is required by browsers to allow cross-origin requests from your frontend application. This often happens because Flask-CORS is not initialized or configured correctly to allow the specific origin of the client application.","error":"Access to fetch at 'http://your-flask-app.com/api' from origin 'http://your-frontend.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."},{"fix":"Ensure `flask-cors` is configured to allow the specific HTTP methods and headers for your routes. When initializing `CORS(app)`, you can specify `methods=['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']` and `headers=['Content-Type', 'Authorization']` (adjust as needed). Also, ensure `OPTIONS` requests are handled, which Flask-CORS does by default when enabled globally or per route with `@cross_origin()`.","cause":"This error, in the context of CORS, often occurs during a preflight OPTIONS request or for complex requests (e.g., PUT, DELETE with custom headers) where the Flask-CORS configuration does not explicitly allow the HTTP method being used or the necessary headers for the preflight response.","error":"Method Not Allowed (405)"},{"fix":"When using `supports_credentials=True` in `CORS(app, supports_credentials=True)`, you must specify exact origins instead of the wildcard '*'. Change `CORS(app)` or `CORS(app, origins='*')` to `CORS(app, origins=['http://localhost:3000'], supports_credentials=True)` (replace 'http://localhost:3000' with your actual frontend origin).","cause":"You are attempting to make a cross-origin request with credentials (e.g., cookies, HTTP authentication) while the server's 'Access-Control-Allow-Origin' header is set to '*', which is not permitted by the W3C CORS specification for security reasons.","error":"Access to XMLHttpRequest at 'http://your-flask-app.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'."}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":"6.0.2","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.47,"mem_mb":11.8,"disk_size":"22.5M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.49,"mem_mb":11.8,"disk_size":"22.5M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2.1,"import_time_s":0.4,"mem_mb":11.8,"disk_size":"23M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.36,"mem_mb":11.8,"disk_size":"23M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.6,"mem_mb":13.3,"disk_size":"25.2M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.66,"mem_mb":13.3,"disk_size":"25.1M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2.4,"import_time_s":0.55,"mem_mb":13.3,"disk_size":"26M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.5,"mem_mb":13.3,"disk_size":"26M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.52,"mem_mb":12.9,"disk_size":"16.8M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.54,"mem_mb":12.9,"disk_size":"16.8M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2.1,"import_time_s":0.55,"mem_mb":12.9,"disk_size":"17M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.53,"mem_mb":12.9,"disk_size":"17M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.5,"mem_mb":13.9,"disk_size":"16.6M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.56,"mem_mb":13.9,"disk_size":"16.5M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2.1,"import_time_s":0.51,"mem_mb":13.8,"disk_size":"17M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.53,"mem_mb":13.8,"disk_size":"17M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.41,"mem_mb":12,"disk_size":"22.2M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.43,"mem_mb":12,"disk_size":"22.2M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2.7,"import_time_s":0.4,"mem_mb":12,"disk_size":"23M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.35,"mem_mb":12,"disk_size":"23M"}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}