diff --git a/haystack/components/converters/openapi_functions.py b/haystack/components/converters/openapi_functions.py index bcc08a53ae..f6bf7e0830 100644 --- a/haystack/components/converters/openapi_functions.py +++ b/haystack/components/converters/openapi_functions.py @@ -233,6 +233,16 @@ def _parse_property_attributes( return parsed_schema + @staticmethod + def _no_external_ref_loader(uri: str, **_: Any) -> Any: + # In-document refs (those starting with "#") are resolved by jsonref without invoking + # the loader. Anything else points outside the document (file://, http(s)://, ...) and + # is rejected to prevent local file disclosure and outbound requests during parsing. + raise RuntimeError( + f"Refusing to resolve external $ref '{uri}' while parsing OpenAPI spec. " + "Only in-document JSON-pointer references (starting with '#') are supported." + ) + def _parse_openapi_spec(self, content: str) -> dict[str, Any]: """ Parses OpenAPI specification content, supporting both JSON and YAML formats. @@ -243,7 +253,7 @@ def _parse_openapi_spec(self, content: str) -> dict[str, Any]: open_api_spec_content = None try: open_api_spec_content = json.loads(content) - return jsonref.replace_refs(open_api_spec_content) + return jsonref.replace_refs(open_api_spec_content, loader=self._no_external_ref_loader, proxies=False) except json.JSONDecodeError as json_error: # heuristic to confirm that the content is likely malformed JSON if content.strip().startswith(("{", "[")): @@ -258,4 +268,4 @@ def _parse_openapi_spec(self, content: str) -> dict[str, Any]: raise RuntimeError(error_message, content) from e # Replace references in the object with their resolved values, if any - return jsonref.replace_refs(open_api_spec_content) + return jsonref.replace_refs(open_api_spec_content, loader=self._no_external_ref_loader, proxies=False) diff --git a/releasenotes/notes/openapi-converter-disallow-external-refs-9b1d3f0a7c2e54a1.yaml b/releasenotes/notes/openapi-converter-disallow-external-refs-9b1d3f0a7c2e54a1.yaml new file mode 100644 index 0000000000..2e84c3c288 --- /dev/null +++ b/releasenotes/notes/openapi-converter-disallow-external-refs-9b1d3f0a7c2e54a1.yaml @@ -0,0 +1,9 @@ +--- +enhancements: + - | + ``OpenAPIServiceToFunctions`` now resolves only in-document JSON-pointer + references (those starting with ``#``) when parsing OpenAPI specifications. + External ``$ref`` URIs (for example ``file://`` or ``http(s)://``) are no longer + fetched during parsing; specs that depend on them will raise a + ``RuntimeError``. This avoids unintended filesystem access or outbound + HTTP requests when the spec content is not fully trusted.