Evidence: security scans, security tests and performance baseline (2026-10-30)
Dependency and image scans
- govulncheck: 12 reachable stdlib/x/net findings fixed (Go 1.27.3, golang.org/x/net v0.62.0); 0 reachable now. 3 unreachable, no fix available: aws-sdk-go v1 S3 crypto client (x2, via the Stellar SDK data-lake support), x/crypto.
- pnpm audit (prod and all): Next.js 16.3.8 had 2 critical RCE + 1 high DoS advisories → upgraded to 16.4.3 in all four apps; now "No known vulnerabilities". The Ethereum sibling still runs 16.3.8.
- gosec: 32 findings triaged (bounded integer conversions, config-driven cookie Secure, RFC 6238 HMAC-SHA1, public manifest file); 2 hardened (explicit fee cap in FeePerOp, Friendbot body close).
- Grype on the demo images, first pass: built before the Next.js upgrade (next 16.3.8), plus undici 6.28.0 and brace-expansion 5.0.9 (High) from the node:24-alpine base's bundled npm.
- Grype after rebuilding all five images (Next 16.4.3, npm/corepack/yarn removed from the web runtime stage, Go 1.27.3
with x/net 0.62.0 and go-jose 4.1.6): api 0 findings; landing, wallet, admin, scan 3 Medium each, all
CVE-2025-60876 in busybox 1.37.0-r31 (base image, no fixed version yet). No Critical or High.
Build note: the company npm mirror answers 500 for Next 16.4.3 and container DNS fails here, so images were built
with
podman build --network=hostandNPM_REGISTRY=https://registry.npmjs.org/(R2-04). - SBOMs: docs/security/sbom/backend.cdx.json (CycloneDX, Go), docs/security/sbom/web.cdx.json (Syft, 567 components).
Security tests (local Stellar + PostgreSQL)
TestHTTPSecurity: auth bypass, customer session on the admin listener, role bypass and privilege escalation (auditor, operator), operator self-approval, CSRF, IDOR (404), duplicate financial request (byte-exact replay — found jsonb reordering, fixed by migration 00010), used quote refused, price move above max needs a second operator. TestFailoverPastADeadNode, TestAllNodesDownThenRecover, TestOutageClosesTradingAndIndexerCatchesUp, TestConcurrentBuysNeverOversellTheHotFloat, TestClawback (incl. Dara Scan and SEP-1 stellar.toml checks).
Performance baseline (PERF=1 TestPerformanceBaseline; 16 CPUs, loaded host, local Quickstart)
| Operation | p50 | p95 | p99 | throughput /s |
|---|---|---|---|---|
| GET /v1/assets | 1.07ms | 1.93ms | 3.53ms | 6484 |
| GET /v1/me/balances | 1.9ms | 2.73ms | 3.55ms | 4023 |
| POST /v1/quotes (40 customers) | 6.83ms | 20.6ms | 55.5ms | 823 |
| ledger posting (2 legs) | 41.6ms | 93.3ms | 113ms | 173 |
| BUY accept over HTTP | 68.7ms | 119.6ms | 132.5ms | 77 |
| BUY settlement on-chain, 60 orders, 3 channels | — | — | — | 2.0 |
| indexer catch-up | — | — | — | 54 ledgers/s |
| reconciliation run (1 asset) | 56ms | 81ms | 81ms | 16 |
Bottleneck: on-chain settlement = channels ÷ ledger close time (one transaction per channel per ledger). Mainnet (~5.5 s ledgers) with 3 channels ≈ 0.5 settlements/s; size channels to peak BUY/SELL rate × 6 s (e.g. 20 channels ≈ 3.5/s) or batch payments per transaction. Per-customer and per-IP rate limits held throughout.