Files
semantic-kernel/python/semantic_kernel
Roger Barreto f6391ad8b6 Python: OpenApi: Harden operation path handling for consistent selection and request targeting (.Net & Python) (#14140)
## 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
2026-07-06 16:43:25 +00:00
..
2024-10-10 22:33:42 +00:00
2024-03-28 15:10:28 +00:00