You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit d73b20d
Browse filesBrowse the repository at this point in the historyBrowse files
5.**Size**: the document is at most 100 KB (the SEP-0001 limit)
159
+
160
+
### Payload sanitization and strict validation (issue #1457)
161
+
162
+
Every value comes from the merchant record or server environment, and the
163
+
generator treats all of it as untrusted.
164
+
165
+
| Input | Rule | If invalid |
166
+
|---|---|---|
167
+
|`merchant_id` query param | Single value, must be a UUID |`400`. The database is not queried. |
168
+
|`business_name`| Bidi override characters (U+202A–202E, U+2066–2069, U+200E/F) stripped, trimmed, max 256 characters | Falls back to `Stellar Payment Merchant` when empty or not a string |
169
+
| All string values | TOML-escaped, including `\r`, `\t`, and every other control character (`\uXXXX`) | A value can never close its quotes and inject keys or `[TABLES]`|
170
+
|`recipient` → `ACCOUNTS`| Valid Stellar public key, StrKey checksum included |`ACCOUNTS` omitted |
171
+
|`SIGNING_KEY`| Valid Stellar **public** key | Omitted. A secret seed is never published and is logged as an error (without the value). |
172
+
|`email`, `notification_email`| Email syntax, max 254 characters | Field omitted |
173
+
|`branding_config.homepage` / `logo_url`|`https` URL, no credentials, no whitespace, max 2048 characters | Field omitted |
174
+
|`TRANSFER_SERVER_URL` / `API_BASE_URL`|`https` URL. `http` is allowed only for `localhost`/`127.0.0.1`. No credentials. |`500 Failed to generate valid stellar.toml`. Details are logged, never returned. |
175
+
|`FEDERATION_SERVER_URL`, `DOCS_URL`| Same URL rules | Field omitted |
176
+
|`STELLAR_NETWORK_PASSPHRASE`| Printable, max 128 characters |`500`, as above |
177
+
178
+
Omitted or altered fields are logged (`SEP-0001: fields omitted or altered by
179
+
sanitization`) and counted in `sep0001_rejected_fields_total{field,reason}`.
180
+
181
+
Responses also send `Access-Control-Allow-Origin: *`, which SEP-0001 requires
182
+
so browser wallets can read the file, and `X-Content-Type-Options: nosniff`.
# WebSocket Relay Service: integration and stress tests
2
+
3
+
Issue #1456.
4
+
5
+
| Suite | File | What it proves |
6
+
|---|---|---|
7
+
| Integration |`src/lib/websocket-relay.integration.test.js`| The real security, query, recovery and metrics modules wired as a relay worker: handshake (origin allow-list, HS256-pinned JWT, `alg: none`/expired/wrong-secret rejection), frame size limit, unknown/prototype-polluting field stripping, parameterised batch insert, FIFO dequeue, delivery through the circuit breaker, `markEventComplete`/`markEventFailed`, dead-lettering, HALF_OPEN recovery and DLQ replay, DB failure wrapping, pagination clamps, reconnect backoff, and audit log integrity |
8
+
| Stress |`src/lib/websocket-relay.stress.test.js`| 50 concurrent consumers drain 2,000 events with every event claimed exactly once; interleaved async latency never double-claims; a 1,000-row single-statement insert; 10,000 frames sanitized; oversized-frame floods; byte-accurate size checks for multi-byte text; 1,000 concurrent fast-fails on an open circuit; 10,000 mixed breaker outcomes; a 10,000-entry DLQ in FIFO order; 200 concurrent reconnect loops staying under the delay cap |
9
+
10
+
Only Postgres is faked. `tests/helpers/fake-relay-db.js` interprets the exact
11
+
SQL emitted by `websocket-relay-queries.js`. Each statement applies
12
+
atomically, mirroring `FOR UPDATE SKIP LOCKED` row locking, so the
13
+
exactly-once assertions test the claiming logic rather than the fake.
14
+
15
+
Timing assertions in the stress suite are deliberately loose. They catch
16
+
pathological regressions (quadratic or blocking behaviour), not small slowdowns.
17
+
18
+
## Finding fixed
19
+
20
+
`auditRelayEvent()` spread caller metadata **after** the fixed fields, so
21
+
metadata containing `audit`, `ts` or `event` (for example values echoed from
22
+
a client) could overwrite them and forge an audit line. Metadata is now
0 commit comments