Skip to content

fix(client): security hardening, input validation for request paths - #265

Merged
david-ruiz-cko merged 4 commits into
mainfrom
fix/INT-1771-request-building
Nov 6, 2026
Merged

david-ruiz-cko merged 4 commits into
mainfrom
fix/INT-1771-request-building

Conversation

@david-ruiz-cko

@david-ruiz-cko david-ruiz-cko commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Security hardening: input validation for request paths. Reported internally.

Changes

  • checkout_sdk/client.py: input validation and encoding in the shared path builder (build_path); docstring added.
  • checkout_sdk/payments/sessions/sessions_client.py, checkout_sdk/events/events_client.py: request building moved to the shared helpers.
  • checkout_sdk/apm/sepa_client.py, checkout_sdk/payments/googlepay/googlepay_client.py, checkout_sdk/instruments/instruments_client.py: path constants refactored into single segments; request paths unchanged.
  • README.md: "Exception handling" documents how identifiers are handled.
  • tests/client_test.py: new; path segment encoding and validation tests.
  • tests/compliancerequests/compliance_requests_client_test.py: expects CheckoutArgumentException for a None identifier.

API Reference

None. No operation or schema change; request paths for valid identifiers are unchanged.

Breaking changes ⚠️

  • Client methods raise CheckoutArgumentException before sending when an identifier is not a valid path segment, for example None or empty (None previously raised TypeError). Migration: pass identifiers as returned by the API.
  • Identifiers are encoded by the SDK, so an identifier that is already encoded is encoded again. Migration: pass identifiers unencoded.
  • Client.build_path treats each argument as one path segment. Migration: pass each segment as its own argument.

Tests

  • Existing tests pass
  • Serialization tests cover every new or changed property (no request or response type changed)
  • README updated if documented usage changed

Unit tests added; pytest and flake8 pass.

Related

None.

@david-ruiz-cko
david-ruiz-cko requested a review from a team November 6, 2026 10:25
@agent-wall-e

agent-wall-e Bot commented Nov 6, 2026

Copy link
Copy Markdown

🔴 Risk Classification: MAJOR

Approval route: AI Review + Human Approval Required
Rollback controls: Change-freeze window + documented rollback plan

Classification reasons

  • security_sensitive_path:checkout_sdk/payments/sessions/sessions_client.py

Operational gates

  • ✅ jira_ticket (INT-1771)
  • ✅ independent_review

Files analysed: 9


wall-e 2026.06.19-02 · policy 6b4ce2b3b45a…

@agent-wall-e

agent-wall-e Bot commented Nov 6, 2026

Copy link
Copy Markdown
🔬 Debug — why this classification?

Each reason code emitted by the classifier, its source clause in the AI in SDLC Control Framework, and what it means.

Reason code Kind Clause Meaning
security_sensitive_path — checkout_sdk/payments/sessions/sessions_client.py classifying §2.1 M4/M5 Path matched a sensitive pattern (auth, secrets, crypto, PCI, migrations, network IaC).

Kinds:

  • classifying — this rule contributed to the chosen tier.
  • informational — context only; did not by itself decide the tier.

See issue #3 for the proposal to formalise this map as Appendix A of the standards doc.

wall-e 2026.06.19-02 · debug

@agent-wall-e

agent-wall-e Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

🟢 Advisory review: Looks good to me

This PR still needs a human approval — wall-e cannot auto-approve it. For what it's worth, I read the diff and found nothing I'd block on.

This PR adds input validation and percent-encoding to the shared build_path helper, refactors multi-segment path constants into individual segments, and migrates two clients from string concatenation to build_path. The implementation is correct and the stated intent matches the diff.

What I checked

  • The _encode_path_segment method correctly uses type(value) and issubclass to resist __class__ spoofing, and the str.__getitem__ slice defensively bypasses overridden str methods in subclasses — both are sound techniques for the stated security goal.
  • The empty/dot/dotdot checks occur after encoding (if encoded in ('', '.', '..')), which correctly catches the case where the raw string is . or .. even though those characters pass the regex — the raw-string pre-check (_FORBIDDEN_SEGMENT_CHARACTERS) already catches / and \, and the post-encode check catches . and .. since those encode to themselves.
  • The events_client.py change replaces string concatenation (event-types?version=...) with a proper query-param dict passed to the API client, which is a clean improvement assuming ApiClient.get accepts an optional params argument — the diff doesn't show ApiClient, but the existing retrieve_events call already passes a request object as the third arg, making this consistent.
  • The _ZeroLength test helper overrides __len__, __bool__, __eq__, and __str__ but build_path reads content via str.__getitem__(value, slice(None)) which bypasses all of these, so the test correctly verifies the subclass-bypass logic works.
  • The compliance test update from TypeError to CheckoutArgumentException correctly reflects the new early-rejection behaviour and the match string 'Invalid path segment' aligns with _INVALID_SEGMENT_MESSAGE.
  • The sepa, googlepay, instruments, and sessions refactors produce identical URL paths to the originals — each previously-combined constant is now passed as two separate segments, and build_path joins them with / as before.
  • The README addition accurately describes the validation rules enforced in code (empty, ., .., /, \, ASCII control chars, non-string, UTF-8 failure) and correctly notes that Enum members are sent by value.

⚠️ The diff was too large to read in full, so this review covers only part of the change.


This is not an approval. wall-e cannot auto-approve this PR — it is an opinion to help whoever does. Advisory review · us.anthropic.claude-sonnet-4-6 · wall-e 2026.06.19-02

@agent-wall-e

agent-wall-e Bot commented Nov 6, 2026

Copy link
Copy Markdown

🔴 Risk Classification: MAJOR

Approval route: AI Review + Human Approval Required
Rollback controls: Change-freeze window + documented rollback plan

Classification reasons

  • security_sensitive_path:checkout_sdk/payments/sessions/sessions_client.py

Operational gates

  • ✅ jira_ticket (INT-1771)
  • ✅ independent_review

Files analysed: 9


wall-e 2026.06.19-02 · policy 6b4ce2b3b45a…

@agent-wall-e

agent-wall-e Bot commented Nov 6, 2026

Copy link
Copy Markdown
🔬 Debug — why this classification?

Each reason code emitted by the classifier, its source clause in the AI in SDLC Control Framework, and what it means.

Reason code Kind Clause Meaning
security_sensitive_path — checkout_sdk/payments/sessions/sessions_client.py classifying §2.1 M4/M5 Path matched a sensitive pattern (auth, secrets, crypto, PCI, migrations, network IaC).

Kinds:

  • classifying — this rule contributed to the chosen tier.
  • informational — context only; did not by itself decide the tier.

See issue #3 for the proposal to formalise this map as Appendix A of the standards doc.

wall-e 2026.06.19-02 · debug

@agent-wall-e

agent-wall-e Bot commented Nov 6, 2026

Copy link
Copy Markdown

🔴 Risk Classification: MAJOR

Approval route: AI Review + Human Approval Required
Rollback controls: Change-freeze window + documented rollback plan

Classification reasons

  • security_sensitive_path:checkout_sdk/payments/sessions/sessions_client.py

Operational gates

  • ✅ jira_ticket (INT-1771)
  • ✅ independent_review

Files analysed: 9


wall-e 2026.06.19-02 · policy 6b4ce2b3b45a…

@agent-wall-e

agent-wall-e Bot commented Nov 6, 2026

Copy link
Copy Markdown
🔬 Debug — why this classification?

Each reason code emitted by the classifier, its source clause in the AI in SDLC Control Framework, and what it means.

Reason code Kind Clause Meaning
security_sensitive_path — checkout_sdk/payments/sessions/sessions_client.py classifying §2.1 M4/M5 Path matched a sensitive pattern (auth, secrets, crypto, PCI, migrations, network IaC).

Kinds:

  • classifying — this rule contributed to the chosen tier.
  • informational — context only; did not by itself decide the tier.

See issue #3 for the proposal to formalise this map as Appendix A of the standards doc.

wall-e 2026.06.19-02 · debug

@sonarqubecloud

sonarqubecloud Bot commented Nov 6, 2026

Copy link
Copy Markdown

@david-ruiz-cko
david-ruiz-cko merged commit a95dbdd into main Nov 6, 2026
4 checks passed
@david-ruiz-cko
david-ruiz-cko deleted the fix/INT-1771-request-building branch November 6, 2026 11:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants