{"id":"PYSEC-2026-3563","summary":"datamodel-code-generator: Authorization / request headers leaked to cross-origin redirect target when fetching remote schemas","details":"### Summary\n\nWhen `datamodel-code-generator` fetches a remote schema and follows an HTTP redirect, it re-sends the original request headers, including any `Authorization` header, to the redirect target even when the redirect changes origin (host/port/scheme). Credentials that an operator scoped to a trusted schema host are therefore forwarded to an attacker-controlled or otherwise different host, leaking them.\n\n### Details\n\nIn `src/datamodel_code_generator/http.py`, `get_body()` follows redirects manually and re-issues each hop with the same `headers` argument, with no check that the origin is unchanged:\n\n```python\nfor redirect_count in range(MAX_HTTP_REDIRECTS + 1):\n    _validate_url_for_fetch(current_url, allow_private_network=allow_private_network)\n    response = httpx.get(current_url, headers=headers, follow_redirects=False, ...)  # same headers every hop\n    if (redirect_url := _get_redirect_url(httpx, current_url, response)) is None:\n        break\n    current_url = redirect_url\n```\n\nBrowsers and HTTP clients such as `requests`/`httpx` strip `Authorization` when a redirect crosses origin; here it is preserved unconditionally. Headers are operator-supplied via `--http-headers` (and credentials can also arrive through `--url` userinfo), so a redirect from the trusted host to any other host discloses them.\n\n### PoC\n\nSelf-contained reproducer: https://gist.github.com/thegr1ffyn/ade3035d7f2be95e16f11698259cdbc2  \nHost A (the trusted schema host) 302-redirects to host B (a different origin) which records received headers; the request carries an auth token scoped to A. \n\n(The PoC uses loopback servers; `allow_private_network=True` is only to avoid the separate SSRF guard blocking loopback and has no bearing on the leak.)\n\n### Impact\n\nExposure of sensitive information to an unauthorized actor (CWE-200). Affects operators who pass authentication headers/credentials to fetch a remote schema (`--http-headers`, `--url` with userinfo) when the configured host issues a redirect to a different origin — e.g. a compromised or open-redirect-prone schema host, or a redirect chain influenced by an attacker-supplied `$ref`. The leaked credential can then be replayed against the trusted host. This is a credential-scoping weakness secondary to, and in the same component as, the project's other SSRF hardening.\n\n### Suggested remediation\n\nWhen a redirect changes the origin (scheme/host/port), drop `Authorization` and other sensitive headers before following it, matching the behavior of mainstream HTTP clients.\n\n### Maintainer status\n\nConfirmed by maintainer review and regression tests. The private fix PR was merged and released in `0.63.0`: https://github.com/koxudaxi/datamodel-code-generator-ghsa-r5vv-ff45-prp2/pull/1\n\nFix summary: strip `Authorization`, `Cookie`, and `Proxy-Authorization` headers when a redirect crosses origin; preserve headers for same-origin redirects.\n\nRelease status: fixed in `0.63.0`; `0.62.0` and earlier are affected.\n\nValidation: `uv run --group test --extra http pytest tests/test_http.py` passed locally for the redirect regression coverage; `uv run --group fix ruff check src/datamodel_code_generator/http.py tests/test_http.py` passed.\n\nSubmitted by: Hamza Haroon (thegr1ffyn)","aliases":["CVE-2026-55403","GHSA-r5vv-ff45-prp2"],"modified":"2026-08-04T14:30:26.224128453Z","published":"2026-08-04T11:34:44.166317Z","references":[{"type":"WEB","url":"https://github.com/koxudaxi/datamodel-code-generator/security/advisories/GHSA-r5vv-ff45-prp2"},{"type":"WEB","url":"https://github.com/koxudaxi/datamodel-code-generator/commit/a585c037c8307b7aae815de193b7fe1c4c44994b"},{"type":"PACKAGE","url":"https://github.com/koxudaxi/datamodel-code-generator"},{"type":"WEB","url":"https://github.com/koxudaxi/datamodel-code-generator/releases/tag/0.63.0"},{"type":"PACKAGE","url":"https://pypi.org/project/datamodel-code-generator"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-r5vv-ff45-prp2"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-55403"}],"affected":[{"package":{"name":"datamodel-code-generator","ecosystem":"PyPI","purl":"pkg:pypi/datamodel-code-generator"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.63.0"}]}],"versions":["0.0.1","0.0.2","0.0.3","0.0.4","0.0.5","0.0.6","0.1.0","0.10.0","0.10.1","0.10.2","0.10.3","0.11.0","0.11.1","0.11.10","0.11.11","0.11.12","0.11.13","0.11.14","0.11.15","0.11.16","0.11.17","0.11.18","0.11.19","0.11.2","0.11.20","0.11.3","0.11.4","0.11.5","0.11.6","0.11.7","0.11.8","0.11.9","0.12.0","0.12.1","0.12.2","0.12.3","0.13.0","0.13.1","0.13.2","0.13.3","0.13.4","0.13.5","0.14.0","0.14.1","0.15.0","0.16.0","0.16.1","0.17.0","0.17.1","0.17.2","0.18.0","0.18.1","0.19.0","0.2.0","0.2.1","0.2.10","0.2.11","0.2.12","0.2.13","0.2.14","0.2.15","0.2.16","0.2.2","0.2.3","0.2.4","0.2.5","0.2.6","0.2.7","0.2.8","0.2.9","0.20.0","0.21.0","0.21.1","0.21.2","0.21.3","0.21.4","0.21.5","0.22.0","0.22.1","0.23.0","0.24.0","0.24.1","0.24.2","0.25.0","0.25.1","0.25.2","0.25.3","0.25.4","0.25.5","0.25.6","0.25.7","0.25.8","0.25.9","0.26.0","0.26.1","0.26.2","0.26.3","0.26.4","0.26.5","0.27.0","0.27.1","0.27.2","0.27.3","0.28.0","0.28.1","0.28.2","0.28.3","0.28.4","0.28.5","0.29.0","0.3.0","0.3.1","0.3.2","0.3.3","0.30.0","0.30.1","0.30.2","0.31.0","0.31.1","0.31.2","0.32.0","0.33.0","0.34.0","0.35.0","0.36.0","0.37.0","0.38.0","0.39.0","0.4.0","0.4.1","0.4.10","0.4.11","0.4.2","0.4.3","0.4.4","0.4.5","0.4.6","0.4.7","0.4.8","0.4.9","0.40.0","0.41.0","0.42.0","0.42.1","0.42.2","0.43.0","0.43.1","0.44.0","0.45.0","0.46.0","0.47.0","0.48.0","0.49.0","0.5.0","0.5.1","0.5.10","0.5.11","0.5.12","0.5.13","0.5.14","0.5.15","0.5.16","0.5.17","0.5.18","0.5.19","0.5.2","0.5.20","0.5.21","0.5.22","0.5.23","0.5.24","0.5.25","0.5.26","0.5.27","0.5.28","0.5.29","0.5.3","0.5.30","0.5.31","0.5.32","0.5.33","0.5.34","0.5.35","0.5.36","0.5.37","0.5.38","0.5.39","0.5.4","0.5.5","0.5.6","0.5.7","0.5.8","0.5.9","0.50.0","0.51.0","0.52.0","0.52.1","0.52.2","0.53.0","0.54.0","0.54.1","0.55.0","0.56.0","0.56.1","0.57.0","0.58.0","0.59.0","0.59.1","0.6.0","0.6.1","0.6.10","0.6.11","0.6.12","0.6.13","0.6.14","0.6.15","0.6.16","0.6.17","0.6.18","0.6.19","0.6.2","0.6.20","0.6.21","0.6.22","0.6.23","0.6.24","0.6.25","0.6.26","0.6.3","0.6.4","0.6.5","0.6.6","0.6.7","0.6.8","0.6.9","0.60.0","0.60.1","0.60.2","0.61.0","0.62.0","0.7.0","0.7.1","0.7.2","0.7.3","0.8.0","0.8.1","0.8.2","0.8.3","0.9.0","0.9.1","0.9.2","0.9.3","0.9.4"],"database_specific":{"source":"https://github.com/pypa/advisory-database/blob/main/vulns/datamodel-code-generator/PYSEC-2026-3563.yaml"}}],"schema_version":"1.8.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N"}]}