CVE-2026-7722 Overview
CVE-2026-7722 is an authentication bypass vulnerability in PrefectHQ Prefect through version 3.6.21. The flaw resides in the endswith logic of the /api/health endpoint inside the Health Check API component of the server middleware. An attacker can craft request paths that satisfy the suffix check and bypass token validation, reaching authenticated endpoints without credentials. The issue is exploitable remotely over the network and proof-of-concept details are public. PrefectHQ released a fix in version 3.6.22 via commit e21617125335025b4b27e7d6f0ca028e8e8f3b79. The weakness maps to [CWE-287: Improper Authentication].
Critical Impact
Unauthenticated remote attackers can reach protected Prefect server API routes by crafting URL paths that end with health or ready, defeating the bearer-token middleware.
Affected Products
- PrefectHQ Prefect versions up to and including 3.6.21
- Prefect server deployments using PREFECT_SERVER_API_AUTH_STRING for token-based authentication
- Self-hosted Prefect installations exposing the Health Check API endpoint
Discovery Timeline
- 2026-05-04 - CVE-2026-7722 published to NVD
- 2026-05-04 - Last updated in NVD database
Technical Details for CVE-2026-7722
Vulnerability Analysis
Prefect's FastAPI server registers an HTTP middleware that validates the Authorization header against a configured auth string. The middleware exempts Kubernetes-style probes by allowing unauthenticated GET requests whose path ends in health or ready. The exemption uses Python's str.endswith against request.url.path, which is a suffix match rather than an exact match. An attacker can craft a path such as /variables/name/system-health that terminates with the literal string health and inherits the unauthenticated branch. The middleware then forwards the request to the downstream route handler without enforcing token validation, exposing data and control-plane operations.
Root Cause
The root cause is improper authentication caused by suffix-based path matching. The original check trusted any path ending with health or ready, and it read from request.url.path, which can be influenced by Host header manipulation. Both behaviors widen the unauthenticated surface beyond the intended /api/health and /ready probes.
Attack Vector
Exploitation requires only network reachability to the Prefect server. The attacker issues an HTTP GET request to any authenticated endpoint whose URL path ends with health or ready. No credentials, user interaction, or prior privileges are required. Because the bypass occurs in middleware, downstream handlers process the request as if the auth check passed.
auth_string = prefect.settings.PREFECT_SERVER_API_AUTH_STRING.value()
if auth_string is not None:
+ health_check_paths = {health_check_path, "/ready"}
@api_app.middleware("http")
async def token_validation(request: Request, call_next: Any): # type: ignore[reportUnusedFunction]
header_token = request.headers.get("Authorization")
- # used for probes in k8s and such
- if (
- request.url.path.endswith(("health", "ready"))
- and request.method.upper() == "GET"
- ):
+ # Allow unauthenticated health/ready probes (e.g. k8s).
+ # Use scope["path"] (not request.url.path) because url.path
+ # can be spoofed via Host header manipulation. Use exact path
+ # matching (not suffix matching) to prevent auth bypass via
+ # crafted paths like /variables/name/system-health.
+ scope = request.scope
+ app_path = scope["path"].removeprefix(scope.get("root_path", ""))
+ if app_path in health_check_paths and request.method.upper() == "GET":
return await call_next(request)
try:
if header_token is None:
Source: GitHub Prefect Commit e21617125335025b4b27e7d6f0ca028e8e8f3b79
Detection Methods for CVE-2026-7722
Indicators of Compromise
- HTTP GET requests to Prefect server paths that end in health or ready but are not the canonical /api/health or /ready endpoints, for example /api/variables/name/system-health.
- Successful API responses on protected resources without an accompanying Authorization header in access logs.
- Anomalous traffic from external IP ranges hitting Prefect server ports historically reserved for internal probes.
Detection Strategies
- Inspect reverse proxy and Prefect server access logs for any 200 OK responses on non-public routes when the request lacks an Authorization header.
- Build a rule that flags requests where request.path matches *health or *ready but does not equal /api/health, /health, or /ready.
- Correlate Prefect server activity against expected operator workflows to surface enumeration of variables, deployments, or flow runs from unauthenticated sessions.
Monitoring Recommendations
- Enable structured access logging on the Prefect server and forward logs to a centralized analytics platform for retention and search.
- Alert on spikes in requests to URL paths containing the substrings health or ready outside of known probe sources such as the Kubernetes kubelet.
- Track the deployed Prefect version across hosts and trigger alerts when any node remains on 3.6.21 or earlier.
How to Mitigate CVE-2026-7722
Immediate Actions Required
- Upgrade Prefect to version 3.6.22 or later, which replaces the suffix match with an exact path comparison and reads from scope["path"].
- Audit Prefect server access logs for unauthenticated requests to paths ending in health or ready since deployment.
- Rotate any secrets, API tokens, or credentials managed through Prefect variables and blocks if log review indicates exposure.
Patch Information
The fix is delivered in PrefectHQ Prefect release 3.6.22, tracked in pull request #21063 and committed as e21617125335025b4b27e7d6f0ca028e8e8f3b79. The patch defines an explicit health_check_paths set, switches to ASGI scope["path"] to prevent Host header spoofing, and uses set membership instead of endswith for path comparison. See the GitHub Prefect Release 3.6.22 notes and GitHub Prefect Pull Request #21063 for full details.
Workarounds
- Restrict network access to the Prefect server so that only trusted clients and probe sources can reach the API port.
- Place an authenticating reverse proxy in front of the Prefect server that enforces token validation independently of the application middleware.
- Block external requests to URL paths ending in health or ready at the load balancer, allowing only the canonical /api/health and /ready endpoints.
# Upgrade Prefect to the patched release
pip install --upgrade 'prefect>=3.6.22'
# Verify the running server version
prefect version
# Example NGINX rule restricting health-suffixed paths to the loopback probe
# location ~* (health|ready)$ {
# allow 127.0.0.1;
# deny all;
# proxy_pass http://prefect_upstream;
# }
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

