Skip to content

Harden API requestor code against malicious URLs - #2284

Merged
xavdid merged 3 commits into
masterfrom
RUN_DEVSDK-2808
Aug 31, 2026
Merged

xavdid merged 3 commits into
masterfrom
RUN_DEVSDK-2808

Conversation

@xavdid

@xavdid xavdid commented Aug 28, 2026 •

Copy link
Copy Markdown
Member

Why?

If an attacker got access to a user's webhook secret (or the user wasn't validating incoming webhook signatures) and a user was calling the built-in event_notification.fetch_related_object() method, a malicious webhook payload could cause a user integration to make an authenticated request to an attacker-controlled domain (leaking the secret key)

To solve, we're being more careful during url construction to ensure user input can't be used to send requests to non-stripe.com domains (on a per-request basis).

What?

  • add path validation method and call it before the final URL is built
  • Encode the event.id path param in fetch_event() to match the sanitation in the rest of the generated endpoints
  • add tests

See Also

@xavdid
xavdid marked this pull request as ready for review August 28, 2026 21:23
@xavdid
xavdid requested a review from a team as a code owner August 28, 2026 21:23
@xavdid
xavdid requested review from jar-stripe and removed request for a team August 28, 2026 21:24
@xavdid
xavdid enabled auto-merge (squash) August 28, 2026 21:24

@jar-stripe jar-stripe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving to unblock. Change looks good, but the comments are a bit length and repetative

Comment thread src/main/java/com/stripe/net/LiveStripeResponseGetter.java
Comment thread src/test/java/com/stripe/net/OriginRelativePathTest.java Outdated
@xavdid
xavdid merged commit e4f0ec3 into master Aug 31, 2026
18 checks passed
@xavdid
xavdid deleted the RUN_DEVSDK-2808 branch August 31, 2026 21:27
jar-stripe added a commit that referenced this pull request Sep 28, 2026
* Add discriminated union serialization tests (#2260)

* Add discriminated union serialization tests

Tests both request-side (params → map) and response-side (JSON → object)
serialization for discriminated unions, covering standalone and inline
variants.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Committed-By-Agent: claude

* Add null assertions for non-selected DU variants

Assert that when one variant is selected, the other variant fields/structs
remain null in both serialization and deserialization tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Committed-By-Agent: claude

* Fix response standalone DU test to use proper class hierarchy

Restructure the response-side test fixtures from a flat TestColorEntity
class (holding all variant fields) to a proper class hierarchy:
TestColorEntity (base) -> TestRgbColorEntity / TestHsvColorEntity.

Add a TestColorTypeAdapterFactory that dispatches deserialization to the
correct subclass based on the `model` discriminator field, mirroring how
the codegen will emit TypeAdapterFactory-based dispatch for real DUs.

Update assertions to use instanceof checks and typed casts rather than
checking for null fields on a flat class. Add a second test covering the
HSV variant path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Committed-By-Agent: claude

* fixed formatting

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* Carry private-preview's CI workflow hunks on master (#2283)

private-preview's ci.yml differs from master's by exactly two additive
hunks: `private-preview` in `on.push.branches`, and a `base:` input on the
stripe-mock step mapping every private-preview context onto the beta spec.

Because those hunks live only on private-preview, every merge of master into
private-preview yields a ci.yml matching neither parent. GitHub refuses a
push from a GitHub App lacking `workflows` permission when it introduces a
workflow blob that does not already exist in the repository, so the codegen
job's push is rejected and a human has to perform the merge by hand. Holding
the hunks on master too means both sides of the merge carry the same change,
the merge result is byte-identical to master's blob, and the App only ever
carries an already-committed file forward.

Both hunks are no-ops on master:

- For a push event the workflow file comes from the pushed ref, so master's
  copy listing private-preview cannot affect pushes to master or beta.
- The base: expression falls through to `github.base_ref || github.ref_name`
  for every master-side ref, which is character-identical to the default
  declared by stripe/openapi/actions/stripe-mock.

Committed-By-Agent: claude

* Harden API requestor code against malicious URLs (#2284)

* validate that incoming urls don't redirect requests

* shorten comments

* Bump version to 33.4.1

* validate that webhook secrets are non-empty (#2286)

* Bump version to 33.4.2

* support related singleton objects (#2288)

* Migrate changelog management to `hark` (#2289)

* migrate to hark

* tweak issue template

* point the hark actions at master

* point at the renamed check-github-links action

* use the single hark/checks action in CI

* use the hark checks action and rename pr_link to pr_url

* record language and channel in versions.json metadata

* rename versions.json to releases.json

* regenerate changelogs; pad short versions

* add a minimum-runtime-version recipe

Committed-By-Agent: claude

* add print-version-info recipe

* swap from is_breaking to semver_level

* trigger CI for hark v1.0.0

* add missing changefile

* rename changefiles that don't adhere to new naming rules

* Fix event handler account scoping (#2294)

* Fix event handler account scoping

Committed-By-Agent: codex
Co-authored-by: codex <noreply@openai.com>

* Add PR URL to changefile

Committed-By-Agent: codex
Co-authored-by: codex <noreply@openai.com>

---------

Co-authored-by: codex <noreply@openai.com>

* Add option to suppress Stripe notices (#2293)

* Add option to suppress Stripe notices

Committed-By-Agent: codex
Co-authored-by: codex <noreply@openai.com>

* Add changelog entry for notice suppression

Committed-By-Agent: codex
Co-authored-by: codex <noreply@openai.com>

* Make Stripe notice integration test environment-independent

Committed-By-Agent: codex
Co-authored-by: codex <noreply@openai.com>

* Clarify Stripe notice suppression instructions

Committed-By-Agent: codex
Co-authored-by: codex <noreply@openai.com>

---------

Co-authored-by: codex <noreply@openai.com>

* Document Stripe notice suppression (#2297)

Committed-By-Agent: goose
Orbit-Session-Id: d60d503e-7c8a-4aa0-89d1-37cc435afc02

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: David Brownman <1231935+xavdid@users.noreply.github.com>
Co-authored-by: Zachary Chua <zacchua@stripe.com>
Co-authored-by: David Brownman <xavdid@stripe.com>
Co-authored-by: codex <noreply@openai.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants