Threat Model: Merchant Portal¶
Status: Draft | Owner: Security Team | Last Updated: 2026-04-03 Methodology: STRIDE | Scope: Merchant-facing web portal and administrative functions
Overview¶
STRIDE threat analysis for Simpaisa's Merchant Portal — the web application through which merchants manage their payment integration, view transactions, configure webhooks, manage API keys, and administer team access. The portal is a high-value target as it provides direct access to financial operations and sensitive configuration.
Data Flow Diagram¶
┌──────────────┐ HTTPS ┌──────────┐ HTTPS ┌───────────┐
│ Merchant │───────────▶│ CDN / │───────────▶│ Portal │
│ Browser │ (TLS 1.3) │ WAF │ │ Frontend │
└──────────────┘ └──────────┘ │ (SPA) │
│ └─────┬─────┘
│ │
│ OIDC │ REST API
▼ ▼
┌──────────────┐ ┌───────────┐
│ControlPlane │◀──── OIDC federation ─────────────│ Portal │
│ IdP (OIDC) │ │ Backend │
└──────────────┘ └─────┬─────┘
│
┌─────────────────────────────────────┤
│ │ │ │
▼ ▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐
│ Auth / │ │Transaction│ │ Webhook │ │API Key │
│ Session │ │ Search │ │ Config │ │ Mgmt │
│ Service │ │ Service │ │ Service │ │Service │
└──────────┘ └──────────┘ └──────────┘ └────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────────────────────────────────────────┐
│ SurrealDB │
└─────────────────────────────────────────────────┘
Attack Surfaces¶
| Surface | Entry Point | Trust Level |
|---|---|---|
| Authentication flow | OIDC login via ControlPlane | Unauthenticated |
| API key management | Portal backend API | Authenticated |
| Webhook configuration | Portal backend API | Authenticated |
| Transaction search | Portal backend API | Authenticated |
| Team user management | Portal backend API | Privileged |
| Session management | Browser cookies / tokens | Client-side |
STRIDE Analysis¶
S — Spoofing¶
| ID | Threat | Likelihood | Impact |
|---|---|---|---|
| S-PT-1 | Credential stuffing | High | High |
| S-PT-2 | Session hijacking (token theft) | Medium | Critical |
| S-PT-3 | Phishing for portal credentials | High | High |
S-PT-1: Credential stuffing - Attack: Attacker uses leaked credentials from other breaches to attempt login to merchant portal accounts. - Mitigation: - MFA mandatory for all portal users (TOTP or WebAuthn) - ControlPlane.com IdP handles authentication with brute-force protection - Account lockout after 5 failed attempts (30-minute window) - Breached password detection (HaveIBeenPwned API integration) - IP-based rate limiting on login endpoint (10 attempts/min per IP)
S-PT-2: Session hijacking - Attack: Attacker steals session token via XSS, network sniffing, or malware to impersonate a logged-in user. - Mitigation: - HTTP-only, Secure, SameSite=Strict cookies - Session bound to IP address and user agent (re-auth on change) - Short-lived access tokens (15 min) with refresh token rotation - Sensitive actions (disbursement, key management) require MFA step-up
S-PT-3: Phishing - Mitigation: Custom domain with HSTS preload. Security awareness programme for merchant users. Login notifications sent on new device/location.
T — Tampering¶
| ID | Threat | Likelihood | Impact |
|---|---|---|---|
| T-PT-1 | XSS in transaction search results | Medium | High |
| T-PT-2 | CSRF on webhook URL change | Medium | High |
| T-PT-3 | Parameter tampering on API requests | Medium | High |
T-PT-1: XSS (transaction search)
- Attack: Merchant reference fields or transaction metadata containing malicious JavaScript rendered without sanitisation in the search results page, executing in the context of another portal user's session.
- Mitigation:
- Output encoding on all rendered fields (React's default JSX escaping)
- Content Security Policy (CSP) with strict nonce-based script policy
- No dangerouslySetInnerHTML usage; all dynamic content via safe bindings
- Input validation: merchant reference fields restricted to alphanumeric + limited punctuation
- Regular automated XSS scanning (DAST)
T-PT-2: CSRF (webhook URL change) - Attack: Attacker crafts a malicious page that, when visited by an authenticated portal user, silently changes their webhook URL to an attacker-controlled endpoint — intercepting all webhook notifications. - Mitigation: - SameSite=Strict cookies prevent cross-origin cookie inclusion - CSRF token on all state-changing requests (synchroniser token pattern) - Webhook URL changes require MFA re-authentication - Notification email sent on webhook URL modification - 24-hour cooling period before new webhook URL receives events
T-PT-3: Parameter tampering - Attack: Modifying request parameters (merchantId, userId, amount) in browser dev tools. - Mitigation: Server-side authorisation for every request. merchantId derived from session — never from client. Input validation with strict schemas (Go struct validation). Rate/amount limits enforced server-side.
R — Repudiation¶
| ID | Threat | Likelihood | Impact |
|---|---|---|---|
| R-PT-1 | Disputed configuration changes | Medium | Medium |
| R-PT-2 | API key creation/revocation disputes | Low | High |
R-PT-1: Configuration change disputes - Mitigation: All portal actions logged with user ID, IP address, timestamp, and before/after values. Audit log accessible to merchant admins. Immutable AuditEntry in SurrealDB.
R-PT-2: API key disputes
- Mitigation: Key creation and revocation events generate email notifications to all merchant admins. Full audit trail with createdBy/revokedBy attribution.
I — Information Disclosure¶
| ID | Threat | Likelihood | Impact |
|---|---|---|---|
| I-PT-1 | Transaction data exposure via IDOR | Medium | Critical |
| I-PT-2 | API key exfiltration | Medium | Critical |
| I-PT-3 | Error message information leakage | Medium | Medium |
I-PT-1: Transaction IDOR - Attack: Attacker modifies transaction ID in URL/API request to view another merchant's transaction details. - Mitigation: All data queries scoped to authenticated merchantId at database query level. SurrealDB row-level security policies enforce tenant isolation. Direct object reference validation on every endpoint.
I-PT-2: API key exfiltration
- Attack: Attacker compromises a portal session and extracts API keys for use outside the portal.
- Mitigation: Raw API keys shown once at creation (modal with copy button, never in DOM after close). Only keyPrefix (first 8 chars) displayed in key listing. Keys cannot be retrieved after creation — only revoked and re-created. Key listing page requires MFA step-up authentication.
I-PT-3: Error leakage - Mitigation: Generic error messages returned to frontend. Stack traces and internal details logged server-side only. Custom error boundary in React SPA prevents rendering of raw error objects.
D — Denial of Service¶
| ID | Threat | Likelihood | Impact |
|---|---|---|---|
| D-PT-1 | Transaction search abuse (expensive queries) | Medium | Medium |
| D-PT-2 | Login endpoint abuse | High | Medium |
D-PT-1: Search abuse - Attack: Crafting broad date ranges or wildcard searches that generate expensive database queries, degrading portal performance for all users. - Mitigation: Maximum date range enforced (90 days). Query timeout (5 seconds). Pagination mandatory (max 100 results per page). Result count estimation before execution. Search queries run against read replica.
D-PT-2: Login abuse - Mitigation: Rate limiting at WAF/CDN layer. CAPTCHA after 3 failed attempts. Account lockout with exponential backoff. ControlPlane.com IdP provides DDoS protection on auth endpoints.
E — Elevation of Privilege¶
| ID | Threat | Likelihood | Impact |
|---|---|---|---|
| E-PT-1 | Team member → admin escalation | Medium | Critical |
| E-PT-2 | Cross-merchant portal access | Low | Critical |
| E-PT-3 | Viewer role initiating transactions | Medium | High |
E-PT-1: Team member to admin escalation
- Attack: A user with developer or finance role exploits a vulnerability to grant themselves admin permissions, gaining access to user management and API key operations.
- Mitigation:
- Role assignment requires manage_roles permission (admin/owner only)
- Role change API validates caller has higher privilege than target role
- System roles (owner, admin) are immutable — cannot be modified via API
- All role changes logged and notified to merchant owner
- Permission checks enforced at API layer AND database query layer (defence in depth)
E-PT-2: Cross-merchant access - Attack: Attacker manipulates tenant context to access another merchant's portal data. - Mitigation: Tenant context derived from OIDC token claims (ControlPlane.com cpTenantId). Server-side session stores merchantId — never from client. Database queries always include merchantId filter. Penetration testing specifically covers tenant isolation. → ADR-019
E-PT-3: Viewer initiating transactions
- Mitigation: Permission checks on every API endpoint. Viewer role explicitly lacks initiate_payin, initiate_payout, initiate_refund permissions. UI hides action buttons, but authorisation enforced server-side regardless.
Risk Matrix¶
| Threat | Likelihood | Impact | Risk Level | Mitigation Status |
|---|---|---|---|---|
| S-PT-1 | High | High | High | Implemented |
| S-PT-2 | Medium | Critical | High | Implemented |
| S-PT-3 | High | High | High | Partial |
| T-PT-1 | Medium | High | High | Implemented |
| T-PT-2 | Medium | High | High | Implemented |
| T-PT-3 | Medium | High | High | Implemented |
| R-PT-1 | Medium | Medium | Medium | Implemented |
| R-PT-2 | Low | High | Medium | Implemented |
| I-PT-1 | Medium | Critical | High | Implemented |
| I-PT-2 | Medium | Critical | High | Implemented |
| I-PT-3 | Medium | Medium | Medium | Implemented |
| D-PT-1 | Medium | Medium | Medium | Implemented |
| D-PT-2 | High | Medium | High | Implemented |
| E-PT-1 | Medium | Critical | High | Implemented |
| E-PT-2 | Low | Critical | Medium | Implemented |
| E-PT-3 | Medium | High | High | Implemented |
ADR Cross-References¶
| Mitigation Area | Related ADR / Standard |
|---|---|
| Authentication / OIDC | ADR-017 API Authentication |
| Tenant isolation | ADR-019 Tenant Isolation |
| Session management | SECURITY-ARCHITECTURE |
| XSS / CSP | ADR-045 Content Security Policy |
| CSRF protection | ADR-046 CSRF Protection |
| Audit trail | ADR-031 Audit Trail |
| Rate limiting | RATE-LIMITING-POLICY |
| Penetration testing | STD-SECURITY-042 |
| PII handling | PII-HANDLING-STANDARD |