Documentation
Security
Quick start newArchitectureGatewaysHTTP APIPrepayment and rulesFiscal receiptsNotifications and CRMPayment linksAnalytics newPolandNative Shopify gatewaySecurity new
Model
- Card data never touches the server (gateway hosted pages) — PCI DSS SAQ A.
- Every webhook is verified cryptographically (ECDSA, HMAC, RSA, SHA-384/SHA1 per the gateway’s scheme) with a timing-safe comparison; the status is re-read from the API.
- Buyer links are protected by the order’s confirmation number or a 96-bit token; order ids cannot be enumerated (403/404, rate limit).
- One transaction per payment (mutex + flag), Shopify webhook dedup, 256 KB body limit, generic errors without stack traces.
- Admin — behind a key with a timing-safe comparison, 404 without the key,
noindex.
Pentest suite (in the repository, npm run pentest)
| Class | Checks |
|---|---|
| Webhook forgery | no signature, garbage, wrong key, signature from another body, +1 byte, replay ×10 in parallel, stale timestamp (Stripe) |
| Amount/status tampering | a signed “success” while the API says created; underpayment → unpaid + tag; currency |
| Enumeration and access | /pay without/with a wrong c, huge parameters, path traversal, GID as id, other people’s/paid/COD orders, unknown link tokens |
| Races | 15 parallel /pay → one invoice; 10 parallel success → one transaction |
| Shopify HMAC | missing/empty/wrong/truncated HMAC, webhook id replay, hostile payloads in orders/create |
| DoS, leaks, injections | 300 KB body, deep JSON, flood of bad signatures (no pubkey storm), 502 from Shopify → generic 500, CRLF/XSS/SQL in names |
Current state: 88 pentest checks + 111 functional + 698 unit — all green; npm audit with no vulnerabilities. Full report — PENTEST.md.
Security panel and webhook inspector new
- Admin → 🛡️ Security (owner): failed logins over 7 days by IP and login, locked IPs with an “unlock” button, active sessions (who, IP, browser, time) with “end” per session or “end all others” — e.g. after a leaked password; protection posture (2FA, .env login, HTTPS cookie, ?key=). Sessions live in the database: a revoked one dies at once, logout revokes too.
- Admin → 📥 Webhooks: every incoming PSP and Shopify webhook — signature result, matched order, our reply, duration, IP, headers (secrets masked) and body; filters by source and signature; “↻ replay” re-syncs the order. The tab badge counts bad signatures in the last 24 h. The newest 2000 are kept (
WEBHOOK_LOG_KEEP).
System health new
- Admin → 🩺 Health: ok / warn / critical with the list of issues; process (uptime, memory, event-loop lag), SQLite (
quick_check, size, WAL), disk, age of the last backup, incoming webhooks over 24 h, outgoing events in retry, pending receipts, failed refunds, per PSP — created/paid/failed and the last reason; “Live PSP check” measures each gateway's latency. Recent process errors are shown on the page. - JSON for monitoring:
GET /admin/api/health?full=1(503 when critical),?deep=1adds the live probes. Telegram:/health,/health psp. - Watchdog every 5 min: one Telegram message when the status turns critical and one on recovery (
HEALTH_WATCH=offdisables).
Residual risks (infrastructure)
- HTTPS/HSTS at the edge,
TRUST_PROXY=1behind nginx/Cloudflare — otherwise the rate limiter sees everyone as one IP. - Secrets in
.envwith 600 permissions or a secret manager; rotation ofADMIN_KEY, webhook secrets, gateway tokens. - The Shopify Admin token (
write_orders) — minimal scopes, a separate custom app. - Live gateway sandboxes are not reachable from our development environment: signatures were checked against the official formulas and SDKs; a first run on test keys is mandatory.