Frontend trust boundaries, build guards, and expert mode (#376) #378

Closed
opened 2026-06-13 07:56:26 +00:00 by PlasticDigits · 38 comments
PlasticDigits commented 2026-06-13 07:56:26 +00:00 (Migrated from gitlab.com)

Parent

Remediation bundle for #376 — Full security report.

Covers approved findings: H-04, H-05, M-07, M-08, M-09, M-10, M-15 (audit ID M-14).

Current codebase

  • Indexer route trust (H-04): frontend-dapp/src/pages/SwapPage.tsx and src/services/indexer/routeOperations.ts trust indexer router_operations after parsing; swapRoutePreflight.ts validates hop pairs via factory LCD getPair(). Route summary row exists (data-testid="swap-route-summary"). VITE_INDEXER_URL defaults to http://127.0.0.1:3001 in src/services/indexer/client.ts. No dedicated off-chain trust documentation.
  • Dev mnemonic guard (H-05): frontend-dapp/vite.config.ts L51–59 blocks VITE_DEV_MNEMONIC only for build && mode === 'production'. Staging/non-prod builds can still inline mnemonic.
  • CSP (M-07): frontend-dapp/index.html L18–19 uses script-src 'self' 'unsafe-inline' and broad connect-src … https: wss:. render.yaml mirrors policy.
  • Build-time addresses (M-08): frontend-dapp/src/utils/constants.ts reads VITE_FACTORY_ADDRESS, VITE_ROUTER_ADDRESS with public-node fallbacks. No startup LCD verification. ProtocolPage.tsx does not display factory/router addresses.
  • Token display phishing (M-09): useTokenDisplayInfo.ts uses indexer logo_url; TokenLogo.tsx renders raw <img src> with no host allowlist. docs/CG_CMC_COMPLIANCE.md covers manual CMC listing only.
  • WalletConnect ID (M-10): frontend-dapp/src/services/terraclassic/wallet.ts L37 falls back to shared default project ID when VITE_WC_PROJECT_ID unset.
  • Expert mode (M-15): swapRouteSlippage.ts blocks >30% route slippage unless expert mode. ExpertModeModal.tsx uses click-to-enable disclaimer; no typed confirmation. 50% slippage tolerance allowed in settings for expert users.

Why needed

Off-chain trust boundaries (indexer, build env, token metadata) can mislead users into signing degraded or malicious transactions. Build misconfiguration can leak dev keys. Approved fixes harden build guards, document indexer trust, tighten CSP/WC, and add expert-mode friction without on-chain hop cross-checks.

Constraints / guardrails

  • H-04: Do not implement on-chain hop graph cross-check or client-side BFS fallback (RPC/LCD rate limits). Do document risks, pin indexer URL + TLS in deploy docs, ensure human-readable hop summary at confirmation.
  • M-08: Show factory/router addresses only on existing settings/audit surfaces (e.g. /protocol) — not in swap confirmation UI (cognitive overload).
  • M-09: Do not add more token detail to retail UI. Implement logo host allowlist; document that indexer listing includes human review.
  • M-15: Keep 30% standard / 50% expert slippage thresholds. Typed confirmation required for expert mode enable only.

Relevant files

Area Paths
Swap / routes frontend-dapp/src/pages/SwapPage.tsx, src/services/indexer/routeOperations.ts, src/services/indexer/client.ts, src/services/terraclassic/swapRoutePreflight.ts, src/utils/swapRouteDisplay.ts
Build guards frontend-dapp/vite.config.ts, src/services/terraclassic/devWallet.ts, src/viteConfig.build.test.ts
Wallet / constants src/services/terraclassic/wallet.ts, src/utils/constants.ts
Token UI src/hooks/useTokenDisplayInfo.ts, src/components/ui/TokenLogo.tsx
Expert mode src/components/swap/ExpertModeModal.tsx, src/utils/swapRouteSlippage.ts, src/utils/expertMode.ts
CSP frontend-dapp/index.html, render.yaml
Protocol / audit UI src/pages/ProtocolPage.tsx
Docs docs/frontend.md, docs/security-model.md, docs/operator-secrets.md
  1. H-04: Add docs/security-model.md § off-chain trust (MITM, compromised indexer, malicious but valid pools). Deploy checklist: HTTPS-only VITE_INDEXER_URL, TLS cert pinning guidance. Polish hop summary in swap confirmation (existing route row + pre-submit breakdown).
  2. H-05: Fail vite build when VITE_DEV_MNEMONIC is set unless mode === 'development' or explicit VITE_ALLOW_DEV_MNEMONIC=local-only. Extend viteConfig.build.test.ts.
  3. M-07: Move bootstrap scripts to bundled modules or nonce-based CSP; narrow connect-src to env-specific LCD/RPC/indexer hosts.
  4. M-08: Pin per-network addresses in deploy; optional startup factory LCD sanity check; display router/factory on ProtocolPage (audit/settings only).
  5. M-09: Logo host allowlist in TokenLogo / logo URI resolver; ops doc confirming indexer token listing requires human review.
  6. M-10: Fail production build when VITE_WC_PROJECT_ID missing (mirror H-05 pattern in vite.config.ts).
  7. M-15: Add type-to-confirm phrase in ExpertModeModal before enabling expert mode; unit/E2E tests.

Acceptance criteria

  • Off-chain indexer trust documented; deploy checklist requires HTTPS indexer URL.
  • vite build fails on dev mnemonic outside development mode; fails on missing WC project ID in production.
  • CSP tightened (no broad https: connect-src in production); documented dev exception.
  • Factory/router visible on protocol/audit page only; startup verification optional but documented.
  • Logo host allowlist enforced; listing human-review process documented.
  • Expert mode requires typed confirmation; 30%/50% thresholds unchanged.

Test plan

  • make test-frontend / make lint-frontend
  • frontend-dapp: viteConfig.build.test.ts (staging mnemonic rejection, WC ID guard)
  • Unit tests for TokenLogo allowlist, ExpertModeModal typed confirm
  • make verify-issue-295 or targeted Playwright if swap confirmation UI changes
  • Manual: make dev → verify route summary, protocol page addresses, expert mode flow

Attack / abuse test plan

  • Attempt vite build --mode staging with VITE_DEV_MNEMONIC set — must fail.
  • Attempt production build without VITE_WC_PROJECT_ID — must fail.
  • Token logo from https://evil.example/logo.png — must fall back to blockie.
  • Expert mode: verify cannot enable without typing confirmation phrase.
  • Not in scope: simulated malicious indexer BFS comparison (explicitly rejected).

Verification criteria

  • All frontend unit tests pass.
  • Production build artifacts contain no dev mnemonic and no default WC project ID.
  • Docs updated and linked from parent #376 remediation tracking.
## Parent Remediation bundle for [#376 — Full security report](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/376). Covers approved findings: **H-04**, **H-05**, **M-07**, **M-08**, **M-09**, **M-10**, **M-15** (audit ID M-14). ## Current codebase - **Indexer route trust (H-04):** `frontend-dapp/src/pages/SwapPage.tsx` and `src/services/indexer/routeOperations.ts` trust indexer `router_operations` after parsing; `swapRoutePreflight.ts` validates hop pairs via factory LCD `getPair()`. Route summary row exists (`data-testid="swap-route-summary"`). `VITE_INDEXER_URL` defaults to `http://127.0.0.1:3001` in `src/services/indexer/client.ts`. No dedicated off-chain trust documentation. - **Dev mnemonic guard (H-05):** `frontend-dapp/vite.config.ts` L51–59 blocks `VITE_DEV_MNEMONIC` only for `build && mode === 'production'`. Staging/non-prod builds can still inline mnemonic. - **CSP (M-07):** `frontend-dapp/index.html` L18–19 uses `script-src 'self' 'unsafe-inline'` and broad `connect-src … https: wss:`. `render.yaml` mirrors policy. - **Build-time addresses (M-08):** `frontend-dapp/src/utils/constants.ts` reads `VITE_FACTORY_ADDRESS`, `VITE_ROUTER_ADDRESS` with public-node fallbacks. No startup LCD verification. `ProtocolPage.tsx` does not display factory/router addresses. - **Token display phishing (M-09):** `useTokenDisplayInfo.ts` uses indexer `logo_url`; `TokenLogo.tsx` renders raw `<img src>` with no host allowlist. `docs/CG_CMC_COMPLIANCE.md` covers manual CMC listing only. - **WalletConnect ID (M-10):** `frontend-dapp/src/services/terraclassic/wallet.ts` L37 falls back to shared default project ID when `VITE_WC_PROJECT_ID` unset. - **Expert mode (M-15):** `swapRouteSlippage.ts` blocks >30% route slippage unless expert mode. `ExpertModeModal.tsx` uses click-to-enable disclaimer; no typed confirmation. 50% slippage tolerance allowed in settings for expert users. ## Why needed Off-chain trust boundaries (indexer, build env, token metadata) can mislead users into signing degraded or malicious transactions. Build misconfiguration can leak dev keys. Approved fixes harden build guards, document indexer trust, tighten CSP/WC, and add expert-mode friction without on-chain hop cross-checks. ## Constraints / guardrails - **H-04:** Do **not** implement on-chain hop graph cross-check or client-side BFS fallback (RPC/LCD rate limits). **Do** document risks, pin indexer URL + TLS in deploy docs, ensure human-readable hop summary at confirmation. - **M-08:** Show factory/router addresses **only** on existing settings/audit surfaces (e.g. `/protocol`) — **not** in swap confirmation UI (cognitive overload). - **M-09:** Do **not** add more token detail to retail UI. Implement logo host allowlist; document that indexer listing includes human review. - **M-15:** Keep 30% standard / 50% expert slippage thresholds. Typed confirmation required for **expert mode enable only**. ## Relevant files | Area | Paths | |------|-------| | Swap / routes | `frontend-dapp/src/pages/SwapPage.tsx`, `src/services/indexer/routeOperations.ts`, `src/services/indexer/client.ts`, `src/services/terraclassic/swapRoutePreflight.ts`, `src/utils/swapRouteDisplay.ts` | | Build guards | `frontend-dapp/vite.config.ts`, `src/services/terraclassic/devWallet.ts`, `src/viteConfig.build.test.ts` | | Wallet / constants | `src/services/terraclassic/wallet.ts`, `src/utils/constants.ts` | | Token UI | `src/hooks/useTokenDisplayInfo.ts`, `src/components/ui/TokenLogo.tsx` | | Expert mode | `src/components/swap/ExpertModeModal.tsx`, `src/utils/swapRouteSlippage.ts`, `src/utils/expertMode.ts` | | CSP | `frontend-dapp/index.html`, `render.yaml` | | Protocol / audit UI | `src/pages/ProtocolPage.tsx` | | Docs | `docs/frontend.md`, `docs/security-model.md`, `docs/operator-secrets.md` | ## Recommended direction 1. **H-04:** Add `docs/security-model.md` § off-chain trust (MITM, compromised indexer, malicious but valid pools). Deploy checklist: HTTPS-only `VITE_INDEXER_URL`, TLS cert pinning guidance. Polish hop summary in swap confirmation (existing route row + pre-submit breakdown). 2. **H-05:** Fail `vite build` when `VITE_DEV_MNEMONIC` is set unless `mode === 'development'` or explicit `VITE_ALLOW_DEV_MNEMONIC=local-only`. Extend `viteConfig.build.test.ts`. 3. **M-07:** Move bootstrap scripts to bundled modules or nonce-based CSP; narrow `connect-src` to env-specific LCD/RPC/indexer hosts. 4. **M-08:** Pin per-network addresses in deploy; optional startup factory LCD sanity check; display router/factory on `ProtocolPage` (audit/settings only). 5. **M-09:** Logo host allowlist in `TokenLogo` / logo URI resolver; ops doc confirming indexer token listing requires human review. 6. **M-10:** Fail production build when `VITE_WC_PROJECT_ID` missing (mirror H-05 pattern in `vite.config.ts`). 7. **M-15:** Add type-to-confirm phrase in `ExpertModeModal` before enabling expert mode; unit/E2E tests. ## Acceptance criteria - [ ] Off-chain indexer trust documented; deploy checklist requires HTTPS indexer URL. - [ ] `vite build` fails on dev mnemonic outside development mode; fails on missing WC project ID in production. - [ ] CSP tightened (no broad `https:` connect-src in production); documented dev exception. - [ ] Factory/router visible on protocol/audit page only; startup verification optional but documented. - [ ] Logo host allowlist enforced; listing human-review process documented. - [ ] Expert mode requires typed confirmation; 30%/50% thresholds unchanged. ## Test plan - `make test-frontend` / `make lint-frontend` - `frontend-dapp`: `viteConfig.build.test.ts` (staging mnemonic rejection, WC ID guard) - Unit tests for `TokenLogo` allowlist, `ExpertModeModal` typed confirm - `make verify-issue-295` or targeted Playwright if swap confirmation UI changes - Manual: `make dev` → verify route summary, protocol page addresses, expert mode flow ## Attack / abuse test plan - Attempt `vite build --mode staging` with `VITE_DEV_MNEMONIC` set — must fail. - Attempt production build without `VITE_WC_PROJECT_ID` — must fail. - Token logo from `https://evil.example/logo.png` — must fall back to blockie. - Expert mode: verify cannot enable without typing confirmation phrase. - **Not in scope:** simulated malicious indexer BFS comparison (explicitly rejected). ## Verification criteria - All frontend unit tests pass. - Production build artifacts contain no dev mnemonic and no default WC project ID. - Docs updated and linked from parent #376 remediation tracking.
PlasticDigits commented 2026-06-13 07:56:46 +00:00 (Migrated from gitlab.com)

mentioned in issue #376

mentioned in issue #376
PlasticDigits commented 2026-06-13 09:45:19 +00:00 (Migrated from gitlab.com)

mentioned in commit b45ac0aea6

mentioned in commit b45ac0aea60c370b1097a42a4677a9c14bbb0dbb
PlasticDigits commented 2026-06-13 09:45:34 +00:00 (Migrated from gitlab.com)

mentioned in merge request !902

mentioned in merge request !902
ghost1 commented 2026-06-13 09:52:16 +00:00 (Migrated from gitlab.com)

mentioned in commit ec409fde96

mentioned in commit ec409fde96255489523f8772334d480cc3e56b11
PlasticDigits commented 2026-06-13 09:59:47 +00:00 (Migrated from gitlab.com)

mentioned in commit 0607c11a78

mentioned in commit 0607c11a780c762eba1a304a45d8d5616a0a9b72
PlasticDigits commented 2026-06-13 14:02:39 +00:00 (Migrated from gitlab.com)

mentioned in commit 525056e0ff

mentioned in commit 525056e0ffb110a9f79bd799f8063007fbfb9c8e
PlasticDigits commented 2026-06-13 14:02:50 +00:00 (Migrated from gitlab.com)

mentioned in merge request !906

mentioned in merge request !906
PlasticDigits commented 2026-06-13 14:17:21 +00:00 (Migrated from gitlab.com)

mentioned in commit 4e06ee3688

mentioned in commit 4e06ee36886598e8b9bfd74f498c1dd4c359272d
PlasticDigits commented 2026-06-14 02:54:46 +00:00 (Migrated from gitlab.com)

mentioned in commit 171aa60b58

mentioned in commit 171aa60b58f5f033b9f2f17a9d59689462686076
PlasticDigits commented 2026-06-14 03:10:50 +00:00 (Migrated from gitlab.com)

mentioned in commit eaecea2462

mentioned in commit eaecea24627cac200be7dd72ae8197b760d38e04
PlasticDigits commented 2026-06-14 03:11:03 +00:00 (Migrated from gitlab.com)

mentioned in merge request !909

mentioned in merge request !909
PlasticDigits commented 2026-06-14 06:56:16 +00:00 (Migrated from gitlab.com)

mentioned in commit dd654b11f5

mentioned in commit dd654b11f5c8209b4807562c2e34a2c9436e3ccd
PlasticDigits commented 2026-06-14 06:57:51 +00:00 (Migrated from gitlab.com)

mentioned in commit 01b1b664e2

mentioned in commit 01b1b664e241ea36be95f003a5f08ddb90db69e7
PlasticDigits commented 2026-06-14 07:08:55 +00:00 (Migrated from gitlab.com)

mentioned in commit d7aa33e895

mentioned in commit d7aa33e895a916a5a84af4b95421abf42c4488ea
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-14 07:08:55 +00:00
PlasticDigits commented 2026-06-14 12:06:12 +00:00 (Migrated from gitlab.com)

mentioned in commit 8acee13f41

mentioned in commit 8acee13f41cf7e979d4afa57951ef0ca6573d04c
PlasticDigits commented 2026-06-14 12:06:15 +00:00 (Migrated from gitlab.com)

mentioned in merge request !908

mentioned in merge request !908
PlasticDigits commented 2026-06-25 14:13:01 +00:00 (Migrated from gitlab.com)

mentioned in issue #422

mentioned in issue #422
Brouie commented 2026-06-28 22:40:29 +00:00 (Migrated from gitlab.com)

mentioned in merge request !951

mentioned in merge request !951
Brouie commented 2026-06-28 22:41:06 +00:00 (Migrated from gitlab.com)

mentioned in issue #337

mentioned in issue #337
Brouie commented 2026-06-29 07:52:30 +00:00 (Migrated from gitlab.com)

mentioned in merge request !953

mentioned in merge request !953
PlasticDigits commented 2026-08-17 03:45:38 +00:00 (Migrated from gitlab.com)

mentioned in issue #541

mentioned in issue #541
PlasticDigits commented 2026-08-17 03:45:49 +00:00 (Migrated from gitlab.com)

mentioned in issue #542

mentioned in issue #542
PlasticDigits commented 2026-08-17 03:45:50 +00:00 (Migrated from gitlab.com)

marked as related to #542

marked as related to #542
PlasticDigits commented 2026-08-17 10:35:57 +00:00 (Migrated from gitlab.com)

mentioned in issue #550

mentioned in issue #550
PlasticDigits commented 2026-08-17 10:35:58 +00:00 (Migrated from gitlab.com)

marked as related to #550

marked as related to #550
PlasticDigits commented 2026-08-18 00:20:44 +00:00 (Migrated from gitlab.com)

mentioned in issue #554

mentioned in issue #554
PlasticDigits commented 2026-08-18 15:21:51 +00:00 (Migrated from gitlab.com)

mentioned in issue PlasticDigits2/ustr-cmm#17

mentioned in issue PlasticDigits2/ustr-cmm#17
PlasticDigits commented 2026-08-18 15:22:41 +00:00 (Migrated from gitlab.com)

mentioned in issue #566

mentioned in issue #566
PlasticDigits commented 2026-08-19 01:02:31 +00:00 (Migrated from gitlab.com)

mentioned in issue #569

mentioned in issue #569
PlasticDigits commented 2026-08-19 01:03:03 +00:00 (Migrated from gitlab.com)

mentioned in issue #570

mentioned in issue #570
PlasticDigits commented 2026-08-26 01:10:54 +00:00 (Migrated from gitlab.com)

mentioned in issue #652

mentioned in issue #652
PlasticDigits commented 2026-08-26 03:07:39 +00:00 (Migrated from gitlab.com)

mentioned in issue #656

mentioned in issue #656
PlasticDigits commented 2026-08-28 05:28:47 +00:00 (Migrated from gitlab.com)

mentioned in issue #693

mentioned in issue #693
PlasticDigits commented 2026-08-28 09:24:20 +00:00 (Migrated from gitlab.com)

mentioned in issue #695

mentioned in issue #695
PlasticDigits commented 2026-08-28 09:24:21 +00:00 (Migrated from gitlab.com)

marked as related to #695

marked as related to #695
PlasticDigits commented 2026-08-28 09:39:05 +00:00 (Migrated from gitlab.com)

mentioned in merge request !1192

mentioned in merge request !1192
PlasticDigits commented 2026-08-30 02:48:10 +00:00 (Migrated from gitlab.com)

mentioned in issue #706

mentioned in issue #706
PlasticDigits commented 2026-08-31 16:08:49 +00:00 (Migrated from gitlab.com)

mentioned in issue #715

mentioned in issue #715
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic#378
No description provided.