Repository navigation
Conversation
New utils/_validation.py provides:
- validate_resource_name(): allowlist check [A-Za-z0-9][A-Za-z0-9._-]{0,199}
raises ValueError for names with path separators, dot segments, control
chars, percent escapes, @, and non-ASCII characters
- encode_path_segment(): validates then percent-encodes for safe URL interpolation
All 42 unit tests green. Full unit suite: 735/735.
- Add _split_name_and_level() module helper to auto-parse @ConsumptionLevel suffix from name (backward compat for legacy callers) - validate_resource_name() called before proxy check / try block so ValueError propagates cleanly without being wrapped in DestinationOperationError - encode_path_segment() applied at every URL interpolation site (V1 + V2) - create_destination / update_destination validate dest.name (round-trip guard) - Deprecated get_instance_destination / get_subaccount_destination validate too 184 client tests green.
…tificateClient Same security pattern as DestinationClient: - validate_resource_name() at every public method boundary (before try block) - encode_path_segment() at every URL interpolation site - create/update validate entity.name (round-trip consistency guard) 183 fragment + certificate tests green.
…st() Reject any path containing a '..' segment before issuing the HTTP request. Belt-and-suspenders layer behind the client-layer name validation. 10 tests green.
…subaccount read methods get_instance_fragment, get_subaccount_fragment, get_instance_certificate, and get_subaccount_certificate were delegating directly to internal helpers that have an except Exception catch-all, causing invalid names to raise DestinationOperationError instead of ValueError. Add validate_resource_name before the try block in all four methods, consistent with every other public method on this branch. Also replace path-echo in _http.py traversal guard error message with a fixed generic message to avoid returning attacker-controlled strings in error responses. 843 tests green.
- Bump version 0.58.1 → 0.58.2 (patch; src/ modified on this branch) - Collapse multiline raise in _validation.py to satisfy ruff-format - Add ty: ignore[invalid-argument-type] suppression on intentional non-string test inputs in test_validation.py - Add resource name validation section and @Level shorthand docs to destination user-guide.md
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Destination, fragment, and certificate resource names passed to public SDK methods are now validated against an allowlist grammar (
[A-Za-z0-9][A-Za-z0-9._\-]{0,199}) and percent-encoded before being interpolated into URL path segments.A
ValueErroris raised for names containing path separators, dot segments, query/fragment delimiters, control characters, or other characters outside the allowed set — before any OAuth token is fetched or HTTP request is sent. A defense-in-depth guard in_request()also rejects paths containing..segments.get_destination()auto-parses a@ConsumptionLevelsuffix in the name for backward compatibility. Callers using"my-dest@provider_subaccount"continue to work without changes; thelevel=parameter form is the canonical usage.No breaking changes. No agent or consumer repositories need to be modified.
Changes
src/sap_cloud_sdk/destination/utils/_validation.pywithvalidate_resource_name()andencode_path_segment()helpersvalidate_resource_name()added as the first statement in every public name-accepting method acrossDestinationClient,FragmentClient, andCertificateClientencode_path_segment()applied at every URL interpolation site in all three clients_split_name_and_level()helper inclient.pyauto-parses@ConsumptionLevelsuffix for backward compatibility..segment guard added to_request()in_http.pyTest plan
uv run pytest tests/destination/unit/test_validation.py -v— 42 cases covering allowlist accepts and rejectsuv run pytest tests/destination/unit/ -q— full unit suite, 843 tests greenTestPathTraversalGuardintest_client.py,test_fragment_client.py,test_certificate_client.py— attack names rejected, no HTTP call on invalid name,@levelauto-parse backward compat