VYPR
High severity7.6NVD Advisory· Published Mar 20, 2025· Updated Apr 15, 2026

CVE-2024-8183

CVE-2024-8183

Description

A CORS (Cross-Origin Resource Sharing) misconfiguration in prefecthq/prefect version 2.20.2 allows unauthorized domains to access sensitive data. This vulnerability can lead to unauthorized access to the database, resulting in potential data leaks, loss of confidentiality, service disruption, and data integrity risks.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
prefectPyPI
>= 3.0.0rc1, < 3.0.33.0.3
prefectPyPI
< 2.20.172.20.17

Patches

1
a69266e07716

Adds settings to control server CORS configuration

https://github.com/prefecthq/prefectAlex StreedSep 16, 2024via ghsa
4 files changed · +103 3
  • docs/3.0/api-ref/rest-api/server/schema.json+15 0 modified
    @@ -21881,6 +21881,21 @@
                             "title": "Prefect Server Csrf Token Expiration",
                             "default": "PT1H"
                         },
    +                    "PREFECT_SERVER_CORS_ALLOWED_ORIGINS": {
    +                        "type": "string",
    +                        "title": "Prefect Server Cors Allowed Origins",
    +                        "default": "*"
    +                    },
    +                    "PREFECT_SERVER_CORS_ALLOWED_METHODS": {
    +                        "type": "string",
    +                        "title": "Prefect Server Cors Allowed Methods",
    +                        "default": "*"
    +                    },
    +                    "PREFECT_SERVER_CORS_ALLOWED_HEADERS": {
    +                        "type": "string",
    +                        "title": "Prefect Server Cors Allowed Headers",
    +                        "default": "*"
    +                    },
                         "PREFECT_SERVER_ALLOW_EPHEMERAL_MODE": {
                             "type": "boolean",
                             "title": "Prefect Server Allow Ephemeral Mode",
    
  • src/prefect/server/api/server.py+9 3 modified
    @@ -641,9 +641,15 @@ def on_service_exit(service, task):
         # middleware
         app.add_middleware(
             CORSMiddleware,
    -        allow_origins=["*"],
    -        allow_methods=["*"],
    -        allow_headers=["*"],
    +        allow_origins=prefect.settings.PREFECT_SERVER_CORS_ALLOWED_ORIGINS.value().split(
    +            ","
    +        ),
    +        allow_methods=prefect.settings.PREFECT_SERVER_CORS_ALLOWED_METHODS.value().split(
    +            ","
    +        ),
    +        allow_headers=prefect.settings.PREFECT_SERVER_CORS_ALLOWED_HEADERS.value().split(
    +            ","
    +        ),
         )
     
         # Limit the number of concurrent requests when using a SQLite database to reduce
    
  • src/prefect/settings.py+30 0 modified
    @@ -1288,6 +1288,36 @@ def default_cloud_ui_url(settings, value):
     and usage patterns.
     """
     
    +PREFECT_SERVER_CORS_ALLOWED_ORIGINS = Setting(
    +    str,
    +    default="*",
    +)
    +"""
    +A comma-separated list of origins that are authorized to make cross-origin requests to the API.
    +
    +By default, this is set to `*`, which allows requests from all origins.
    +"""
    +
    +PREFECT_SERVER_CORS_ALLOWED_METHODS = Setting(
    +    str,
    +    default="*",
    +)
    +"""
    +A comma-separated list of methods that are authorized to make cross-origin requests to the API.
    +
    +By default, this is set to `*`, which allows requests with all methods.
    +"""
    +
    +PREFECT_SERVER_CORS_ALLOWED_HEADERS = Setting(
    +    str,
    +    default="*",
    +)
    +"""
    +A comma-separated list of headers that are authorized to make cross-origin requests to the API.
    +
    +By default, this is set to `*`, which allows requests with all headers.
    +"""
    +
     PREFECT_SERVER_ALLOW_EPHEMERAL_MODE = Setting(bool, default=False)
     """
     Controls whether or not a subprocess server can be started when no API URL is provided.
    
  • tests/server/api/test_server.py+49 0 modified
    @@ -29,6 +29,9 @@
         PREFECT_API_URL,
         PREFECT_MEMO_STORE_PATH,
         PREFECT_MEMOIZE_BLOCK_AUTO_REGISTRATION,
    +    PREFECT_SERVER_CORS_ALLOWED_HEADERS,
    +    PREFECT_SERVER_CORS_ALLOWED_METHODS,
    +    PREFECT_SERVER_CORS_ALLOWED_ORIGINS,
         temporary_settings,
     )
     from prefect.testing.utilities import AsyncMock
    @@ -135,6 +138,52 @@ async def raise_other_error():
             assert response.status_code == 500
     
     
    +async def test_cors_middleware_settings():
    +    with SubprocessASGIServer() as server:
    +        health_response = httpx.options(
    +            f"{server.api_url}/health",
    +            headers={
    +                "Origin": "http://example.com",
    +                "Access-Control-Request-Method": "GET",
    +            },
    +        )
    +        assert health_response.status_code == 200
    +        assert health_response.headers["Access-Control-Allow-Origin"] == "*"
    +        assert (
    +            health_response.headers["Access-Control-Allow-Methods"]
    +            == "DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT"
    +        )
    +        assert "Access-Control-Allow-Headers" not in health_response.headers
    +
    +    with temporary_settings(
    +        {
    +            PREFECT_SERVER_CORS_ALLOWED_ORIGINS: "http://example.com",
    +            PREFECT_SERVER_CORS_ALLOWED_METHODS: "GET,POST",
    +            PREFECT_SERVER_CORS_ALLOWED_HEADERS: "x-tra-header",
    +        }
    +    ):
    +        with SubprocessASGIServer() as server:
    +            health_response = httpx.options(
    +                f"{server.api_url}/health",
    +                headers={
    +                    "Origin": "http://example.com",
    +                    "Access-Control-Request-Method": "GET",
    +                },
    +            )
    +            assert health_response.status_code == 200
    +            assert (
    +                health_response.headers["Access-Control-Allow-Origin"]
    +                == "http://example.com"
    +            )
    +            assert (
    +                health_response.headers["Access-Control-Allow-Methods"] == "GET, POST"
    +            )
    +            assert (
    +                "x-tra-header"
    +                in health_response.headers["Access-Control-Allow-Headers"]
    +            )
    +
    +
     async def test_health_check_route(client):
         response = await client.get("/health")
         assert response.status_code == status.HTTP_200_OK
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.