audit: 2026-05-30 full-codebase audit — report, issues, docs, runbooks
Full-codebase-audit 2026-05-30 outputs: - Audit report: 09 - Audits/Full Codebase Audit - 2026-05-30.md - 81 issue files ISSUE-055..135 (decisions + 1 skipped no-brainer). - Scanner docs from scratch (was zero): architecture, data model, API ref, payment flow, operations runbook + repo README. - Doc-sync updates across API reference, data models, flows, design system. - Secret Rotation Runbook (08 - Operations) for the exposed credentials. - Reusable workflow guide (07 - Development) + .claude/workflows/full-codebase-audit.js. Issues remain status:open intentionally — the code fixes are uncommitted-then-committed working-tree changes per repo and aren't "resolved" until merged/deployed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
268
09 - Audits/Full Codebase Audit - 2026-05-30.md
Normal file
268
09 - Audits/Full Codebase Audit - 2026-05-30.md
Normal file
@@ -0,0 +1,268 @@
|
||||
---
|
||||
title: Full Codebase Audit — 2026-05-30
|
||||
tags: [audit, index, security, logic, performance]
|
||||
created: 2026-05-30
|
||||
status: open
|
||||
---
|
||||
|
||||
# Full Codebase Audit — 2026-05-30
|
||||
|
||||
Full-system audit across all three repos (frontend, backend, scanner) triggered as a periodic health pass. 134 findings across security, logic, performance, and supply-chain dimensions. 49 no-brainers were applied automatically; 1 was skipped (requires new persistence layer); 80 decision items were queued for human review.
|
||||
|
||||
---
|
||||
|
||||
## Findings Summary by Severity and Dimension
|
||||
|
||||
| Severity | Security | Logic | Performance | Supply-Chain | Total |
|
||||
|----------|----------|-------|-------------|--------------|-------|
|
||||
| Critical | 3 | 2 | 0 | 1 | 6 |
|
||||
| High | 18 | 12 | 8 | 4 | 42 |
|
||||
| Medium | 14 | 12 | 8 | 6 | 40 |
|
||||
| Low | 10 | 6 | 10 | 20 | 46 |
|
||||
| **Total** | **45** | **32** | **26** | **31** | **134** |
|
||||
|
||||
### By Repo
|
||||
|
||||
| Repo | Findings | No-Brainers Applied | Skipped | Decision Items |
|
||||
|------|----------|---------------------|---------|----------------|
|
||||
| frontend | 49 | 18 (NB-1 – NB-17, NB-49) | 0 | 31 (DEC-1–21, DEC-74–80) |
|
||||
| backend | 55 | 21 (NB-18 – NB-38) | 1 (NB-27) | 33 (DEC-22–56) |
|
||||
| scanner | 30 | 10 (NB-39 – NB-48) | 0 | 20 (DEC-57–73) |
|
||||
|
||||
---
|
||||
|
||||
## Systemic Themes
|
||||
|
||||
Eight root-cause patterns cut across most findings. Addressing these themes eliminates whole clusters at once.
|
||||
|
||||
### 1. Missing Authorization on Payment and Admin Endpoints (Broken Access Control)
|
||||
Routes are gated only by `authenticateToken`/`AuthGuard` with no role or ownership check. Payment status writes, exports, stats, user-payment listings, file deletion, delivery updates, offer selection, dispute evidence, and the entire admin UI tree all trust authentication alone. **Root fix:** a shared `requireAdmin` middleware + ownership-check helper + centralized status-transition validator applied consistently.
|
||||
|
||||
### 2. Payment Status State Machine Is Inconsistent and Corruptible
|
||||
Non-enum statuses (`'released'`, `'funded'`) are written and silently dropped, the provider enum omits `'shkeeper'`, transition guards check fields never set (`escrowState:'funded'`), the transition map omits `'in_negotiation'`, and amount-mismatch is checked after side-effects commit. **Root cause:** schema enums and state machine drifted from the code that writes them.
|
||||
|
||||
### 3. Secrets Committed to the Repo and Baked into Images
|
||||
Telegram bot token, Resend SMTP key, Google secret, JWT secret, admin password, Alchemy keys, and RN secrets appear across `.env.example`, `.env.development`, `.gitleaks.toml`, Dockerfiles, and committed scripts — and `.dockerignore` whitelists `.env.development` into prod images. **Root fix:** placeholder all committed files, remove env files from images, inject at runtime, rotate every exposed credential.
|
||||
|
||||
### 4. Test/Debug Bypasses Reachable in Production
|
||||
Test-payment mode, `force-verify-user`, RN test-webhook signature bypass, the debug panel, and console-suppression hacks all rely on weak runtime `NODE_ENV` checks (or none). **Root fix:** gate on `NODE_ENV` at registration/build time; never honour bypass flags in production.
|
||||
|
||||
### 5. N+1 Queries, Unbounded Fan-Out, and Chatty Polling
|
||||
Per-row DB lookups in `getPurchaseRequestsByBuyer` and `getReferrals`, unbounded notification/seller fan-out, redundant polling alongside sockets, full-collection loads, and per-intent HTTP fan-out in the scanner. **Root fix:** batch with `$in`/aggregation, bound concurrency, replace redundant polling with socket-driven or visibility-gated updates.
|
||||
|
||||
### 6. Float Math and Weak Randomness in Money/Crypto Paths
|
||||
USDT wei conversion via IEEE-754 floats risks under-payment; verification codes use `Math.random` instead of a CSPRNG. **Root fix:** use `parseUnits` for token amounts and `crypto.randomInt` for codes (both already available in the codebase).
|
||||
|
||||
### 7. Unhardened Outbound HTTP and Webhook Handling (SSRF / OOM / Retry Leaks)
|
||||
Scanner accepts arbitrary `callbackUrl` (SSRF), follows third-party `next`-URLs unvalidated, reads RPC/API bodies without size limits (OOM), overrides confirmation thresholds, and spawns unbounded sleeping retry goroutines. **Root fix:** URL allowlisting + private-range blocking at dial time, `io.LimitReader` caps, threshold floors, bounded persisted retry queues.
|
||||
|
||||
### 8. CI/CD Supply-Chain Hygiene Gaps
|
||||
Floating/unpinned images, missing lint/type/test/audit gates on production and manual pipelines, privileged buildx, dual lockfiles, no `engines` pin, and untested manual builds. **Root fix:** digest-pin all CI images, enforce quality gate on every pipeline, unify lockfiles, add audit/vuln scanning.
|
||||
|
||||
---
|
||||
|
||||
## No-Brainers Applied (49 fixes)
|
||||
|
||||
All 49 no-brainers were applied. NB-13/NB-14: lockfile not regenerated (no `yarn install` run per instructions — leave uncommitted for human review). NB-7: requires backend to expose `GET /chat/unread-count` returning `{ data: { count: number } }`. NB-29: depends on DEC-32 outcome; applied `status:'completed'` as interim until enum decision is made.
|
||||
|
||||
| ID | Repo | Title | Files |
|
||||
|----|------|-------|-------|
|
||||
| NB-1 | frontend | USDT amount-to-wei uses floating-point arithmetic | `src/web3/context/action.ts` |
|
||||
| NB-2 | frontend | Email verification logs full form data including password | `src/auth/view/jwt/jwt-verify-view.tsx` |
|
||||
| NB-3 | frontend | Hardcoded Telegram bot ID fallback in widget loader | `src/auth/utils/telegram-login-widget.ts` |
|
||||
| NB-4 | frontend | releasePayment returns fake success with hardcoded tx hash | `src/actions/payment.ts` |
|
||||
| NB-5 | frontend | signUp/verifyEmailWithCode bypass StorageUtils.safeSet | `src/auth/context/jwt/action.ts` |
|
||||
| NB-6 | frontend | Redundant 30s polling on buyer request details page | `src/sections/request/view/buyer/buyer-request-details-view.tsx` |
|
||||
| NB-7 | frontend | getUnreadCount fetches entire conversation list | `src/actions/chat.ts`, `src/lib/axios.ts` |
|
||||
| NB-8 | frontend | Debug new Error().stack capture on every step-change | `src/sections/request/view/buyer/buyer-request-details-view.tsx` |
|
||||
| NB-9 | frontend | transformMessage logs two info calls per message | `src/actions/chat.ts` |
|
||||
| NB-10 | frontend | Alchemy API keys hardcoded as Dockerfile ARG defaults | `Dockerfile` |
|
||||
| NB-11 | frontend | Escrow wallet address hardcoded across multiple files | `src/web3/decentralizedPayment.ts`, `step-6-buyer-confirmed.tsx`, `manual-payout.tsx` |
|
||||
| NB-12 | frontend | NEXT_PUBLIC_MAPBOX_API_KEY missing from Dockerfile ARGs/docs | `Dockerfile` |
|
||||
| NB-13 | frontend | google-auth-library and @google-cloud/local-auth unused | `package.json` |
|
||||
| NB-14 | frontend | @depay/widgets unused dependency | `package.json` |
|
||||
| NB-15 | frontend | MockedUser (demo@minimals.cc) rendered in production nav | `src/layouts/components/nav-upgrade.tsx` |
|
||||
| NB-16 | frontend | WEB3_PROVIDER_URL declared but never used | `src/global-config.ts` |
|
||||
| NB-17 | frontend | google-oauth.ts.backup committed to source tree | `src/auth/services/google-oauth.ts.backup` |
|
||||
| NB-18 | backend | Verification/reset codes logged to server console | `src/services/auth/authController.ts`, `src/services/delivery/DeliveryService.ts` |
|
||||
| NB-19 | backend | Verification code uses Math.random() | `src/services/auth/authService.ts` |
|
||||
| NB-20 | backend | Admin password hardcoded fallback in init-admin.ts | `src/infrastructure/database/init-admin.ts` |
|
||||
| NB-21 | backend | force-verify-user route registered unconditionally | `src/services/auth/authRoutes.ts` |
|
||||
| NB-22 | backend | getUserPayments queries non-existent 'userId' field | `src/services/payment/paymentService.ts` |
|
||||
| NB-23 | backend | getPaymentStats sums object-typed amount field | `src/services/payment/paymentService.ts` |
|
||||
| NB-24 | backend | GET /api/payment/export endpoints lack admin guard | `src/services/payment/paymentControllerRoutes.ts` |
|
||||
| NB-25 | backend | getUserPayments route lacks ownership check (IDOR) | `src/services/payment/paymentControllerRoutes.ts` |
|
||||
| NB-26 | backend | GET /api/files/stats missing admin guard | `src/services/file/fileRoutes.ts` |
|
||||
| NB-28 | backend | updateDeliveryInfo does not enforce seller ownership | `src/services/marketplace/marketplaceController.ts` |
|
||||
| NB-29 | backend | payout/confirm and release/confirm set non-enum 'released' status | `src/services/payment/requestNetwork/requestNetworkRoutes.ts` |
|
||||
| NB-30 | backend | N+1 per-request Payment lookup in getPurchaseRequestsByBuyer | `src/services/marketplace/PurchaseRequestService.ts` |
|
||||
| NB-31 | backend | Full unpaginated load in getPayments admin endpoint | `src/services/marketplace/marketplaceController.ts` |
|
||||
| NB-32 | backend | 13 sequential countDocuments in getCollectionStats | `src/services/admin/dataCleanupService.ts` |
|
||||
| NB-33 | backend | Real credentials committed in tracked .env.example | `.env.example` |
|
||||
| NB-34 | backend | Dockerfile.dev runs --frozen-lockfile before copying yarn.lock | `Dockerfile.dev` |
|
||||
| NB-35 | backend | Deprecated npm 'crypto' shim in production deps | `package.json` |
|
||||
| NB-36 | backend | body-parser redundant with Express 5 | `package.json` |
|
||||
| NB-37 | backend | manual.yml CI missing typecheck gate | `.woodpecker/manual.yml` |
|
||||
| NB-38 | backend | No engines field / .nvmrc for Node version | `package.json`, `.nvmrc` |
|
||||
| NB-39 | scanner | Scanner Dockerfile runs as root (no USER) | `Dockerfile` |
|
||||
| NB-40 | scanner | cleanup.yml uses alpine:latest | `.woodpecker/cleanup.yml` |
|
||||
| NB-41 | scanner | scanner buildx plugin not pinned | `.woodpecker/development.yml`, `.woodpecker/manual.yml`, `.woodpecker/production.yml` |
|
||||
| NB-42 | scanner | Scanner RPC/API bodies read without size limit | `chain.go`, `tron_chain.go`, `ton_chain.go` |
|
||||
| NB-43 | scanner | Scanner manual.yml has no test step | `.woodpecker/manual.yml` |
|
||||
| NB-44 | scanner | No govulncheck/gosec in scanner CI | `.woodpecker/development.yml`, `.woodpecker/production.yml` |
|
||||
| NB-45 | scanner | No RPC_TRON/RPC_TON override env vars | `config.go` |
|
||||
| NB-46 | scanner | EVM scan lag warning uses reorgBuf-adjusted checkpoint | `chain.go` |
|
||||
| NB-47 | scanner | handleScannerStatus loads full intent rows to count pending | `api.go`, `intent.go` |
|
||||
| NB-48 | scanner | SQLite no connection pool limit set | `intent.go` |
|
||||
| NB-49 | frontend | Admin route polling paused when tab hidden | `payments-awaiting-confirmation-list-view.tsx` |
|
||||
|
||||
### Skipped No-Brainers
|
||||
|
||||
| ID | Reason | Issue Filed |
|
||||
|----|--------|-------------|
|
||||
| NB-27 (DELETE /api/files/delete ownership check) | `fileService.deleteFile()` is a pure filesystem path operation with no DB ownership record — no `File` model, no `createdBy`/`owner` field stored anywhere. Adding an ownership check requires creating a new persistence layer, which is a larger-than-mechanical change. | [[ISSUE-055-delete-api-files-delete-has-no-ownership-check-requires-new-pe|ISSUE-055]] |
|
||||
|
||||
---
|
||||
|
||||
## Decision Queue (80 items)
|
||||
|
||||
These items require human judgment before implementation. Each has a corresponding issue file.
|
||||
|
||||
### Critical
|
||||
|
||||
| Issue | Title | Repo | Recommendation |
|
||||
|-------|-------|------|----------------|
|
||||
| [[ISSUE-056-backend-verifypayment-and-paymentcallback-routes-unauthenticat|ISSUE-056]] | verifyPayment and paymentCallback routes unauthenticated | backend | Auth + HMAC on callback; remove isWeb3Payment bypass |
|
||||
|
||||
### High
|
||||
|
||||
| Issue | Title | Repo |
|
||||
|-------|-------|------|
|
||||
| [[ISSUE-057-frontend-admin-ui-routes-lack-role-based-authorization-guard|ISSUE-057]] | Admin UI routes lack role-based authorization guard | frontend |
|
||||
| [[ISSUE-058-frontend-test-payment-mode-enablable-in-production-via-env-var|ISSUE-058]] | Test payment mode enablable in production via NEXT_PUBLIC env var | frontend |
|
||||
| [[ISSUE-059-frontend-auth-provider-clears-tokens-on-any-non-403-error|ISSUE-059]] | Auth provider clears tokens on any non-403 error including network failures | frontend |
|
||||
| [[ISSUE-060-frontend-contacts-popover-reads-userid-from-non-existent-local|ISSUE-060]] | contacts-popover reads userId from non-existent localStorage 'user' key | frontend |
|
||||
| [[ISSUE-061-frontend-socket-context-helpers-accumulate-listeners-without-d|ISSUE-061]] | Socket context helpers accumulate listeners without dedup | frontend |
|
||||
| [[ISSUE-062-backend-payment-update-routes-lack-ownership-role-guards|ISSUE-062]] | Backend payment update routes lack ownership/role guards | backend |
|
||||
| [[ISSUE-063-backend-legacy-marketplace-patch-payments-id-lets-any-user-set|ISSUE-063]] | Legacy marketplace PATCH /payments/:id lets buyer/seller set any status | backend |
|
||||
| [[ISSUE-064-backend-request-network-allow-test-webhooks-bypasses-signature|ISSUE-064]] | REQUEST_NETWORK_ALLOW_TEST_WEBHOOKS bypasses signature verification | backend |
|
||||
| [[ISSUE-065-backend-rn-webhook-advances-purchaserequest-to-non-existent-fu|ISSUE-065]] | RN webhook advances PurchaseRequest to non-existent 'funded' status | backend |
|
||||
| [[ISSUE-066-backend-payout-and-release-confirm-set-non-enum-status|ISSUE-066]] | payout/confirm and release/confirm set non-enum status 'released' | backend |
|
||||
| [[ISSUE-067-backend-amount-mismatch-check-runs-after-payment-saved-and-offe|ISSUE-067]] | amount-mismatch check runs after payment saved and offers accepted | backend |
|
||||
| [[ISSUE-068-backend-datacleanuservice-deletes-payments-without-provider-sco|ISSUE-068]] | dataCleanupService deletes Payments without provider scoping | backend |
|
||||
| [[ISSUE-069-backend-cleanupoldpendingpayments-deletes-pending-rn-payments-m|ISSUE-069]] | cleanupOldPendingPayments deletes pending RN payments mid-flow | backend |
|
||||
| [[ISSUE-070-backend-notifyallsellersaboutnewrequest-unbounded-fan-out|ISSUE-070]] | notifyAllSellersAboutNewRequest unbounded fan-out | backend |
|
||||
| [[ISSUE-071-backend-getreferrals-n-plus-1-purchaserequest-and-pointtransac|ISSUE-071]] | getReferrals N+1 (PurchaseRequest + PointTransaction per referral) | backend |
|
||||
| [[ISSUE-072-backend-chat-messages-stored-as-embedded-array-unbounded-growth|ISSUE-072]] | Chat messages stored as embedded array (unbounded document growth) | backend |
|
||||
| [[ISSUE-073-backend-payment-provider-enum-missing-shkeeper|ISSUE-073]] | Payment provider enum missing 'shkeeper' | backend |
|
||||
| [[ISSUE-074-backend-env-development-committed-with-live-telegram-and-smtp-s|ISSUE-074]] | Backend Telegram bot token + SMTP key committed in .env.development | backend |
|
||||
| [[ISSUE-075-backend-dockerignore-whitelists-env-development-into-prod-image|ISSUE-075]] | .dockerignore whitelists .env.development into prod image | backend |
|
||||
| [[ISSUE-076-scanner-ssrf-via-unvalidated-callbackurl|ISSUE-076]] | Scanner: SSRF via unvalidated callbackUrl | scanner |
|
||||
| [[ISSUE-077-scanner-caller-can-override-confirmation-threshold-down-to-1|ISSUE-077]] | Scanner: caller can override confirmation threshold down to 1 | scanner |
|
||||
| [[ISSUE-078-scanner-idempotency-path-ignores-mismatched-parameters|ISSUE-078]] | Scanner: idempotency path ignores mismatched parameters | scanner |
|
||||
| [[ISSUE-079-frontend-telegram-bot-token-committed-in-gitleaks-toml-allowli|ISSUE-079]] | Frontend: Telegram bot token committed in .gitleaks.toml allowlist | frontend |
|
||||
|
||||
### Medium
|
||||
|
||||
| Issue | Title | Repo |
|
||||
|-------|-------|------|
|
||||
| [[ISSUE-080-frontend-open-redirect-via-unvalidated-returnto-in-guestguard|ISSUE-080]] | Open redirect via unvalidated returnTo in GuestGuard | frontend |
|
||||
| [[ISSUE-081-frontend-tokens-stored-in-localstorage-xss-accessible|ISSUE-081]] | Tokens stored in localStorage (XSS-accessible) | frontend |
|
||||
| [[ISSUE-082-frontend-wallet-ownership-signature-verification-is-a-no-op|ISSUE-082]] | Wallet ownership signature verification is a no-op on frontend | frontend |
|
||||
| [[ISSUE-083-frontend-no-content-security-policy-header-in-next-config|ISSUE-083]] | No Content-Security-Policy header in Next.js config | frontend |
|
||||
| [[ISSUE-084-frontend-console-error-warn-suppression-masks-prod-errors|ISSUE-084]] | console.error/warn suppression masks prod errors | frontend |
|
||||
| [[ISSUE-085-frontend-token-refresh-queue-dispatches-with-undefined-authori|ISSUE-085]] | Token refresh queue dispatches with undefined Authorization | frontend |
|
||||
| [[ISSUE-086-frontend-paymentdetailsview-status-dropdown-exposed-to-all-use|ISSUE-086]] | PaymentDetailsView status dropdown exposed to all users | frontend |
|
||||
| [[ISSUE-087-frontend-getpaymentstatus-and-checkpaymentstatus-hit-different|ISSUE-087]] | getPaymentStatus and checkPaymentStatus hit different endpoints | frontend |
|
||||
| [[ISSUE-088-frontend-adminwalletpayout-falls-back-to-literal-admin-string|ISSUE-088]] | adminWalletPayout falls back to literal 'admin' adminUserId | frontend |
|
||||
| [[ISSUE-089-frontend-admin-payments-awaiting-confirmation-polls-every-12s|ISSUE-089]] | Admin payments-awaiting-confirmation polls every 12s unconditionally | frontend |
|
||||
| [[ISSUE-090-frontend-chat-views-re-fetch-full-conversation-on-every-new-me|ISSUE-090]] | Chat views re-fetch full conversation on every new-message event | frontend |
|
||||
| [[ISSUE-091-frontend-dual-socket-connections-socketprovider-and-socketserv|ISSUE-091]] | Dual socket connections (SocketProvider + socketService singleton) | frontend |
|
||||
| [[ISSUE-092-backend-jwt-refresh-and-access-tokens-share-same-secret|ISSUE-092]] | JWT refresh and access tokens share the same secret; middleware skips type check | backend |
|
||||
| [[ISSUE-093-backend-addevidence-no-participant-ownership-check-on-disputes|ISSUE-093]] | addEvidence: no participant ownership check on disputes | backend |
|
||||
| [[ISSUE-094-backend-selectoffer-does-not-verify-buyer-owns-purchase-request|ISSUE-094]] | selectOffer does not verify buyer owns the purchase request | backend |
|
||||
| [[ISSUE-095-backend-getuserstats-no-ownership-admin-check-idor|ISSUE-095]] | getUserStats: no ownership/admin check (IDOR) | backend |
|
||||
| [[ISSUE-096-backend-validatestatustransition-requires-escrowstate-funded-n|ISSUE-096]] | validateStatusTransition requires escrowState 'funded' never set on completed payments | backend |
|
||||
| [[ISSUE-097-backend-validtransitions-map-missing-in-negotiation-key|ISSUE-097]] | validTransitions map missing 'in_negotiation' key | backend |
|
||||
| [[ISSUE-098-backend-in-memory-seendeliveryids-resets-on-restart|ISSUE-098]] | validateStatusTransition: in-memory seenDeliveryIds resets on restart | backend |
|
||||
| [[ISSUE-099-backend-on-demand-rn-reconciliation-in-getpaymentbyid-can-race|ISSUE-099]] | On-demand RN reconciliation in getPaymentById can race | backend |
|
||||
| [[ISSUE-100-backend-updatepurchaserequest-does-findbyid-then-findbyidandupd|ISSUE-100]] | updatePurchaseRequest does findById then findByIdAndUpdate | backend |
|
||||
| [[ISSUE-101-backend-config-loads-env-development-unconditionally|ISSUE-101]] | Backend config loads .env.development unconditionally | backend |
|
||||
| [[ISSUE-102-backend-14-high-severity-npm-vulns-no-audit-step-in-ci|ISSUE-102]] | 14 high-severity npm vulns, no audit step in CI | backend |
|
||||
| [[ISSUE-103-backend-react-react-dom-in-backend-production-dependencies|ISSUE-103]] | react/react-dom in backend production dependencies | backend |
|
||||
| [[ISSUE-104-backend-bcrypt-native-addon-alongside-used-bcryptjs|ISSUE-104]] | bcrypt native addon present alongside used bcryptjs | backend |
|
||||
| [[ISSUE-105-backend-no-startup-validation-of-required-env-vars|ISSUE-105]] | No startup validation of required env vars | backend |
|
||||
| [[ISSUE-106-backend-dual-lockfiles-yarn-lock-and-package-lock-json-diverge|ISSUE-106]] | Dual lockfiles (yarn.lock + package-lock.json) diverge | backend |
|
||||
| [[ISSUE-107-scanner-tronGrid-pagination-next-url-used-unvalidated|ISSUE-107]] | Scanner: TronGrid pagination next-URL used unvalidated | scanner |
|
||||
| [[ISSUE-108-scanner-unauthenticated-startup-when-scanner-api-key-unset|ISSUE-108]] | Scanner: unauthenticated startup when SCANNER_API_KEY unset | scanner |
|
||||
| [[ISSUE-109-scanner-tron-lag-metric-reported-in-ms-not-blocks|ISSUE-109]] | Scanner: Tron lag metric reported in ms, not blocks | scanner |
|
||||
| [[ISSUE-110-scanner-ton-worker-on-http-fan-out-per-scan-cycle|ISSUE-110]] | Scanner: TON worker O(N) HTTP fan-out per scan cycle | scanner |
|
||||
| [[ISSUE-111-scanner-deliverwebhook-goroutines-use-blocking-time-sleep|ISSUE-111]] | Scanner: deliverWebhook goroutines use blocking time.Sleep (leak risk) | scanner |
|
||||
| [[ISSUE-112-scanner-unbounded-goroutine-fan-out-for-webhook-retries|ISSUE-112]] | Scanner: unbounded goroutine fan-out for webhook retries | scanner |
|
||||
| [[ISSUE-113-scanner-rpc-response-bodies-read-without-size-limit-oom|ISSUE-113]] | Scanner/backend: RPC response bodies read without size limit (OOM) | scanner |
|
||||
| [[ISSUE-114-frontend-walletconnect-google-client-ids-hardcoded-dockerfile|ISSUE-114]] | Frontend: WalletConnect/Google client IDs hardcoded as Dockerfile ARG defaults | frontend |
|
||||
| [[ISSUE-115-frontend-real-plaintext-credentials-in-committed-scripts|ISSUE-115]] | Frontend: real plaintext credentials in committed scripts | frontend |
|
||||
| [[ISSUE-116-frontend-backend-scanner-ci-images-not-pinned-to-digests|ISSUE-116]] | Frontend/scanner/backend: CI images not pinned to digests | frontend |
|
||||
| [[ISSUE-117-frontend-backend-scanner-production-manual-ci-pipelines-lack-g|ISSUE-117]] | Frontend/scanner/backend: production/manual CI pipelines lack lint/type/test/audit gates | frontend |
|
||||
|
||||
### Low
|
||||
|
||||
| Issue | Title | Repo |
|
||||
|-------|-------|------|
|
||||
| [[ISSUE-118-frontend-notification-title-rendered-via-dangerouslysetinnerht|ISSUE-118]] | Notification title rendered via dangerouslySetInnerHTML | frontend |
|
||||
| [[ISSUE-119-frontend-telegramdebugpanel-exposed-in-production-via-url-flag|ISSUE-119]] | TelegramDebugPanel exposed in production via URL/localStorage flag | frontend |
|
||||
| [[ISSUE-120-frontend-50ms-setinterval-console-suppression-script-in-root-l|ISSUE-120]] | 50ms setInterval console-suppression script in root layout | frontend |
|
||||
| [[ISSUE-121-frontend-transferfunds-and-createpayment-post-to-same-endpoint|ISSUE-121]] | transferFunds and createPayment POST to the same endpoint | frontend |
|
||||
| [[ISSUE-122-backend-missing-compound-index-for-seller-visibility-purchase-r|ISSUE-122]] | Missing compound index for seller-visibility purchase-request query | backend |
|
||||
| [[ISSUE-123-backend-notification-unread-count-chatty-db-access|ISSUE-123]] | Notification unread-count chatty DB access | backend |
|
||||
| [[ISSUE-124-backend-per-seller-socket-emit-loop-in-updatepurchaserequeststatu|ISSUE-124]] | Per-seller socket emit loop in updatePurchaseRequestStatus | backend |
|
||||
| [[ISSUE-125-backend-getcategorypath-unbounded-sequential-findbyid-loop|ISSUE-125]] | getCategoryPath unbounded sequential findById loop | backend |
|
||||
| [[ISSUE-126-backend-getuserpoints-writes-full-user-document-on-read|ISSUE-126]] | getUserPoints writes full User document on read when fields missing | backend |
|
||||
| [[ISSUE-127-scanner-get-intents-id-exposes-salt-and-callbackurl|ISSUE-127]] | Scanner: GET /intents/:id exposes salt and callbackUrl | scanner |
|
||||
| [[ISSUE-128-scanner-post-intents-returns-200-instead-of-201|ISSUE-128]] | Scanner: POST /intents returns 200 instead of 201 | scanner |
|
||||
| [[ISSUE-129-scanner-ton-processTransfer-doesnt-verify-jettonmasteraddress|ISSUE-129]] | Scanner: TON processTransfer doesn't verify JettonMasterAddress vs intent.TokenAddress | scanner |
|
||||
| [[ISSUE-130-scanner-config-getchaingettokengetrpc-on-linear-scans|ISSUE-130]] | Scanner: Config.GetChain/GetToken/GetRPC O(N) linear scans | scanner |
|
||||
| [[ISSUE-131-scanner-tron-ton-workers-dont-share-http-transport|ISSUE-131]] | Scanner: Tron/TON workers don't share HTTP transport | scanner |
|
||||
| [[ISSUE-132-scanner-evm-checkpoint-saved-every-2000-block-chunk|ISSUE-132]] | Scanner: EVM checkpoint saved every 2000-block chunk | scanner |
|
||||
| [[ISSUE-133-scanner-ci-buildx-steps-run-privileged-true|ISSUE-133]] | Scanner: CI buildx steps run privileged: true | scanner |
|
||||
| [[ISSUE-134-frontend-sentry-source-map-upload-configured-but-no-auth-token|ISSUE-134]] | Frontend: Sentry source-map upload configured but no auth token injected | frontend |
|
||||
| [[ISSUE-135-backend-uploads-directory-served-without-authentication|ISSUE-135]] | Backend uploads directory served without authentication | backend |
|
||||
|
||||
---
|
||||
|
||||
## Documentation Gaps Identified (Doc Sync)
|
||||
|
||||
The following gaps were identified but not filled during this audit pass. They should be tracked as separate doc tasks:
|
||||
|
||||
- **Frontend:** Admin dashboard sub-pages (confirmation-thresholds, networks, payments-awaiting-confirmation, trezor) missing from Admin API doc.
|
||||
- **Frontend:** Trezor registration and break-glass UI (commit c9ce345) not reflected in Trezor API or Trezor Safekeeping Flow docs.
|
||||
- **Frontend:** Cloudflare Turnstile/CAPTCHA behavior (3 failed logins) not documented in Authentication Flow or Authentication API docs.
|
||||
- **Frontend:** AMN Pay Scanner lag column and per-row probe button have no dedicated flow or operations doc.
|
||||
- **Frontend:** Telegram startup notification (TG_NOTIFY_BOT_TOKEN) not in Operations/Environment Variables doc.
|
||||
- **Frontend:** Amaneh UI variant toggle — state key and exact behavior not fully described in Settings & Theming.
|
||||
- **Frontend:** `productLink` made truly optional; `deliveryType` required marker dropped — Purchase Request Flow wizard narrative needs update.
|
||||
- **Backend:** Sweep signer strategy (PermitPullSweepSigner + GasTopUpSweepSigner) has no operations runbook.
|
||||
- **Backend:** Native token sweep (BNB/ETH to derived destinations) not reflected in Payment API or sweep operations runbook.
|
||||
- **Backend:** AML screening (OFAC SDN provider) has no dedicated flow doc covering when screening fires, seller opt-in, fee deduction.
|
||||
- **Backend:** GET /api/health response field names not verified against live `healthCheckService` output.
|
||||
- **Backend:** RequestTemplate budget currency restriction (USDT/USDC only) not reflected in Marketplace API or RequestTemplate model docs.
|
||||
- **Backend:** Sweep integration tests (Anvil + INTEGRATION_TEST=1) not covered in Testing.md.
|
||||
- **Backend:** Telegram startup notification (app startup `tgNotify`) not in Monitoring.md.
|
||||
- **Backend:** AMN Pay Scanner adapter internals (amnPayAdapter, amnScannerWebhookRoutes) have no doc.
|
||||
- **Backend:** New env vars (OFAC_SDN_URL, TURNSTILE_SECRET_KEY, TURNSTILE_SITE_KEY, AMN_SCANNER_URL, AMN_SCANNER_WEBHOOK_SECRET) may not be in Environment Variables doc.
|
||||
- **Backend:** Seller Offer Flow does not reflect selectedOfferId persistence fix and atomic offer rejection on payment.
|
||||
- **Backend:** ISSUE-021 (POST /api/marketplace/offers/:id/withdraw) should be marked resolved (implemented in commit 3e47713).
|
||||
- **Scanner:** No doc for CI pipeline structure (.woodpecker/ steps, secrets, image push flow).
|
||||
- **Scanner:** No doc for test suite (chain_validate_test.go / reference_test.go / tron_chain_test.go) and how to extend it.
|
||||
- **Scanner:** Multi-chain reorg edge cases and exact ReorgBuffer formula not in troubleshooting doc.
|
||||
- **Scanner:** TON scaling limitation (O(pending intents) API calls per cycle) noted but no mitigation/batching design documented.
|
||||
- **Scanner:** RN proxy address discrepancy in supported-chains.json (ETH v0.1.0 vs v0.2.0) not documented.
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [[Security Audit - 2026-05-24]]
|
||||
- [[Logic Audit - 2026-05-24]]
|
||||
- [[Performance Audit - 2026-05-24]]
|
||||
- [[Doc vs Code Audit Report - 2026-05-29]]
|
||||
Reference in New Issue
Block a user