Codex Security Second-Pass Review
Archival note: this document is a security review record, not current product or architecture guidance. Where its finding text quotes older code, wording may reflect historical states rather than current account-model terminology.
Re-evaluation of archival Codex finding exports against current HEAD code. This pass explicitly checks for false positives, superficial fixes, and security-theater remediations.
Summary
- Total findings reviewed: 92
- Verdicts: Legit issue 83, False positive 5, Unclear 4
- Fix assessments: Correct 58, Partial 18, Unresolved 15, Suspicious 1, Incorrect 0
Prioritized Residual Risk Queue
| Priority | Finding ID | Title | Fix assessment | Recommended follow-up |
|---|---|---|---|---|
| P1 | 9d6391c902808191822d848bc1ea64f6 | Token image endpoint returns raw upstream bytes via style=raw | Unresolved | Disable raw mode for untrusted URLs or trusted-overrides only; validate MIME and magic bytes before embedding. |
| P1 | 8f7b5511374c8191b6457a9d9dfe58c9 | Token image endpoint now prefers originalUri, enabling SSRF | Unresolved | Add SSRF guards in fetchBytes (scheme, DNS/IP, private-range denylist) and avoid preferring untrusted originalUri over vetted images. |
| P1 | b6d9f0250f8c819187bb64f3dbd5cdcf | Unbounded raw image processing enables DoS in token image API | Unresolved | Enforce max download bytes/pixels before decode, reject oversized images, and bound heavy image transforms. |
| P1 | bd7cb9302e24819197695b42f73118f6 | Runtime lease table lacks RLS enabling lock hijack DoS | Unresolved | Add migration: ENABLE RLS + deny-all except service role writes. |
| P1 | 28d4eb1f87e081918b4c48077544221c | RPC proxy timeout errors leak upstream RPC URLs | Unresolved | Return generic upstream errors to clients; log full RPC URLs only on the server. |
| P1 | b83a4d49a4e48191a986dfb1feb0665f | Ajna inner vault exposed without adapter-only access control | Unresolved | Restrict user-facing methods to adapter/approved caller paths. |
| P1 | afe55d04489481918eeebd4d2aa87495 | SSRF via Zora image fetch in image auto-assets handler | Unresolved | Apply URL destination allowlisting plus response-size caps before fetching and storing subject assets. |
| P1 | bf36c2639dc48191b4541fda549cbb6d | Baseline reset skips profit reporting after large withdrawals | Suspicious | Run econ-invariant tests for withdraw->report->redeposit cycles and confirm intended fee behavior. |
| P1 | a356311f4fa881919c1c0d61f9b48278 | Solana hook config can be initialized by any signer | Unresolved | Add mint-authority or registry-admin constraint for initialization. |
| P1 | 92d4820688388191a214c33b24b8266d | Quickstart endpoint allows self-allowlisting | Unresolved | Require explicit admin/approval before allowlist write. |
| P1 | 9b030c9327e48191a0c0d6926ef9b034 | Unauthenticated /api/rpc proxy exposes RPC backend to abuse | Unresolved | Require auth + method allowlist + stronger per-client rate limits on /api/rpc. |
| P1 | 0285a61e189c81918b37cb74f00d15a2 | SSRF via token image caching to Vercel Blob | Unresolved | Implement SSRF destination controls and restrict caching/persistence of untrusted fetch results. |
| P1 | 6b0c1eb120588191b26e553d053604ac | Paymaster phase2 validation bypass via spoofed wrapper/shareOFT | Unresolved | Verify wrapper.vault and shareOFT.vault (and ownership expectations) before phase2 sponsorship. |
| P1 | ed4eed76195c8191a03680cd108eb740 | Strict fallback deferral can stall agent conversations | Unresolved | Persist skip/processed state for deferred unsupported commands or advance checkpoint past blocker. |
| P1 | ab770ea04a748191950f64df6514c747 | Swap UI labels arbitrary URL tokens as creator/share assets | Unresolved | Do not auto-verify URL tokens; require trusted metadata before creator/share labeling. |
| P1 | 41c8fbaba520819182141454e74d51e7 | Privy wallet policy enforcement disabled in production | Unresolved | Fail closed in production when policy ID is missing. |
| P2 | 59dc7f81b9248191ae3016f5f66483ae | Legacy profile fallback enables deploy session auth bypass | Partial | Remove legacy profiles fallback after profile_wallets migration. |
| P2 | b98caf93de5881919c7e835a075935f6 | Paymaster ownership bypass for contract sessions | Partial | Enforce sender provenance (known CSW factory/codehash) before sponsorship. |
| P2 | 91ffbf79090881919f3f472da627bf18 | Private DM flag bypasses Telegram chat allowlist | Partial | Add explicit DM allowlist/role gates for sensitive commands when private DMs are enabled. |
| P2 | a03ca8a6034881919a12617c0217c3d5 | Swap sponsorship allows arbitrary router actions via dummy approval | Partial | Parse Universal Router commands; allow only swap opcodes that spend approved token, reject sweeps/transfers. |
| P2 | a7baba2d3598819198913618869ed804 | Unauthenticated Uniswap proxy exposes server API key usage | Partial | Require auth or signed client attestation for quote/swap; keep rate limits as secondary control. |
| P2 | 4f3d7b2901648191a9146caea4e2f13a | Unauthenticated LLM SSE endpoint allows cost/DoS abuse | Partial | Add endpoint rate limiting and hard cap/truncate context length before LLM call. |
| P2 | 259e497be010819192f6b981fe9489ff | Unvalidated CSW owner check enables waitlist auth bypass | Partial | Require CSW provenance validation before owner fallback (known factory/codehash or registry proof). |
| P2 | c342ee029908819182aa1820240fb636 | Unified Eliza runtime logs full XMTP messages to console | Partial | Remove/redact legacy runtime content logging to avoid accidental sensitive data capture. |
| P2 | 807df1684c10819191964019ee697c09 | Unbounded chainId input enables wallet intelligence DoS | Partial | Cap chainIds length and validate against supported allowlist before fanout. |
| P2 | 7a70955b62548191b74e670fe32def82 | Legacy paymaster path accepts unverified vault targets | Partial | Add vault/wrapper/shareOFT provenance checks (registry or expected bytecode/hash) in legacy mode. |
| P2 | f109ef33b8fc8191b54c429d9e0d8e66 | Imagegen endpoints allow unauthorized vault image association | Partial | Require actor ownership checks in _auto-assets before attachImageGenerationAsset writes. |
| P2 | af26ff093f5c81918f073dc51f216025 | Paymaster rejection now falls back to direct executeBatch | Partial | Block direct owner executeBatch fallback for paymaster policy denials. |
| P2 | 77f7f3db5208819188c9c4dd047e84dd | In-memory daily /send limits allow bypass across instances | Partial | Fail closed when durable ledger unavailable; remove memory fallback. |
| P2 | f54844584d3481918d0c73c31e49460d | Public portfolio endpoint proxies Debank without rate limits | Partial | Add rate limiting and short TTL cache for public Debank summary fetches. |
| P2 | 166c8f080c448191a1a7fd4f256fbc73 | Charm factory vaults leave governance under external control | Partial | Document trust assumptions and monitor governance changes. |
| P2 | 02fa81d2b3c481919eafb4402de519d3 | Public agents list exposes unlisted creator XMTP agents | Partial | Gate listed=false to admin scope and use no-store/private cache with auth Vary. |
| P2 | 1c5de7cd487881919dc45d57d8749faf | Rate-limit bypass via spoofed IP headers in Debank token list | Partial | Document trusted proxy headers and enforce/validate IP provenance at the edge. |
| P2 | d4cd49c74af881918536e24562eba9c9 | Unfiltered LiquidityMigrated logs enable spoofed fee status | Partial | Add factory/registry provenance checks or contract-address filtering to remove residual spoof surface. |
Full Per-Finding Matrix
| Row | Finding ID | Verdict | Fix assessment | Why / Evidence | Recommended follow-up | Confidence |
|---|---|---|---|---|---|---|
| 1 | 2b8cbe89e2548191ba9b3782176b74e0 | Unclear | Correct | Telegram miniapp link no longer checks shared API secret — telegram/_miniapp-link.ts: enforces verifyTelegramLinkApiSecret unless miniapp session is required, then validates miniAppSessionToken + user/chat match. | Optionally require both session token and shared secret for extra defense-in-depth. | Medium |
| 2 | 8f7b5511374c8191b6457a9d9dfe58c9 | Legit issue | Unresolved | Token image endpoint now prefers originalUri, enabling SSRF — _image.ts prefers mediaContent.originalUri; fetchSourceArtworkBytes -> fetchBytes(url). blob.ts fetch follows redirects with no host/IP or private-range guard. | Add SSRF guards in fetchBytes (scheme, DNS/IP, private-range denylist) and avoid preferring untrusted originalUri over vetted images. | High |
| 3 | b6d9f0250f8c819187bb64f3dbd5cdcf | Legit issue | Unresolved | Unbounded raw image processing enables DoS in token image API — _image.ts cropTransparentPadding -> getAlphaBounds decodes raw RGBA and scans all pixels; no pre-decode byte/pixel limits on fetched artwork. | Enforce max download bytes/pixels before decode, reject oversized images, and bound heavy image transforms. | High |
| 4 | ed4eed76195c8191a03680cd108eb740 | Legit issue | Unresolved | Strict fallback deferral can stall agent conversations — agent/_process.ts: strict retry defaults true; deferred fallback path hits shouldDeferFallbackCommand then break, allowing repeated reprocessing of same blocker msg. | Persist skip/processed state for deferred unsupported commands or advance checkpoint past blocker. | High |
| 5 | 9724eddabad081918ce072fc0c7a2763 | False positive | Correct | Default private DM enablement exposes Telegram bot — telegram/webhook/config.ts: allowPrivateDmsExplicit defaults false; TELEGRAM_ALLOW_ALL_PRIVATE_DMS also parses with default false. | Keep DM defaults false and document the opt-in flags clearly. | High |
| 6 | 9d6391c902808191822d848bc1ea64f6 | Legit issue | Unresolved | Token image endpoint returns raw upstream bytes via style=raw — _image.ts permits style=raw and embeds fetched bytes into SVG/PNG data URIs; bytes come from metadata-controlled URLs without strict content validation. | Disable raw mode for untrusted URLs or trusted-overrides only; validate MIME and magic bytes before embedding. | High |
| 7 | 77526e64416481918b46ac84d257fe88 | Legit issue | Correct | Telegram mini app replay nonce bypass via initData ordering — miniAppAuth.ts now hashes canonical sorted initData; _miniapp-session.ts claims replay nonce by initDataHash; DB replay table enforces uniqueness. | No immediate action; keep replay TTLs tuned to balance security/usability. | High |
| 8 | 11436050f3988191b7933dae2e30e9bc | Legit issue | Correct | Host header injection in auction status image URL — _status.ts builds auctionTokenImageUrl origin from API_HOST via getCanonicalApiOrigin(); request host/forwarded host are not used. | Keep API_HOST pinned per env and retain spoofed-host regression coverage. | High |
| 9 | 91ffbf79090881919f3f472da627bf18 | Legit issue | Partial | Private DM flag bypasses Telegram chat allowlist — services/access.ts still ORs allowedByPrivateDm; _webhook.runtime.ts now mitigates privileged fallback by forcing non-admin DM to groupId=telegram:<chat> + zero sender. | Add explicit DM allowlist/role gates for sensitive commands when private DMs are enabled. | High |
| 10 | 46fee1d3435c8191bf9c9bd72d6fd9e0 | Legit issue | Correct | Plain-text chats now sent to LLM, leaking group content — parsers/command.ts auto-routes only for @keepr/@bot or reply-to-bot; keepr/commands.ts AI trigger is /ai or mention, not arbitrary plain chat. | Retain mention/reply gating and avoid reintroducing plain-text auto routing. | High |
| 11 | 6ab225238d408191a0657ea78d4b2226 | Legit issue | Correct | Holder-room invite links exposed to group chat — telegram/_webhook.runtime.ts: for non-private chats, /join sends invite via DM and group response omits the invite link. | Optionally require private-chat /join flow only for stricter room-link hygiene. | High |
| 12 | 659aa8f7408881918ccc8c725a7208f1 | Legit issue | Correct | Admin trend endpoints set public cache headers — _trendStatus.ts calls setNoStore; auth/_shared.ts sets Cache-Control: no-store. | Keep admin telemetry endpoints non-cacheable; add Vary auth if caching returns. | High |
| 13 | d8f06e5842fc8191a7964223c11c413c | Legit issue | Correct | Flat gauge boost enables jackpot farming via tiny swaps — CreatorLotteryManager._applyBoost now uses _scaleGaugeBoostBySwapSize; it returns 0 at/below minSwap and scales linearly above. | Keep invariant tests that tiny swaps get zero gauge boost. | High |
| 14 | bd7cb9302e24819197695b42f73118f6 | Legit issue | Unresolved | Runtime lease table lacks RLS enabling lock hijack DoS — frontend/server/agent/eliza/index.ts creates agent_runtime_leases in RUNTIME_LEASE_TABLE_SQL with no RLS enablement or deny policies. | Add migration: ENABLE RLS + deny-all except service role writes. | High |
| 15 | 28d4eb1f87e081918b4c48077544221c | Legit issue | Unresolved | RPC proxy timeout errors leak upstream RPC URLs — _proxy.ts still emits RPC request timeout (${rpc}) and chain-mismatch errors containing ${rpc}, exposing upstream RPC URLs. | Return generic upstream errors to clients; log full RPC URLs only on the server. | High |
| 16 | 4d02347d973081919d9369104b78901a | Legit issue | Correct | Unauthenticated social recipient API leaks wallet mappings — _recipient.ts now requires authenticated principal (401 when missing) and adds per-principal+IP rate limiting before resolution. | Keep auth mandatory and add tests preventing anonymous wallet-mapping queries. | High |
| 17 | b83a4d49a4e48191a986dfb1feb0665f | Legit issue | Unresolved | Ajna inner vault exposed without adapter-only access control — AjnaERC4626Vault deposit/mint/withdraw/redeem remain public+notPaused; onlyAdapterAuthorized guards only bucket-move methods. | Restrict user-facing methods to adapter/approved caller paths. | High |
| 18 | d0bce986a0e081918be1a17557530268 | Legit issue | Correct | Dry-run endpoint allows auth bypass via dev header — deploy/session/_dryRun.ts requires readDeployAuthFromRequest and returns 401 when absent; no X-Deploy-Dry-Run-Dev bypass branch remains. | If a dev bypass is ever restored, gate by localhost plus secret and NODE_ENV=development. | High |
| 19 | 308d297cac3081919ba90a0f9c568b2c | Legit issue | Correct | Public vault-image API exposes project IDs used for writes — _vault-image-get.ts now requires auth and owner-scoped getCompletedImageProjectForVaultOwner; _assets-upload.ts enforces project.ownerAddress == actor. | Keep owner-scoped reads and add regression tests for projectId leakage and cross-user asset upload attempts. | High |
| 20 | afe55d04489481918eeebd4d2aa87495 | Legit issue | Unresolved | SSRF via Zora image fetch in image auto-assets handler — _auto-assets.ts resolves subjectUrl from Zora metadata then calls fetchBytes(subjectUrl); AUTO_ASSET_MAX_BYTES exists but is not enforced on subject fetch. | Apply URL destination allowlisting plus response-size caps before fetching and storing subject assets. | High |
| 21 | ad025f0168248191a3effac8b426d34b | Legit issue | Correct | Unrestricted vault image association enables token icon defacement — _associate-vault.ts now checks auth, project owner/status, creatorAddress match, and vault control for non-admin callers. | Retain these checks and add tests for cross-user project association and unauthorized vault binding. | High |
| 22 | a03ca8a6034881919a12617c0217c3d5 | Legit issue | Partial | Swap sponsorship allows arbitrary router actions via dummy approval — frontend/api/_handlers/_paymaster.ts assertSwapRouterPayloadReferencesToken() only checks token substring in router inputs; command semantics are not enforced. | Parse Universal Router commands; allow only swap opcodes that spend approved token, reject sweeps/transfers. | Medium |
| 23 | f109ef33b8fc8191b54c429d9e0d8e66 | Legit issue | Partial | Imagegen endpoints allow unauthorized vault image association — Most image mutations enforce ownership, but _auto-assets.ts is auth-only and accepts arbitrary projectId for asset writes (no actor==project.ownerAddress check). | Require actor ownership checks in _auto-assets before attachImageGenerationAsset writes. | Medium |
| 24 | e25ee52ab4208191ada0657e832a7062 | False positive | Correct | Paymaster ABI missing finalizePhase2WithPermit2 entry — frontend/api/_handlers/_paymaster.ts CREATOR_VAULT_BATCHER_PHASE_ABI now includes finalizePhase2WithPermit2 and decode path accepts it. | No action; keep decode regression tests for finalizePhase2WithPermit2. | High |
| 25 | bf1c0ee1c514819187b5065a5b807c65 | Legit issue | Correct | Hub composer pools wrapper dust/fees across cross-chain users — OVaultHubComposer now uses wrapper depositFor/withdrawFor(receiver); CreatorOVaultWrapper attributes accounting to beneficiary with operator checks. | Keep beneficiary-operator allowlist strict and assert attribution invariants in tests. | High |
| 26 | 4a4f8742738481919c9140c0b67f9194 | Legit issue | Correct | Documentation leaks production provisioner host details — AGENTS.md now states provisioner host/IP/SSH/fs details are intentionally excluded; points to internal runbook. | Add docs lint rule to block host/IP/SSH leakage patterns. | High |
| 27 | eb979cce1de48191a764ac6905f94265 | Legit issue | Correct | Missing PDA constraints let attackers tamper with pending entries — execute_hook.rs now enforces pending_entries PDA seeds plus creator_mint match constraint on AccountLoader. | Retain mismatched-mint negative tests in Anchor suite. | High |
| 28 | 84403c5655d48191a01fbfbab436f7b0 | Legit issue | Correct | Missing PendingEntries PDA validation enables cross-creator drains — drain_entries.rs now enforces pending_entries PDA seeds and creator_mint consistency constraint before draining/resetting. | Keep cross-creator drain negative tests. | High |
| 29 | c94aa40862508191a22451f694c04bea | Legit issue | Correct | Allowlist bypass via spoofed creatorToken resolution — frontend/api/_handlers/deploy/session/_create.ts resolveAllowlistAddresses() checks session+smartWallet only; no creator/payout expansion for allowlist. | No action; keep tests proving allowlist does not trust token-returned parties. | High |
| 30 | 34a60a4cb880819189e05f764d44fdae | False positive | Correct | Waitlist modal can remain stuck open after OAuth redirect — Home.tsx adds waitlistDismissVersion and recompute path so sticky modal closes immediately without URL change. | No security action; keep UI regression test for sticky close. | High |
| 31 | a42db31449ec81919f11c784af9de532 | Legit issue | Correct | Public verification endpoint leaks RPC diagnostics — _verification.ts returns rpcHealthy/rpcErrorCount only; raw RPC endpoint/error details are no longer exposed. | Keep diagnostics aggregate-only and block any future raw upstream URL/error string exposure. | High |
| 32 | bf36c2639dc48191b4541fda549cbb6d | Unclear | Suspicious | Baseline reset skips profit reporting after large withdrawals — CreatorOVaultCoreModule can zero report baseline on outflow, and report() treats baseline==0 as bootstrap returning (0,0). | Run econ-invariant tests for withdraw->report->redeposit cycles and confirm intended fee behavior. | Medium |
| 33 | 478483d7f108819180bbb15a7a863b67 | Legit issue | Correct | OpenClaw bridge surface has been retired during endpoint cleanup (openclaw/execute removed). | No further action on retired endpoint. | High |
| 34 | 3a9dfff89d6c81919b275e5c9503eba5 | Legit issue | Correct | OpenClaw bridge surface has been retired during endpoint cleanup (openclaw/execute removed). | Duplicate retired root of 478. | High |
| 35 | 53d11dc8dd3081919bd7cd7bc636ac39 | Legit issue | Correct | OpenClaw bridge surface has been retired during endpoint cleanup (openclaw/execute removed). | Duplicate retired root of 478. | High |
| 36 | ab770ea04a748191950f64df6514c747 | Legit issue | Unresolved | Swap UI labels arbitrary URL tokens as creator/share assets — Swap.tsx reads token/share URL params; swapUtils.ts labels them Creator Coin/Share Token; Swap.tsx defaults creator/share groups to verified. | Do not auto-verify URL tokens; require trusted metadata before creator/share labeling. | High |
| 37 | a7baba2d3598819198913618869ed804 | Legit issue | Partial | Unauthenticated Uniswap proxy exposes server API key usage — _quote.ts and _swap.ts remain public POST handlers; trading.ts always injects server x-api-key in uniswapTradeFetch, though routes are rate-limited. | Require auth or signed client attestation for quote/swap; keep rate limits as secondary control. | High |
| 38 | c0d4a45680bc8191891a3bbc2bb576c7 | False positive | Correct | Auto Solana registration drops SIWA header — frontend/api/_handlers/deploy/session/_status.ts tryRegister() forwards X-SIWA-Receipt (plus auth/cookie/privy token) to internal registration call. | No action; keep header-forwarding regression for SIWA/Privy auth. | High |
| 39 | 846f599cf0688191b467d70236b5b993 | Legit issue | Correct | Waitlist errors leak raw database initialization details — _waitlist.ts returns generic waitlistServiceUnavailableMessage on DB failures; postgres init details are logged server-side, not returned. | Keep generic client-facing outage messages; avoid returning DB/Supabase internals. | High |
| 40 | 240a40c3fb488191a52f0ae21b5c885c | Legit issue | Correct | Owner check can fail due to unhandled ownerAtIndex revert — _smartWalletOwner.ts wraps nextOwnerIndex and each ownerAtIndex read in try/catch, continuing scan on reverting or sparse slots. | Keep sparse-owner and reverting-slot tests to prevent future regressions. | High |
| 41 | 41c8fbaba520819182141454e74d51e7 | Legit issue | Unresolved | Privy wallet policy enforcement disabled in production — requirePrivyPolicyId only warns in prod; createAgentWallet omits policy_ids when PRIVY_WALLET_POLICY_ID is unset. | Fail closed in production when policy ID is missing. | High |
| 42 | 6dfda97fa6b88191b52905bc8a90b955 | Legit issue | Correct | Deploy sessions bypass paymaster validation via direct CDP endpoint — frontend/api/_handlers/deploy/session/_continue.ts sendStage() validates with validateSponsoredSmartWalletCalls() before sending, even on direct CDP endpoint. | No action; keep direct-CDP regression tests for local validation before send. | High |
| 43 | e7fa3fc6da488191a0844b44a75c59d6 | Legit issue | Correct | Direct CDP endpoint bypasses paymaster validation in deploy flow — frontend/api/_handlers/deploy/session/_continue.ts direct getBundlerEndpoint() path still runs local sponsorship validation and grant checks. | No action; keep validation/grant checks mandatory on all bundler routes. | High |
| 44 | 6e149f10ac2881918276e5bfb097eed6 | Legit issue | Correct | Deploy-session owner now persists as permanent CSW owner — frontend/api/_handlers/deploy/session/_create.ts shouldPersistManagedSessionOwner() defaults to false; cleanup removeOwnerAtIndex is appended unless persisted. | No action; keep default false for DEPLOY_SESSION_PERSIST_OWNER and cleanup tests. | High |
| 45 | 197103f53dbc8191806d75b7ac9b2543 | Legit issue | Correct | Deploy session no longer verifies creator token ownership — frontend/api/_handlers/deploy/session/_create.ts validateDeploySessionRequest() calls assertCreatorTokenAuthority() (creator/payout/owner must include session/owner). | No action; keep creator-token authority checks in session-create tests. | Medium |
| 46 | 87c94a7bcff4819199b06f39f23213d8 | Legit issue | Correct | Hard-coded admin bypass wallet added to protected route checks — App.tsx no longer hardcodes bypass admin wallet; trust.ts reads admin set from CREATOR_ACCESS_ADMIN_ADDRESSES only. | Keep admin sources env-only and rotate via secrets. | High |
| 47 | 9c83ecff4b1081918584536036edb043 | Legit issue | Correct | Email-based upserts can merge profiles without email verification — walletSync now uses extractPrivyVerifiedEmail and assertNoEmailPrivyCollision before ON CONFLICT(email) upsert. | Add test cases for unverified-email takeover attempts. | High |
| 48 | 4f3d7b2901648191a9146caea4e2f13a | Legit issue | Partial | Unauthenticated LLM SSE endpoint allows cost/DoS abuse — agent/_stream.ts now requires session (401 unauth), but accepts unbounded context; eliza/llm.ts concatenates full vaultContext into systemBlock. | Add endpoint rate limiting and hard cap/truncate context length before LLM call. | Medium |
| 49 | bff6d45c8434819197e4217b22bd5967 | Legit issue | Correct | Public admin bypass list now grants server-side admin access — session.ts uses trust.ts server admin set only, and .env.example documents CREATOR_ACCESS_ADMIN_ADDRESSES with no public VITE bypass. | Keep tests preventing VITE_* values from influencing server admin authorization. | High |
| 50 | 0fc1d49fccc88191b5718656bcc1ae15 | Legit issue | Correct | Hardcoded admin wallet grants persistent backdoor access — session.ts isAdminAddress delegates to isServerAdminAddress; trust.ts only reads CREATOR_ACCESS_ADMIN_ADDRESSES and has no hardcoded admin wallet. | Add regression tests ensuring server admin auth never accepts hardcoded or VITE-sourced addresses. | High |
| 51 | 8006cad63bdc81919e8bb546d81314cc | Legit issue | Correct | Preflight deploy session bypasses rate limit enabling DoS abuse — frontend/api/_handlers/deploy/session/_create.ts preflightOnly now has its own limiter: deploy-preflight max 20/min. | No action; keep preflight-specific rate-limit coverage. | High |
| 52 | 59dc7f81b9248191ae3016f5f66483ae | Legit issue | Partial | Legacy profile fallback enables deploy session auth bypass — deploy/session/_create.ts still has compatibility fallback using profiles primary_wallet/csw/base_sub_account in ownership linking. | Remove legacy profiles fallback after profile_wallets migration. | Medium |
| 53 | af26ff093f5c81918f073dc51f216025 | Legit issue | Partial | Paymaster rejection now falls back to direct executeBatch — frontend/src/pages/deploy/DeployVault.tsx tryOwnerDirectExecuteBatchFallback() still triggers on request denied - in direct Coinbase path and sends direct executeBatch. | Block direct owner executeBatch fallback for paymaster policy denials. | Medium |
| 54 | 1ca1c2026a288191ae8fc98ce2c85f0d | Legit issue | Correct | XMTP encryption downgraded when legacy plaintext DB exists — server/agent/eliza/index.ts and server/keepr/xmtpQueueExecutor.ts throw on plaintext DB unless confirmed migration flags are explicitly set. | Keep strict migration guardrails; alert on plaintext DB detection in ops monitoring. | High |
| 55 | 73661bbd4260819189a7c1513e362c0e | Legit issue | Correct | Waitlist sync endpoints were hardened against repeated point minting, then retired during cleanup (agent-points-sync, lens-points-sync removed from route map). | No further action on these retired endpoints; keep idempotency protections on any replacement sync path. | High |
| 56 | c6c5159f8b2c8191a168d425964e04a5 | Legit issue | Correct | Dynamic Solana route provisioning lacks admin/rate gating — frontend/api/_handlers/deploy/_registerSolanaBridgeToken.ts now requires admin/internal authorization and applies per-caller/IP rate limiting. | No action; keep admin/internal auth + throttling tests on dynamic provisioning path. | High |
| 57 | 1f0a03b44f7c8191b1a4dd4f7f45c52b | Legit issue | Correct | ShareOFT auto-registration endpoint lacks deployment allowlist — frontend/api/_handlers/deploy/_registerSolanaBridgeToken.ts write path (registerToken) is gated by admin/internal secret, not generic session auth. | No action; keep registration write operations restricted to admin/internal callers. | High |
| 58 | 8d2811322f088191a5884f770b9cfdb8 | Legit issue | Correct | Phase1 split enables CREATE2 squatting DoS on shareOFT — contracts/helpers/batchers/DeploymentBatcher.sol _finalizePhase1InternalSplit() catches deploy collision and reuses existing deterministic ShareOFT address. | No action; keep finalize collision-reuse tests for deterministic ShareOFT. | High |
| 59 | 259e497be010819192f6b981fe9489ff | Legit issue | Correct | Legacy waitlist owner-check fallback surface was retired with endpoint cleanup (waitlist/profile-complete removed). | No further action on retired endpoint; keep strict CSW provenance checks on any replacement flow. | Medium |
| 60 | e3612b4c891c8191b57b4028df06b2d7 | False positive | Correct | Lens owner lookup broken by using account addresses query — lensAccounts.ts now queries AccountsBulkQuery with ownedBy first; addresses is only a fallback path. | No security action; keep owner-resolution regression tests. | High |
| 61 | c342ee029908819182aa1820240fb636 | Unclear | Partial | Unified Eliza runtime logs full XMTP messages to console — Unified runtime (frontend/server/agent/eliza/index.ts) logs digest via summarizeInboundMessageForLog; legacy eliza/src/index.ts still logs msg.content.slice(0, 80). | Remove/redact legacy runtime content logging to avoid accidental sensitive data capture. | Medium |
| 62 | f8cbadab6ac0819198b9d4f99ebd28a1 | Legit issue | Correct | Legacy OpenClaw execution endpoint has been retired (openclaw/execute removed); unified wallet-intel plugin remains direct-server path. | Keep per-tool cost quotas on active wallet-intel command paths. | Medium |
| 63 | 977e9770c1d0819197d930273262ff33 | Legit issue | Correct | Feedback index exposes request IPs and accepts unverified entries — v1/agents/feedback/_submit.ts is guarded (kind='write'); agentAudit.ts stores ip_hash; indexFeedback rejects invalid address or feedbackIndex<=0. | If public indexed reads are unnecessary, require auth for mode=indexed. | Medium |
| 64 | 807df1684c10819191964019ee697c09 | Legit issue | Partial | Unbounded chainId input enables wallet intelligence DoS — v1/agents/_wallet-intelligence.ts accepts arbitrary chainIds; funderTrace.ts fans out with Promise.all(chainIds.map(...)) and has no chain-count cap. | Cap chainIds length and validate against supported allowlist before fanout. | High |
| 65 | 548424e0aa048191b06ffdbcbb3a386b | Legit issue | Correct | XMTP DB encryption key cached in localStorage — src/lib/xmtp/provider.tsx keeps DB encryption keys in inMemoryEncKeys; localStorage is used for flags, not encryption key material. | Keep key material ephemeral; clear in-memory map on disconnect/logout. | High |
| 66 | a356311f4fa881919c1c0d61f9b48278 | Legit issue | Unresolved | Solana hook config can be initialized by any signer — initialize_creator.rs accepts arbitrary Signer authority and unchecked creator_mint; no mint-authority/registry ownership check. | Add mint-authority or registry-admin constraint for initialization. | High |
| 67 | 528cbdffedc0819198bad3c77bb36ce4 | Legit issue | Correct | Allowlist gating bypassed when allowlist API fails — App.tsx resolveAllowlistMode returns unknown when data missing; computeAcceptedFromAllowlist fails closed for unknown mode. | Keep fail-closed behavior with API-failure test coverage. | High |
| 68 | 92d4820688388191a214c33b24b8266d | Legit issue | Unresolved | Quickstart endpoint allows self-allowlisting — v1/creators/_quickstart.ts still calls autoAllowlist for authenticated canonical principal without separate admin approval gate. | Require explicit admin/approval before allowlist write. | High |
| 69 | 77f7f3db5208819188c9c4dd047e84dd | Legit issue | Partial | In-memory daily /send limits allow bypass across instances — sendCommand has durable keepr_send_daily_ledger, but DB read/write failures fall back to in-memory Map limits. | Fail closed when durable ledger unavailable; remove memory fallback. | High |
| 70 | 8343861b63c08191bf6563a2799e79f4 | Legit issue | Correct | Agent registration may default to agentId 0 when unset — agentRegistration sets agentId = NaN when env missing and returns missing-config error; no implicit Number('') -> 0 path. | Keep config validation tests for missing agent ID. | High |
| 71 | bf8e477df4a4819190958b528b275208 | Legit issue | Correct | CRE keeper trusts unverified registry entries for onchain calls — frontend/api/_handlers/cre/vaults/_active.ts, frontend/api/_handlers/keepr/vault/_upsert.ts, and CRE actions enforce validate/verifyVaultRegistryBinding before execution. | Keep onchain registry binding checks mandatory across workflows. | High |
| 72 | 388ce85d2d448191af99d6ea5eed20dd | Legit issue | Correct | SIWE URI check trusts spoofable forwarded host header — auth/_verify.ts validates SIWE domain/URI against trusted origins; origin.ts only accepts forwarded host in non-prod allowlist. | Ensure APP_ORIGIN/VERCEL_URL are set in production. | High |
| 73 | dcdd9edcc0308191acef7c759865f80a | Legit issue | Correct | Public portfolio endpoint exposes linked wallet graph — _me.ts public mode returns canonical-only wallets with provider/type stripped and sets profile.primaryEmbeddedEoa to null. | Maintain canonical-only public projection and test that embedded/linked wallets never leak. | High |
| 74 | f54844584d3481918d0c73c31e49460d | Legit issue | Partial | Public portfolio endpoint proxies Debank without rate limits — _me.ts public address mode still calls Debank fetchOnchainSummary without endpoint rate limiting; only mitigation is profile-row gating. | Add rate limiting and short TTL cache for public Debank summary fetches. | Medium |
| 75 | 166c8f080c448191a1a7fd4f256fbc73 | Legit issue | Partial | Charm factory vaults leave governance under external control — DeploymentBatcher adds _enforceCharmFactoryGovernance/_enforceCharmVaultManager, but system still depends on external Charm governance trust. | Document trust assumptions and monitor governance changes. | Medium |
| 76 | b98caf93de5881919c7e835a075935f6 | Legit issue | Partial | Paymaster ownership bypass for contract sessions — frontend/api/_handlers/_paymaster.ts assertSessionOwnsSender() for deployed senders only calls isOwnerAddress; it does not verify sender is a Coinbase Smart Wallet. | Enforce sender provenance (known CSW factory/codehash) before sponsorship. | Medium |
| 77 | fefb3d0795cc8191bbcb713dfc559248 | Legit issue | Correct | Legacy withdrawal paymaster path bypasses allowlist — frontend/api/_handlers/_paymaster.ts validateSponsoredSmartWalletCalls() always runs assertCreatorAllowlisted() after validation, including legacy_withdraw. | No action; keep legacy-withdraw allowlist enforcement tests. | High |
| 78 | 89470bff2e008191bd9c7b3262a02e75 | Legit issue | Correct | Paymaster allowlist bypass for legacy withdraw calls — frontend/api/_handlers/_paymaster.ts allowlist is no longer skipped for legacy_withdraw; same enforcement path as other modes. | No action; keep regression tests for allowlist checks on legacy selectors. | High |
| 79 | 7a70955b62548191b74e670fe32def82 | Legit issue | Partial | Legacy paymaster path accepts unverified vault targets — frontend/api/_handlers/_paymaster.ts legacy_withdraw infers vault via selectors + asset() without registry/bytecode provenance checks on legacy targets. | Add vault/wrapper/shareOFT provenance checks (registry or expected bytecode/hash) in legacy mode. | Medium |
| 80 | 9b030c9327e48191a0c0d6926ef9b034 | Legit issue | Unresolved | Unauthenticated /api/rpc proxy exposes RPC backend to abuse — _proxy.ts remains public POST JSON-RPC forwarding without auth or method allowlist; _routes.ts still exposes rpc. | Require auth + method allowlist + stronger per-client rate limits on /api/rpc. | High |
| 81 | 02fa81d2b3c481919eafb4402de519d3 | Legit issue | Partial | Public agents list exposes unlisted creator XMTP agents — _list.ts blocks listed=false without g.auth, but still sets public cache and listCreatorXmtpAgents(listedOnly=false) returns unlisted rows. | Gate listed=false to admin scope and use no-store/private cache with auth Vary. | Medium |
| 82 | 0285a61e189c81918b37cb74f00d15a2 | Legit issue | Unresolved | SSRF via token image caching to Vercel Blob — _image.ts server-fetches metadata-driven artwork and caches rendered output via blobPutBytes to public blob URLs without SSRF destination controls. | Implement SSRF destination controls and restrict caching/persistence of untrusted fetch results. | High |
| 83 | 6b0c1eb120588191b26e553d053604ac | Legit issue | Unresolved | Paymaster phase2 validation bypass via spoofed wrapper/shareOFT — frontend/api/_handlers/_paymaster.ts deploy_phase2 validates vault, but does not verify calldata wrapper/shareOFT are linked to that expected vault. | Verify wrapper.vault and shareOFT.vault (and ownership expectations) before phase2 sponsorship. | Medium |
| 84 | a7113163dd3881919c8c5c1b53cfa03c | Legit issue | Correct | Paymaster trusts unvalidated vault codeId in CREATE2 check — frontend/api/_handlers/_paymaster.ts now enforces vaultCodeId == CREATOR_OVAULT_CODE_ID (vault_codeid_not_allowed) before CREATE2 derivation. | No action; keep vault codeId allowlist assertions in paymaster tests. | High |
| 85 | 98d893bf77188191a70b066482c76767 | Legit issue | Correct | Brand asset sync follows symlinks and can leak build files — sync-docs.mjs uses followSymbolicLinks:false, lstat symlink rejection, and realpath root checks before copyFile. | Add CI test ensuring symlinked brand files are skipped. | High |
| 86 | 82abee3511748191a4035285f38d285c | Legit issue | Correct | ShareOFT salt override allows squatting on deterministic token addresses — DeploymentBatcher.sol deployPhase1CoreWithSalt/finalizePhase1WithSalt now revert SaltOverrideDisabled for nonzero override. | Consider removing withSalt entrypoints in a cleanup release. | High |
| 87 | ef958e9515bc81918853c1964e645849 | Legit issue | Correct | Approve-only paymaster path enables gas sponsorship bypass — frontend/api/_handlers/_paymaster.ts approve-only branch now hard-fails with approve_only_not_allowed in validateInnerCalls(). | No action; keep approve_only_not_allowed regression tests. | High |
| 88 | 8934379e08f88191ac9e62f2ecea74ee | Legit issue | Correct | Spot-price fallback weakens oracle resistance for deployment pricing — marketFloor.getZoraReferenceV3Ticks retries shorter TWAP observe windows and throws; no slot0 spot fallback remains. | Keep TWAP-only invariant tests for pricing path. | High |
| 89 | 084520cd66648191a509747ecdfe3fce | Legit issue | Correct | Paymaster allowlist bypass via creator token parties — frontend/api/_handlers/_paymaster.ts resolveAllowlistAddresses() now returns only session address; creator token parties are not used for allowlist pass. | No action; keep allowlist resolution scoped to authenticated session address. | High |
| 90 | 1c5de7cd487881919dc45d57d8749faf | Unclear | Partial | Rate-limit bypass via spoofed IP headers in Debank token list — _tokenList.ts rate limits by getTrustedClientIp; _shared.ts avoids x-forwarded-for in prod, but x-real-ip/provider trust leaves deployment-dependent bypass risk. | Document trusted proxy headers and enforce/validate IP provenance at the edge. | Medium |
| 91 | 12e53a43dee881918a9b611d05b74b40 | Legit issue | Correct | Vite dev server now binds to all interfaces by default — vite.config.ts defaults VITE_DEV_SERVER_HOST to 127.0.0.1; network bind requires explicit opt-in true/0.0.0.0. | Keep secure default documented in env template. | High |
| 92 | d4cd49c74af881918536e24562eba9c9 | Legit issue | Partial | Unfiltered LiquidityMigrated logs enable spoofed fee status — migrations.ts still uses topic-only eth_getLogs, but now enforces pool consistency, emitter token match, and proxy implementation allowlist checks. | Add factory/registry provenance checks or contract-address filtering to remove residual spoof surface. | Medium |