Skip to content

Commit

Permalink
SEP-24: Add callback signature requirement (#1263)
Browse files Browse the repository at this point in the history
* SEP-24: Add callback signature requirement

If a callback is used, it needs to be signed by the Anchor so that the Wallet can verify the provenance and integrity.

* SEP-24: Bump date and version

* SEP24: Correct markdown typo

* SEP-24: Remove UI from callback signature

Co-authored-by: Howard Tinghao Chen <[email protected]>

* SEP-24: Signature only for URL callbacks

The callback signature discussed here does not apply to postMessage type callbacks

Co-authored-by: Howard Tinghao Chen <[email protected]>
  • Loading branch information
C0x41lch0x41 and howardtw authored Aug 19, 2022
1 parent aa3f665 commit d61005b
Showing 1 changed file with 54 additions and 4 deletions.
58 changes: 54 additions & 4 deletions ecosystem/sep-0024.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Title: Hosted Deposit and Withdrawal
Author: SDF
Status: Active
Created: 2019-09-18
Updated: 2022-06-08
Version 2.5.0
Updated: 2022-08-19
Version 2.6.0
```

## Simple Summary
Expand Down Expand Up @@ -87,6 +87,52 @@ In order for browsers-based wallets to validate the CORS headers, as [specified

This protocol involves the transfer of value, and so HTTPS is required for all endpoints for security. Wallets and anchors should refuse to interact with any insecure HTTP endpoints.

## URL Callback signature

_Note that the signature discussed here is only for **URL callbacks** and does not apply to **`postMessage` callbacks**_

This protocol involves the optional use of URL callbacks that the Anchor can issue to update the wallet on ```status``` of a transaction.
In order to validate the integrity and provenance of the callback, the Anchor MUST include a signature in an additional HTTP Header `X-Stellar-Signature`.
This Header MUST follow the specification: `X-Stellar-Signature: t=<timestamp>, s=<base64 signature>` where:
* __timestamp__ is the current Unix timestamp (number of seconds since epoch) at the time the callback is sent. This is used to assure the freshness of the request and to prevent this request to be replayed in the future.
* __base64 signature__ is the base64 encoding of the request signature. We explain below how to compute and verify this signature. The signature is computed using the Stellar private key linked to the `SIGNING_KEY` field of the anchor's [`stellar.toml`](sep-0001.md). Note that the timestamp and the Wallet hostname will be part of the signature to prevent replay and relay attacks.

It is the wallet's responsability to:
* Verify the signature using the corresponding Stellar `SIGNING_KEY` field of the anchor's [`stellar.toml`](sep-0001.md).
* Verify the freshness of the request by comparing the `timestamp` in the request with the current timestamp at the time of the reception and discard every request above a threshold of few seconds (1 or 2 minute(s) maximum).
* Send a working callback URL (parameter ```callback``` or ```on_change_callback```) to the anchor.

### VERIFY signature

* Check that callback request has `X-Stellar-Signature` header
* Parse the header and extract:
* Key `t`: __timestamp__
* Key `s`: __base64 signature__
* Verify the request freshness: _current timestamp_ - __timestamp__ < few seconds (1-2 minute(s) max)
* Extract the __body__ of the request
* Base64 decode the __base64 signature__ to get the __signature__
* Prepare the payload to verify the signature:
* The __timestamp__ (as a string)
* The character `.`
* The wallet host to send the callback request to
* The character `.`
* The __body__
* Verify the signature using the correct `SIGNING_KEY`

### COMPUTE signature

* Prepare the callback
* Prepare the payload to sign:
* Current timestamp (as a string)
* The character `.`
* The wallet host to send the callback request to
* The character `.`
* The callback request body
* Sign the payload `<timestamp>.<host>.<body>` using the Anchor private key
* Base64 encode the signature
* Build the `X-Stellar-Signature` header:
* `X-Stellar-Signature: t=<current timestamp>, s=<base64 encoded signature>`

## Content Type

All endpoints accept in requests the following `Content-Type`s:
Expand Down Expand Up @@ -380,8 +426,8 @@ The basic parameters are summarized in the table below.

Name | Type | Description
-----|------|------------
`callback` | string | (optional) [`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) or a URL that the anchor should `POST` a JSON message to when the user successfully completes the interactive flow.
`on_change_callback` | string | (optional) [`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) or a URL that the anchor should `POST` a JSON message to when the `status` or `kyc_verified` properties change.
`callback` | string | (optional) [`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) or a URL that the anchor should `POST` a JSON message to when the user successfully completes the interactive flow. If the callback is a URL (not a `postMessage`), it needs to be signed by the anchor and the signature needs to be verified by the wallet according to the [callback signature specification](#callback-signature).
`on_change_callback` | string | (optional) [`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) or a URL that the anchor should `POST` a JSON message to when the `status` or `kyc_verified` properties change. If the callback is a URL (not a `postMessage`), it needs to be signed by the anchor and the signature needs to be verified by the wallet according to the [callback signature specification](#callback-signature).

The URL supplied by both callback parameters should receive the full transaction object.

Expand All @@ -402,6 +448,8 @@ Because `callback` is used to notify the wallet that the interactive flow is com
Wallet applications display content rendered by a third party anchor service. It is recommended to use the [`rel=noopener`](https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/noopener) attribute on links or the `noopener` feature for [`Window.open()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/open#window_functionality_features).

Note that using `noopener` prohibits the use of `postMessage` callbacks. If `postMessage` callbacks are required for your implementation, it recommended to only open URLs from anchors that you, the wallet developer, trust.

To validate the provenance and integrity of the callback, anchors [must sign it](#callback-signature) and wallet servers must validate the signature before taking any action.

**Differences between `callback` and `on_change_callback`**

Expand Down Expand Up @@ -939,6 +987,8 @@ There is a small set of changes when upgrading from SEP-6 to SEP-24.
* Solar wallet: https://solarwallet.io

## Changelog

* `v2.6.0`: Add callback signature and verification requirement. ([#1263](https://github.com/stellar/stellar-protocol/pull/1263))
* `v2.5.0`: Add `expired` transaction status. ([#1233](https://github.com/stellar/stellar-protocol/pull/1233))
* `v2.4.0`: Add `refunded` transaction status. ([#1195](https://github.com/stellar/stellar-protocol/pull/1195))
* `v2.3.0`: Change `lang` format from [ISO639-1](https://en.wikipedia.org/wiki/ISO_639-1) to [RFC4646](https://datatracker.ietf.org/doc/html/rfc4646) which is a superset of ISO639-1. Add `lang` field to GET `/transactions` and `/transaction`. ([#1191](https://github.com/stellar/stellar-protocol/pull/1191))
Expand Down

0 comments on commit d61005b

Please sign in to comment.