| From 7ae310c56ac30e0b94fb42129aa377bf633256ec Mon Sep 17 00:00:00 2001 |
| From: Adriano Sela Aviles <adriano.selaviles@gmail.com> |
| Date: Fri, 30 Aug 2024 12:14:31 -0400 |
| Subject: [PATCH] Backwards Compatible Fix for CVE-2024-6221 (#363) |
| |
| CVE: CVE-2024-6221 |
| |
| Upstream-Status: Backport [https://github.com/corydolphin/flask-cors/commit/7ae310c56ac30e0b94fb42129aa377bf633256ec] |
| |
| Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com> |
| --- |
| docs/configuration.rst | 14 ++++++++++++++ |
| flask_cors/core.py | 8 +++++--- |
| flask_cors/extension.py | 16 ++++++++++++++++ |
| 3 files changed, 35 insertions(+), 3 deletions(-) |
| |
| diff --git a/docs/configuration.rst b/docs/configuration.rst |
| index 91282d3..c750cf4 100644 |
| --- a/docs/configuration.rst |
| +++ b/docs/configuration.rst |
| @@ -23,6 +23,19 @@ CORS_ALLOW_HEADERS (:py:class:`~typing.List` or :py:class:`str`) |
| Headers to accept from the client. |
| Headers in the :http:header:`Access-Control-Request-Headers` request header (usually part of the preflight OPTIONS request) matching headers in this list will be included in the :http:header:`Access-Control-Allow-Headers` response header. |
| |
| +CORS_ALLOW_PRIVATE_NETWORK (:py:class:`bool`) |
| + If True, the response header :http:header:`Access-Control-Allow-Private-Network` |
| + will be set with the value 'true' whenever the request header |
| + :http:header:`Access-Control-Request-Private-Network` has a value 'true'. |
| + |
| + If False, the reponse header :http:header:`Access-Control-Allow-Private-Network` |
| + will be set with the value 'false' whenever the request header |
| + :http:header:`Access-Control-Request-Private-Network` has a value of 'true'. |
| + |
| + If the request header :http:header:`Access-Control-Request-Private-Network` is |
| + not present or has a value other than 'true', the response header |
| + :http:header:`Access-Control-Allow-Private-Network` will not be set. |
| + |
| CORS_ALWAYS_SEND (:py:class:`bool`) |
| Usually, if a request doesn't include an :http:header:`Origin` header, the client did not request CORS. |
| This means we can ignore this request. |
| @@ -83,6 +96,7 @@ Default values |
| ~~~~~~~~~~~~~~ |
| |
| * CORS_ALLOW_HEADERS: "*" |
| +* CORS_ALLOW_PRIVATE_NETWORK: True |
| * CORS_ALWAYS_SEND: True |
| * CORS_AUTOMATIC_OPTIONS: True |
| * CORS_EXPOSE_HEADERS: None |
| diff --git a/flask_cors/core.py b/flask_cors/core.py |
| index 5358036..bd011f4 100644 |
| --- a/flask_cors/core.py |
| +++ b/flask_cors/core.py |
| @@ -36,7 +36,7 @@ CONFIG_OPTIONS = ['CORS_ORIGINS', 'CORS_METHODS', 'CORS_ALLOW_HEADERS', |
| 'CORS_MAX_AGE', 'CORS_SEND_WILDCARD', |
| 'CORS_AUTOMATIC_OPTIONS', 'CORS_VARY_HEADER', |
| 'CORS_RESOURCES', 'CORS_INTERCEPT_EXCEPTIONS', |
| - 'CORS_ALWAYS_SEND'] |
| + 'CORS_ALWAYS_SEND', 'CORS_ALLOW_PRIVATE_NETWORK'] |
| # Attribute added to request object by decorator to indicate that CORS |
| # was evaluated, in case the decorator and extension are both applied |
| # to a view. |
| @@ -56,7 +56,8 @@ DEFAULT_OPTIONS = dict(origins='*', |
| vary_header=True, |
| resources=r'/*', |
| intercept_exceptions=True, |
| - always_send=True) |
| + always_send=True, |
| + allow_private_network=True) |
| |
| |
| def parse_resources(resources): |
| @@ -186,7 +187,8 @@ def get_cors_headers(options, request_headers, request_method): |
| |
| if ACL_REQUEST_HEADER_PRIVATE_NETWORK in request_headers \ |
| and request_headers.get(ACL_REQUEST_HEADER_PRIVATE_NETWORK) == 'true': |
| - headers[ACL_RESPONSE_PRIVATE_NETWORK] = 'true' |
| + allow_private_network = 'true' if options.get('allow_private_network') else 'false' |
| + headers[ACL_RESPONSE_PRIVATE_NETWORK] = allow_private_network |
| |
| # This is a preflight request |
| # http://www.w3.org/TR/cors/#resource-preflight-requests |
| diff --git a/flask_cors/extension.py b/flask_cors/extension.py |
| index c00cbff..694953f 100644 |
| --- a/flask_cors/extension.py |
| +++ b/flask_cors/extension.py |
| @@ -136,6 +136,22 @@ class CORS(object): |
| |
| Default : True |
| :type vary_header: bool |
| + |
| + :param allow_private_network: |
| + If True, the response header `Access-Control-Allow-Private-Network` |
| + will be set with the value 'true' whenever the request header |
| + `Access-Control-Request-Private-Network` has a value 'true'. |
| + |
| + If False, the reponse header `Access-Control-Allow-Private-Network` |
| + will be set with the value 'false' whenever the request header |
| + `Access-Control-Request-Private-Network` has a value of 'true'. |
| + |
| + If the request header `Access-Control-Request-Private-Network` is |
| + not present or has a value other than 'true', the response header |
| + `Access-Control-Allow-Private-Network` will not be set. |
| + |
| + Default : True |
| + :type allow_private_network: bool |
| """ |
| |
| def __init__(self, app=None, **kwargs): |
| -- |
| 2.40.0 |