Skip to content

Latest commit

 

History

History
115 lines (104 loc) · 18.6 KB

File metadata and controls

115 lines (104 loc) · 18.6 KB

ChamaConnect

ChamaConnect Bug Register

This directory is the authoritative log of issues discovered on chamaconnect.io during the MUIAA x Salamander ChamaConnect Virtual Hackathon (deadline 2026-04-24).

Each issue lives in its own file as BUG-NNN-slug.md and contains:

  1. Evidence — where we observed it (URL, screenshot path, request/response if applicable).
  2. Severity — Critical / High / Medium / Low.
  3. User impact — what breaks for a real chama admin or member.
  4. Root cause — what in the code is likely wrong.
  5. Proposed fix — the smallest diff that resolves it, with code.
  6. Verification — how to prove the fix works.

Update this index when a new bug is filed.

Index

ID Title Severity Surface Status
BUG-001 Every public page ships with default Next.js boilerplate <title> + <meta description> High Public site / SEO Open
BUG-002 Footer Features, Pricing, Resources, Blog, Community, Events all point to # Medium Public site / UX Open
BUG-003 Contact page phone number does not match footer / hackathon-brief contact number Medium Public site / trust Open
BUG-004 Contact page renders literal [email protected] instead of an email address Medium Public site / UX Fixed (2026-04-20)
BUG-005 Login has no 2FA, no phone OTP, no social login — for a money platform High Auth / security Open
BUG-006 Register country selector defaults to International despite Kenya focus Low UX / signup conversion Open
BUG-007 M-Pesa integration marked "Coming Soon" — the #1 Kenyan chama requirement Critical Core product / revenue Open → fixed by ChamaPay module
BUG-008 POST /users/signin returns "message": "User Created" on every login High Auth / API Open
BUG-009 MERRRY_GO_AROUND typo (triple-R, wrong phrase) in both group-types endpoints and the Create Chama dropdown High UI + API + data Open
BUG-010 Two different group-types endpoints with inconsistent (swapped) schemas High API / data integrity Open
BUG-011 Notifications page tries to open ws://localhost:3080 in production — real-time notifications broken Critical Real-time / prod config Open
BUG-012 /admin/chamas throws TypeError: Failed to fetch and shows "create your first chama" on network errors High Dashboard / reliability Open
BUG-013 Signin returns the raw JWT in the response body (also in httpOnly cookie) — XSS-to-takeover path High (security) Auth / API Open
BUG-014 /contact throws React error #418 (hydration mismatch) Medium Public site Open (not reproduced 2026-04-20)
BUG-015 Every role record has permissions: [] — authz likely enforced by role name only High (authz) Backend Open
BUG-016 Signin JWT has no exp/nbf/jti/iss/aud — tokens never expire, can't be revoked Critical (security) Auth / API Open
BUG-017 No Content-Security-Policy; HTML documents missing HSTS / X-Frame-Options / X-Content-Type-Options / Referrer-Policy / Permissions-Policy High (security) Every HTML response Open
BUG-018 Signin rate limit is 1000 req / 15 min per IP, no per-account lockout — brute-force viable High (security) Auth / API Open
BUG-019 /api/auth/token returns 401 on every public page load (should be 200 with {token:null}) Medium Public site / API Open
BUG-020 /api/proxy/users/current-user returns message "Successfully retrieved logged in user" (double space) Low API / copy Open
BUG-021 /api/proxy/roles omits permissions; /users/current-user.role includes permissions:[] — same resource, two shapes Medium API contract Open
BUG-022 Login form inputs have no name and no autocomplete — password managers break, WCAG 1.3.5 fails Medium Auth / UX / a11y Open
BUG-023 /contact "Send Us a Message" inputs have no name, no id, no aria-label Medium Public site / a11y Open
BUG-024 /about has 3 <h1> tags; /contact and /faqs each have 2 — SEO + a11y Low Public site / SEO Open
BUG-025 Every admin/dashboard page ships with <title>Create Next App</title> Medium Admin / UX Open
BUG-026 X-Powered-By: Next.js + x-nextjs-* headers leak backend stack on every HTML response Low (security) Every HTML response Open
BUG-027 Any authenticated User can PUT /api/proxy/settings/:id — platform-wide loanFee, withDrawalFee, fineDelayPercentageIncrement (and likely M-Pesa callback URLs) are attacker-controlled Critical API / authz Open
BUG-028 GET /api/proxy/settings returns M-Pesa Daraja ConsumerKey / ConsumerSecret / LipaNaMpesaShortPass + all C2B/B2C/B2B callback URLs to every signed-in user Critical API / secrets Open
BUG-029 BOLA: GET /api/proxy/groups/:id returns any chama's full data (members' names, emails, phones, blockchain address, schedule) to any authenticated user Critical API / authz / PII Open
BUG-030 BOLA: GET /api/proxy/transactions returns every chama's transactions (amounts, approvals, crypto hashes) to every signed-in user Critical API / authz Open
BUG-031 Signin reveals which emails/phones are registered ("Incorrect password" vs "Invalid email or phone number" + 22-byte size + ~500 ms timing delta) High (security) Auth / API Open
BUG-032 Signup leaks registration status via differential error ("Error creating user…" fires only on already-registered email) High (security) Auth / API Open
BUG-033 Internal backend reachable from the internet at /backend/api/v1/* — doubles the attack surface and bypasses any future proxy-layer mitigations High (security) Infrastructure Open
BUG-034 /api/proxy/users/request-password-reset has no per-account rate limit — enables mail bombing, SMS-cost attack, and OTP brute-force prep High Auth / API Open
BUG-035 GET /api/proxy/permissions returns 201 Created with an empty role-list payload (routing bug + status-code misuse) Medium API Open
BUG-036 GET /api/proxy/notifications/all returns 500 Internal Server Error on every call Medium API / stability Open
BUG-037 Authorization failures return 400 Bad Request (should be 401/403) across signin, group PATCH/DELETE, user DELETE Medium API / REST semantics Open
BUG-038 Signup response contains contradictory status fields (isActive:false + accountStatus:"ACTIVE" + activatedAt populated) Medium Data model Open
BUG-039 Signin/password-reset accept object-valued email/password (MongoDB operators) and return 500 — latent NoSQL injection surface High Auth / API Open
BUG-040 Any authenticated User can POST /api/proxy/roles (create roles) and PATCH /api/proxy/roles/:id (rename/modify ANY role, including SuperAdmin) Critical API / authz Open
BUG-041 GET /api/proxy/transactions?userId=<other> returns another user's full transaction history (IDOR); no server-side pagination Critical API / authz Open
BUG-042 DELETE /api/proxy/groups/:id response embeds full M-Pesa Daraja credentials in GroupSettings — a second exfiltration path independent of BUG-028 Critical API / secrets Open
BUG-043 POST /api/proxy/notifications returns 500 Internal Server Error on every call; no role guard means any user could reach the broken create-notification handler Medium API / stability Open
BUG-044 Path traversal: GET /api/proxy/groups/../settings resolves to /api/proxy/settings, bypassing route guards — all 10+ cross-path combinations confirmed working including M-Pesa credential exfiltration Critical API / routing Open
BUG-045 CORS misconfiguration: localhost:3000 receives Access-Control-Allow-Origin: http://localhost:3000, https://chamaconnect.io + duplicate ACAC: true, true — any localhost JS context can make credentialed cross-origin requests High API / headers Open
BUG-046 JWT not invalidated on logout: DELETE /api/auth/session clears the cookie but the Bearer token remains valid indefinitely (confirmed 200 after "logout") — no revocation mechanism exists High Auth / session management Open
BUG-047 Password-reset OTP brute force: 15+ attempts accepted without lockout or 429, combined with BUG-034 (no reset rate limit) enables full account takeover High Auth / API Open
BUG-048 Transaction approval endpoint leaks internal state: "Only undefined can approve this transaction" (null dereference); rejection endpoint returns 500 even when reason is provided Medium API / stability Open
BUG-049 GET /api/proxy/groups/types and /groups/group-types return 500 — routing collision where "types" is passed as a Mongoose ObjectId Medium API / routing Open
BUG-050 Stored XSS: group name accepts raw HTML including <script> tags without any sanitization — payload persists in DB, returned in API responses, exploitable in email/PDF/SSR contexts High API / input validation Open
BUG-051 GET /api/proxy/roles/permissions and /roles/assign return 500 — same routing collision pattern as BUG-049 Medium API / routing Open
BUG-052 GET /api/proxy/notifications/mark-all-read, /clear, /all return 500 (routing collision + unimplemented handler); clear broken on all methods Medium API / routing Open
BUG-053 BOLA: PATCH /api/proxy/groups/:id/members/:memberId — any authenticated user can change the role of ANY member in ANY chama (confirmed on multiple real members) Critical API / authz Open
BUG-054 M-Pesa STK callback endpoint publicly accessible with no auth, no IP allowlist, no Safaricom signature — forged success callbacks accepted, enabling fake contribution credits Critical API / M-Pesa / financial Open
BUG-055 ?limit=99999 dumps all 29 platform transactions from 7 chamas and 11 users in one request — no server-side pagination cap (amplifies BUG-030) High API Open
BUG-056 NaN / Infinity / -Infinity in any numeric field crashes the handler with 500 Internal Server Error — DoS viable Medium API / input validation Open
BUG-057 withDrawalFee (capital D) field name inconsistency causes silent update failure; sending the canonical name via PUT can null the field Medium API / data model Open
BUG-058 OTP tokens stored in plaintext AND returned in current-user + signin API responses — any JWT holder can read all pending OTPs and reset the victim's password without email access Critical Auth / API Open
BUG-059 Each OTP request creates a new record without invalidating previous ones — 34+ concurrent valid OTPs observed, compounding BUG-047 brute-force and BUG-058 plaintext exposure High Auth / API Open
BUG-060 Null bytes (\u0000) accepted and stored verbatim in group names and other string fields — enables filter bypass, log injection, and downstream null-termination truncation Medium API / input validation Open
BUG-061 Strict-Transport-Security header present on API responses but absent from all HTML pages (homepage, login, admin) — SSL-strip downgrade attack viable on shared Wi-Fi High Web / HTTP headers Open
BUG-062 SPF uses ~all (softfail) and DMARC uses p=quarantine — spoofed @chamaconnect.io emails delivered to recipient spam/junk, enabling phishing and credential harvesting Medium Infrastructure / DNS Open
BUG-063 PATCH /api/proxy/users/update-profile changes email/firstName/lastName with no password re-entry, no OTP, no re-verification — one-shot ATO primitive for any leaked JWT; reproduced twice on live site Critical Auth / Profile API Open
BUG-064 Password policy accepts "password", "password123", and eight-space strings; 6-char minimum, no blacklist, no complexity, no HIBP check High Auth / signup Open
BUG-065 Signin performs exact-match on email — uppercase + whitespace variants all return 400 Invalid email or phone number; silent lockout + enumeration amplifier High Auth / signin Open
BUG-066 Signin accepts ≥ 100 KB request bodies with no 413; bandwidth amplifier for credential-stuffing + log bloat Medium Auth / infrastructure Open
BUG-067 POST /api/auth/session sets auth_token cookie to any supplied value without verifying JWT signature — session-fixation / XSS-amplifier Medium Auth / Next.js bridge Open
BUG-068 No CAA DNS record on chamaconnect.io — any publicly-trusted CA in the world may issue certs for the domain Medium DNS / TLS Open
BUG-069 Every unmatched path (including /.env, /.git/HEAD, /swagger, /api/health) returns a 26 KB HTML clone of the homepage — 130× bandwidth amplifier + soft-404 SEO Low Public site / config Open
BUG-070 /users/signin accepts application/x-www-form-urlencoded — CORS-preflight bypass that becomes a full CSRF amplifier if any /api/proxy/* mutation endpoint also accepts it Medium Auth / API content-type Open
BUG-071 ?from, ?to, ?since, ?createdAt filters accepted but silently ignored on /transactions, /notifications, /groups — dashboard widgets silently show all-time data instead of the filtered range High API / data model Open
BUG-072 /api/proxy/users/admin uses ad-hoc role-name strings ("super admins" vs "admins") across methods — none match the canonical role taxonomy; 400 instead of 403 on authz failure Medium API / authorisation Open
BUG-073 Email verification is enforced at signup (400 "Please verify your email before signing in") but bypassable via PATCH /users/update-profile — strengthens BUG-063 ATO chain High Auth / profile API Open
BUG-074 /users/update-profile uses a correct write-allowlist (roleId/isSuperadmin/accountStatus can't be hijacked) but returns 200 on unknown keys — no 400 hard-reject, so client typos silently fail to persist Low API contract Open
BUG-075 Every /api/proxy/* mutation endpoint accepts application/x-www-form-urlencoded and multipart/form-data — platform-wide CSRF surface (supersedes / escalates BUG-070 from "signin only" to "all mutations") High API / content-type / CSRF Open
BUG-076 Live evidence of BUG-040: a BackendHack role created during probing still exists in the production roles table, visible to every signed-in user and surfaced in the Create-Chama wizard dropdown Critical API / authz / data integrity Open

Severity scale

  • Critical — a real user cannot achieve the core job of the product (e.g. collecting contributions).
  • High — core trust/security/SEO issue visible to everyone.
  • Medium — noticeable inconsistency or dead UX.
  • Low — cosmetic / polish.

Workflow

  1. Discover a bug (manual or via /recon Playwright run).
  2. Create BUG-NNN-slug.md using _template.md.
  3. Add a row to the table above.
  4. Write a failing test (if feasible) in /recon/tests.
  5. Ship the fix in /chamapay (or as a patch in /bugs/patches/BUG-NNN.patch).
  6. Flip status to Fixed and link the PR / commit.