mirror of
https://github.com/microsoft/semantic-kernel.git
synced 2026-10-12 02:19:06 +00:00
## Motivation and Context The OpenAPI plugin imports operations from a spec and lets the host restrict which operations are exposed via an `OperationSelectionPredicate` (and via `OperationsToExclude`). Operation selection and request-URL construction should share one canonical interpretation of an operation path. This change closes two consistency gaps where a spec-supplied path could be interpreted differently at selection time than at request time. 1. **Selection vs. request path normalization.** The selection predicate received the raw operation path, while the request URL is built from a canonicalized path. An encoded dot-segment (for example `%2e%2e`) is textually different from the endpoint it canonicalizes to, so it could pass a path-based include/exclude filter yet resolve to a different route. Operations whose path contains an encoded or literal dot-segment are now excluded before the predicate is consulted, symmetric with the existing request-time dot-segment rejection. 2. **Request target reconciliation (defense in depth).** After the request URL is built, verify it did not move off the configured server. An operation path that is an absolute or authority-changing URI (for example `https://another-host/admin`) carries no dot-segment, so it passes path-segment validation, yet `System.Uri` / `urljoin` resolve it to a different scheme, host, or port. Such a request is now rejected before it is sent, so a credential-bearing request cannot be redirected to an unintended target. Both changes are applied symmetrically to the .NET and Python OpenAPI ports. ## Description - **.NET** - `OpenApiDocumentParser` skips operations whose path contains a dot-segment before invoking the selection predicate. - `RestApiOperation` extracts a shared `ContainsDotSegment` helper (reused by the existing `ValidatePathSegments`) and, after building the request URL, reconciles its scheme/host/port and base path against the configured server. - **Python** - `openapi_parser` skips dot-segment operations before the predicate runs. - `rest_api_operation` adds a shared `_contains_dot_segment` helper and a post-construction `_ensure_request_target_matches_server` reconciliation. ## Tests - .NET: added selection-exclusion and request-target reconciliation tests; full `Functions.UnitTests` OpenApi suite green (488). - Python: added parity tests for both behaviors; `tests/unit/connectors/openapi_plugin` green (173), ruff + ruff-format + mypy + pre-commit clean. ## Contribution Checklist - [x] The code builds clean without any errors or warnings - [x] The PR follows the SK Contribution Guidelines - [x] All unit tests pass, and I have added new tests where possible