# RC-1A1 Authorization & IDOR audit

## Scope and findings

Audited authenticated routes for Membership/Billing, E-Wallet, Lead Credit, Premium Leads, notifications, Support, Partner portal and receipts, onboarding, Coupon checkout, and all `/admin` routes. Administrative routes are consistently protected by `auth` and `admin`; the Partner portal additionally requires current `is_partner` state.

Cross-user resources are scoped in the server layer: Premium Lead details are filtered by assigned user and assigned state; status and note services verify the actor; notifications are queried through the authenticated user's relation; Billing queries add the authenticated user constraint; Support detail/reply compare ticket ownership; and Partner receipt downloads compare withdrawal ownership and paid receipt state.

CMS draft/publish/history operations are admin-only. Section services reject system sections, and rollback reloads revisions through the route section before restoring, preventing a revision from another section or website from being applied. Website asset selection is admin-only.

No authorization or IDOR defect was confirmed in this audit. The focused regression suite covers cross-agent Premium Lead, Support, Billing, notification, Partner receipt, admin-route, and CMS rollback attempts, including no-mutation assertions.

## Deferred security work

No RBAC redesign, API token system, 2FA, team roles, or UI changes were introduced. Broader penetration testing, rate-limit review, and operational logging policy remain separate release-security work.

## RC-1A2 Mass Assignment & Privilege Escalation

Reviewed User, order/payment, wallet/ledger, Partner, Coupon/redemption, Support, Premium Lead, approval, and CMS model assignment surfaces, alongside normal browser controllers. No request path uses unfiltered request payloads for sensitive model writes. Registration and resubmission use validated allow-lists and then set registration/referral authority server-side; profile permits only name and email. Privilege, referral, onboarding, financial snapshots, payment state, ledger balances, payout/withdrawal state, Coupon redemption, Support ownership/admin flags, Lead assignment ownership/distribution fields, and CMS revision state are derived by trusted services, authenticated user, or route resources.

Direct-payload regression coverage confirms registration/resubmission privilege-field rejection, profile/support/withdrawal ownership authority, and Premium Lead status-field narrowing. Existing checkout, Coupon, wallet, receipt, refund, CMS, and Partner financial tests cover their corresponding server-controlled snapshots and ledgers. No mass-assignment or privilege-escalation vulnerability was confirmed.

## RC-1B1 Financial Replay / Double-Spend / Race Conditions

Financial operations use database transactions, row locks, and unique constraints at their business boundaries. Membership fulfilment locks payment attempt then order; Coupon consumption locks the Coupon before capacity count/insert; wallet services lock the wallet before balance updates; withdrawal transitions lock withdrawal then wallet; Lead Credit distribution locks assignment then round-robin/wallet work; and balance-inquiry refunds lock the ticket before the unique refund/credit flow. Unique constraints guard payment attempt references, Coupon redemption per order, affiliate/Partner payout per order, withdrawal ledger/receipt per withdrawal, refund per support ticket, and wallet ownership.

Replay coverage confirms reservation over-subscription prevention, refund exactly-once crediting, and withdrawal transition replay rejection. Existing Membership, CreditOrder, Coupon, Partner payout, and receipt suites cover their callback/fulfilment exactly-once paths. No replay or double-spend defect was confirmed.

## RC-1B2 Payment Callback Authenticity & Failure States

The public CHIP callback is intentionally CSRF-exempt for provider delivery but verifies the exact raw body signature before creating an event, retrieving a provider purchase, or mutating payment state. Callback JSON is only used to identify the provider purchase; the retrieved provider record supplies status, amount, currency, and reference. Amount is checked against the stored order charge (including Coupon/referral snapshots), currency must be MYR, and reference must match the stored local reference.

Pending, failed, cancelled, unknown, mismatched, and unmatched callbacks do not fulfil orders. A later paid provider state may recover an unpaid attempt; once paid, subsequent non-paid callbacks cannot downgrade it or repeat fulfilment. The browser success-return page is presentation-only and cannot fulfil orders. The callback remains intentionally unthrottled so legitimate provider retries are not blocked. No callback-authenticity or failure-state defect was confirmed.

## RC-1C1 PII & Sensitive Data Leakage

Audited User serialization, shared Inertia props, Agent/Admin read models, billing/payment summaries, notifications, registration email paths, safe exception logging, CSV export, Partner receipt presentation, Support, Coupon, Premium Lead, and CMS public props. User serialization hides plaintext/encrypted IC representation, IC hash, password, and remember token. Shared authentication props are curated and omit registration, wallet, payment, and Partner-financial internals. Billing exposes operational attempt summaries without provider references, checkout URLs, or metadata.

Notifications use minimal safe fields; Support/refund notifications contain a summary and ticket URL, not full messages, ledger IDs, or balance snapshots. CHIP checkout logs retain exception class only. CSV/PDF/CMS read models remain intentionally curated: Lead CSV formula neutralization is retained, receipts present only payment-facing snapshots, and public CMS uses relative asset URLs without filesystem paths. No confirmed PII or sensitive-data leak was found. Infrastructure retention, production log access, and secret rotation remain operational controls outside this application audit.

## RC-1C2 XSS, Content Injection & File Upload Security

Public CMS, Support, Coupon, Lead, and registration text is rendered through Vue/Blade escaped interpolation; no raw CMS content renderer uses `v-html` or equivalent. The limited `v-html` uses are framework-generated pagination labels, not user content. CMS navigation is application-defined. Tutorial video input is normalized to canonical HTTPS YouTube, Vimeo, or Loom embed URLs and rejects scripts, data URLs, host confusion, and arbitrary iframe markup. Theme colors use strict validation.

CMS upload accepts only image-validated JPG/JPEG/PNG/WebP files up to 5 MB, rejects SVG and spoofed files, uses an allow-listed context map, and stores hash-named files under generated public-disk paths. No confirmed XSS, content-injection, executable-upload, or traversal defect was found. CSP deployment remains an infrastructure hardening item and was not redesigned in this audit.

## RC-1D1 Query, Lock & Transaction Performance

The high-traffic operational read paths use bounded database work. Round-robin monitoring batches operators, agents, memberships, wallets, states, and pending counts rather than querying each operator or agent. Lead Credit monitoring paginates agents at 25 and uses subqueries/database aggregates for latest transactions, summary counts, and operator breakdowns. Premium Lead Kanban intentionally loads the active agent pipeline but eager-loads its Lead/Submission and Operator relations. Admin Leads paginate at 25, eager-load row relations, and batch pending diagnostics by represented operator; Support and registration-style listings likewise paginate and eager-load safe identities without message history. Admin Lead detail limits activities to 50 and notes/reminders to 20. Notification shared props perform only an unread count and a latest-five query.

The public CMS renderer eagerly resolves the operator/website/theme/page/sections/published revisions graph, preventing a revision query per section. CMS workspace and preview reuse scoped graph loading; no read-only monitor/list/detail/preview path was found to create round-robin state, wallets, revisions, diagnostics, or retries. The Malaysia-day same-day-reuse query retains a UTC `whereBetween` window rather than a timestamp-wrapping `whereDate`; the supporting submissions phone/timestamp index remains applicable. Existing composite indexes support operator/active agents, memberships, lead-assignment monitoring/pipeline, support ticket ordering, coupon redemption usage, withdrawal status, and CMS revision lookup. No additional index was justified.

Measured regression ceilings at moderate fixture scale are: Round Robin monitor 6 queries, Lead Credit monitor 12, Premium Lead Kanban 12, Admin Lead listing with pending diagnostics 15, Admin Support index 8, public CMS page 7, and an authenticated dashboard shell with 30 notifications 8. These are upper bounds rather than brittle exact counts.

Transaction boundaries remain local to state changes. Lead distribution locks assignment then round-robin state before wallet debit, assignment activity/reminder creation, and state update; same-day reuse stays within the assignment transaction. Coupon fulfilment locks the payment/order path before coupon consumption, with redemption uniqueness guarding repeat use. Withdrawal state transitions lock withdrawal then wallet; balance refunds lock the support ticket before wallet/ledger work. Provider HTTP retrieval happens outside the fulfilment mutation transaction. No inconsistent reverse lock order or confirmed deadlock defect was found.

Accepted RC scale limits: the active Kanban and Support detail intentionally load their full active pipeline/conversation respectively; Admin Lead filter options may load the available agent selector; leading-wildcard search is intentionally unindexed; and CSV export streams all matching results lazily. Future high-scale work may introduce bounded conversation history, asynchronous exports, and search infrastructure, but no cache, queue, replica, or UI-pagination redesign was introduced in this audit.
