JSON-Schema $ref values pointing at HTTP or HTTPS URLs are silently dereferenced by datamodel-code-generator with no IP/host validation, no scheme allow-list, and redirects followed unconditionally. The --allow-remote-refs gate added in 0.56.0 defaults to None, which only emits a deprecation warning and then fetches the URL anyway; only explicit --allow-remote-refs=false blocks the request. The fetched body is parsed as a sub-schema and reflected verbatim into the generated .py source. As a result, any JSON-Schema document the developer feeds to datamodel-codegen — including documents authored by an attacker — can pivot to arbitrary internal addresses and leak the response into the generated code, with no developer cooperation beyond running the tool.
Sink: src/datamodel_code_generator/parser/jsonschema.py, _get_ref_body (lines 4776–4793, at tag 0.60.1 / commit a321547e):
def _get_ref_body(self, resolved_ref: str) -> dict[str, YamlValue]:
if is_url(resolved_ref):
if not resolved_ref.startswith("file://") and self.http_local_ref_path is None:
if self.allow_remote_refs is False:
raise Error(f"Fetching remote $ref is disabled: {resolved_ref}...")
if self.allow_remote_refs is None:
warn_deprecated( # (A) warn only
"behavior.remote-ref-default",
details=f"Reference: {resolved_ref}",
stacklevel=2,
)
return self._get_ref_body_from_url(resolved_ref) # (B) fetch fires
return self._get_ref_body_from_remote(resolved_ref)
allow_remote_refs is its default (None); execution falls through to (B)._get_text_from_url → get_body, the same fetcher described in other report — no IP validation, redirects followed.The fetched body is then parsed as a sub-schema...
0.61.0Exploitability
AV:NAC:LPR:NUI:RScope
S:CImpact
C:HI:LA:N8.2/CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:NInput Validation