Security
Last updated: 2026-05-21
What this page is, and isn't.
Plain-English summary of how xrpldashboard handles data and hardens its surfaces. Not a SOC 2 substitute — SOC 2 readiness is on the roadmap and called out by name in the final section. If you're an institutional buyer running a vendor-security checklist, this page is the honest baseline. Anything not stated here is something we don't do yet.
Transport and headers
- HTTPS only. All traffic is terminated at Cloudflare with HSTS enforced. Plain-HTTP requests are 301'd to HTTPS.
- Content Security Policy. CSP restricts script sources, blocks inline-eval, and refuses mixed content. Every page sets it explicitly — no opt-outs.
- Strict referrer + frame ancestors.
Referrer-Policy: strict-origin-when-cross-origin and X-Frame-Options: DENY are set globally to limit leakage and clickjacking.
- No analytics, no pixels, no widgets. No analytics tracker, no marketing pixels, no embedded widgets, no fingerprinting. Outbound network from the page is limited to the XRPL WebSocket cluster (visible in /methodology) and font/animation libraries described below.
- Vendored front-end libraries. Fonts (Geist) and three animation libraries (Lenis, GSAP, CountUp) currently load from
cdn.jsdelivr.net with SRI integrity hashes. They're open-source presentation code with no analytics or telemetry — but they are third-party origins, so we name them here rather than claim "no third-party scripts." Self-hosting these from /static/vendor/ is in progress.
Admin surface
- HMAC-signed admin tokens. Admin routes accept only requests signed with a server-side secret. There is no public admin login form, no password-reset endpoint, and no session cookie that can be replayed.
- Per-IP rate limits. Every public endpoint that returns data has an explicit rate limit, keyed by Cloudflare's authoritative client IP. No global default — limits are written per-route so health checks and HTML pages stay unthrottled.
- No write surface from the public web. The Flask app reads from Postgres; only the workers running on Charlie's Mac (or the standby Render worker) can write. A leaked DB credential on the Flask side cannot mutate state.
Data classification
- No user accounts. Nothing to register for. No email/password on file. No "sign in with X".
- No wallets-of-record. We do not custody, sign for, or hold private keys for any address. Wallet pages are read-only views of the public ledger.
- No PII collection. No analytics tracker, no fingerprinting library, no marketing email list. The only inbound email is the contact form, which goes to a single inbox.
- Standard server logs only. IP, user agent, path. Aggregated into a public view at /analytics — country/browser/path counts, no per-visitor tracking. Used for abuse prevention and uptime monitoring, not behavioral tracking. See /privacy for the full data inventory.
Infrastructure
- Cloudflare sits in front of everything — DDoS absorption, WAF, IP-level rate-limit fallback. CDN cache is honored for static assets only.
- Render hosts the Flask app. Container is rebuilt on every push to
main. No SSH access to the running container.
- Neon Postgres holds time-series and aggregate data. Connections are TLS-only with separate reader and writer credentials; the Flask app uses the reader credential.
- Regions. Render app and Neon database run in geographically aligned regions to minimize cross-border data transit. Cloudflare's edge is global by design.
- Full vendor list is at /subprocessors — what each one sees, where they run, and their DPA.
Disclosure and contact
- /.well-known/security.txt points to the contact address and renewal expiry, per RFC 9116.
- Coordinated disclosure. Email contact@xrpldashboard.com with reproducible findings. We will acknowledge within one business day and credit researchers who request it.
- No bug-bounty program yet. See the final section below.
Source and reproducibility
The methodology page at /methodology discloses every data source, cache TTL, and known limitation. Every number on the site is derivable from those sources — no proprietary feed, no opaque scoring model. If a value is wrong, the audit trail is public.
What we don't do yet
Named gaps, in the same voice as /methodology's known limitations. Listing them is more useful to a buyer than omitting them.
- SOC 2. No Type I or Type II report on file. The control set this page describes is what a Type I would attest to today; formal audit is a 6–12 month commitment we plan to start once a launch partner names it as a hard requirement.
- Third-party penetration test. No formal pentest report yet. Surface is small (read-only Flask, no auth, no write endpoints from the public web) but "small" is not the same as "audited".
- Bug-bounty program. No paid bounty. Coordinated disclosure via the contact address above is the current path; we credit researchers who want it.
- SSO / SAML. No user accounts means no SSO surface today. If a paid tier ships with per-user logins, SSO will be a launch requirement, not an upsell.
- Formal incident-response runbook. Workers self-recycle on common faults and a heartbeat alarm chain pages Charlie on stalls. A written, tested runbook is in draft and will be linked here once the first real incident is reviewed.
Questions
Send anything specific to contact@xrpldashboard.com. If you're a vendor-security analyst working through a checklist, attach the checklist — it's faster than the back-and-forth.