Skip to content

Conversation

@joyceqin-stripe
Copy link
Collaborator

@joyceqin-stripe joyceqin-stripe commented Oct 29, 2025

Summary

Add an AttestationChallenge wrapper around StripeAttest that prewarms attestation on init and fetches an assertion with a timeout.

Wrap PassiveCaptchaChallenge and AttestationChallenge in ConfirmationChallenge. Anywhere we previously passed PassiveCaptchaChallenge, we now pass in ConfirmationChallenge. ConfirmationChallenge creates the passive captcha and attestation challenges asynchronously in parallel and fetches their tokens with timeout in parallel and creates the radar options for the requests.

Added playground switch so that we can test with/without attestation, similar to the passive captcha switch. Will be removed on release.

Moved PassiveCaptchaChallenge into StripePaymentSheet, @_spi(STP) HCaptcha

Motivation

Attestation support for HCaptcha project

Testing

Added tests
Example request: https://admin.corp.stripe.com/request-log/req_YXMjaq42sec9gb

Changelog

N/A

@github-actions
Copy link

github-actions bot commented Oct 29, 2025

⚠️ New dead code detected in this PR but ignored:

MockAppAttestService.swift:47 warning: Function 'setAttestationDelay(_:)' is unused
MockAppAttestService.swift:51 warning: Function 'setAssertionDelay(_:)' is unused
ConfirmationChallenge.swift:18 warning: Function 'setTimeout(timeout:)' is unused

This dead code check has been bypassed with the skip dead code check label.

ℹ️ If this comment appears to be left in error, double check that the flagged code is actually used and/or make sure your branch is up-to-date with master.

[find-dead-code]

A3B2F2B82CF1343F00C0E88C /* SavedPaymentMethodFormFactory+USBankAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3B2F2B72CF1343F00C0E88C /* SavedPaymentMethodFormFactory+USBankAccount.swift */; };
A3B2F2BA2CF134B500C0E88C /* SavedPaymentMethodFormFactory+SEPADebit.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3B2F2B92CF134B500C0E88C /* SavedPaymentMethodFormFactory+SEPADebit.swift */; };
A3BE1C242D4161DC0061632C /* RemoveButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3BE1C232D4161DC0061632C /* RemoveButton.swift */; };
A3DA75572EB20ECE00FFFCC9 /* AttestationChallenge.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3DA75562EB20ECE00FFFCC9 /* AttestationChallenge.swift */; };
Copy link
Contributor

Choose a reason for hiding this comment

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

You can remove these changes, the xcodeproj will now pull in source files automatically

@joyceqin-stripe joyceqin-stripe changed the base branch from master to joyceqin/introduce-attestation-challenge October 30, 2025 14:48
if let keyId = storedKeyID {
return keyId
}
// Check if another task is already generating a key
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Found a race condition— if you initialize AttestationChallenge and immediately try to fetch the assertion, both the prepareAttestation() and assert() functions will read a nil stored key and try and generate a key, overwriting each other and leading to a state mismatch later (client thinks we've attested because we did for one key, but the other key fetches the challenge from the server and gets that it needs to be attested)

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, good catch!

attestationUsingDevelopmentEnvironment = value
}

func setAttestationDelay(_ delay: TimeInterval) async {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Test-only to inject delays to force timeout

@joyceqin-stripe joyceqin-stripe changed the base branch from joyceqin/timeout to master November 10, 2025 17:39
@joyceqin-stripe joyceqin-stripe marked this pull request as ready for review November 12, 2025 18:10
@joyceqin-stripe joyceqin-stripe requested review from a team as code owners November 12, 2025 18:10
@joyceqin-stripe joyceqin-stripe merged commit 3724810 into master Nov 12, 2025
8 checks passed
@joyceqin-stripe joyceqin-stripe deleted the joyceqin/confirmation-challenge branch November 12, 2025 19:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants