Security: swap pre-sign confirmation labels and SEC-D11 tests (#409) #929

Merged
PlasticDigits merged 1 commit from issue-409-swap-signing-confirmation-tests into main 2026-06-19 13:09:32 +00:00
PlasticDigits commented 2026-06-19 12:54:47 +00:00 (Migrated from gitlab.com)

Summary

Adds a labeled pre-sign swap summary (SwapPreSubmitSummary) on /swap and the Trade Market tab so traders see action, pair, pay/receive amounts, max spread, min return, and chain name before the wallet extension opens. Closes the SEC-D11 gap where no frontend test asserted these confirmation fields — phishing substitutions of pair or chain would now fail CI.

Tied to #409.

Acceptance checklist

Item Verification Result
Action label ("Swap") in confirmation panel cd frontend-dapp && npm run test:run -- src/pages/SwapPage.test.tsx -t "pre-sign confirmation" PASS
Offer token symbol and amount displayed Same test asserts swap-confirm-offer PASS
Return token symbol and estimated amount displayed Same test asserts swap-confirm-receive PASS
Max spread value in confirmation panel Same test asserts swap-confirm-max-spread (0.5%) PASS
Chain name in confirmation panel Same test asserts swap-confirm-chain (LocalTerra) PASS
Keplr wallet context where applicable SwapPage test sets walletType: 'keplr' PASS
All new tests pass in CI npm run test:run -- src/components/swap/__tests__/SwapPreSubmitSummary.test.tsx src/pages/SwapPage.test.tsx src/components/trade/__tests__/TradeMarketOrderPanel.submitSnapshot.test.tsx (27/27) PASS

Note: Full make test-frontend currently fails on an unrelated pre-existing cosmesPatch127.test.ts patch-version mismatch on main (@goblinhunt/cosmes@0.0.71-ghunt.22); not introduced by this MR.

Verification checklist (third parties)

  1. Pull branch issue-409-swap-signing-confirmation-tests.
  2. Run targeted tests:
    cd frontend-dapp && npm run test:run -- \
      src/components/swap/__tests__/SwapPreSubmitSummary.test.tsx \
      src/pages/SwapPage.test.tsx \
      src/components/trade/__tests__/TradeMarketOrderPanel.submitSnapshot.test.tsx
    
  3. Manual (optional): make dev → connect Keplr → enter swap amount → confirm card above Swap shows Action, Pair, You pay, You receive, Max spread, Min return, Chain.
  4. Docs: docs/frontend.md § Swap pre-sign summary, skills/AGENTS_FRONTEND_SWAP_SIGNING_CONFIRMATION.md.
## Summary Adds a labeled **pre-sign swap summary** (`SwapPreSubmitSummary`) on `/swap` and the Trade **Market** tab so traders see action, pair, pay/receive amounts, max spread, min return, and chain name before the wallet extension opens. Closes the SEC-D11 gap where no frontend test asserted these confirmation fields — phishing substitutions of pair or chain would now fail CI. Tied to #409. ## Acceptance checklist | Item | Verification | Result | |------|--------------|--------| | Action label ("Swap") in confirmation panel | `cd frontend-dapp && npm run test:run -- src/pages/SwapPage.test.tsx -t "pre-sign confirmation"` | PASS | | Offer token symbol and amount displayed | Same test asserts `swap-confirm-offer` | PASS | | Return token symbol and estimated amount displayed | Same test asserts `swap-confirm-receive` | PASS | | Max spread value in confirmation panel | Same test asserts `swap-confirm-max-spread` (0.5%) | PASS | | Chain name in confirmation panel | Same test asserts `swap-confirm-chain` (LocalTerra) | PASS | | Keplr wallet context where applicable | SwapPage test sets `walletType: 'keplr'` | PASS | | All new tests pass in CI | `npm run test:run -- src/components/swap/__tests__/SwapPreSubmitSummary.test.tsx src/pages/SwapPage.test.tsx src/components/trade/__tests__/TradeMarketOrderPanel.submitSnapshot.test.tsx` (27/27) | PASS | **Note:** Full `make test-frontend` currently fails on an unrelated pre-existing `cosmesPatch127.test.ts` patch-version mismatch on main (`@goblinhunt/cosmes@0.0.71-ghunt.22`); not introduced by this MR. ## Verification checklist (third parties) 1. Pull branch `issue-409-swap-signing-confirmation-tests`. 2. Run targeted tests: ```bash cd frontend-dapp && npm run test:run -- \ src/components/swap/__tests__/SwapPreSubmitSummary.test.tsx \ src/pages/SwapPage.test.tsx \ src/components/trade/__tests__/TradeMarketOrderPanel.submitSnapshot.test.tsx ``` 3. Manual (optional): `make dev` → connect Keplr → enter swap amount → confirm card above **Swap** shows Action, Pair, You pay, You receive, Max spread, Min return, Chain. 4. Docs: [`docs/frontend.md` § Swap pre-sign summary](docs/frontend.md#swap-page-pre-sign-summary), [`skills/AGENTS_FRONTEND_SWAP_SIGNING_CONFIRMATION.md`](skills/AGENTS_FRONTEND_SWAP_SIGNING_CONFIRMATION.md).
PlasticDigits commented 2026-06-19 12:58:57 +00:00 (Migrated from gitlab.com)

Security review — MR !929

Commit reviewed: f08635d0ab94e6130a7696e740fc53b6e592c008
Scope: SwapPreSubmitSummary component, SwapPage / TradeMarketOrderPanel wiring, SEC-D11 tests, docs/skills updates.

Outcome

FINDINGS: 0 medium+

Security review: no medium+ findings on this diff.

Analysis summary

Reviewed added/modified frontend paths for injection, authz bypass, confirmation-vs-submit mismatches, XSS, and trust-boundary regressions.

Area Result
XSS / HTML injection SwapPreSubmitSummary renders all dynamic values as React text nodes ({value}); no dangerouslySetInnerHTML. Token symbols flow through existing getTokenDisplaySymbol (same surface as pre-MR swap UI).
Confirmation vs on-chain submit Pay/receive/min-return/slippage come from useSubmitAlignedSimQuote (simData, minReceived). Submit remains gated by simQuoteStale / isSubmitReady and assertSubmitQuotePayRawAligned in mutation paths (#356). Brief debounce windows may show a stale quote while submit is disabled — not exploitable.
Chain / action labels chainFullLabel from build-time getNetworkBadgeCopy(); actionLabel hardcoded (Swap / Market swap). Not attacker-controlled.
Indexer trust Compromised-indexer quote risk is pre-existing and documented; this MR adds labeled pre-sign fields (anti-phishing), not a new quote trust path.
Secrets / SSRF / deps No new dependencies, logging of secrets, or outbound URL construction in the diff.

Inline threads

None (no medium+ findings).

Prior review

No prior security-review notes on this MR; nothing to re-report.

## Security review — MR !929 **Commit reviewed:** `f08635d0ab94e6130a7696e740fc53b6e592c008` **Scope:** `SwapPreSubmitSummary` component, SwapPage / TradeMarketOrderPanel wiring, SEC-D11 tests, docs/skills updates. ### Outcome **FINDINGS: 0** medium+ Security review: **no medium+ findings** on this diff. ### Analysis summary Reviewed added/modified frontend paths for injection, authz bypass, confirmation-vs-submit mismatches, XSS, and trust-boundary regressions. | Area | Result | |------|--------| | **XSS / HTML injection** | `SwapPreSubmitSummary` renders all dynamic values as React text nodes (`{value}`); no `dangerouslySetInnerHTML`. Token symbols flow through existing `getTokenDisplaySymbol` (same surface as pre-MR swap UI). | | **Confirmation vs on-chain submit** | Pay/receive/min-return/slippage come from `useSubmitAlignedSimQuote` (`simData`, `minReceived`). Submit remains gated by `simQuoteStale` / `isSubmitReady` and `assertSubmitQuotePayRawAligned` in mutation paths (#356). Brief debounce windows may show a stale quote while submit is disabled — not exploitable. | | **Chain / action labels** | `chainFullLabel` from build-time `getNetworkBadgeCopy()`; `actionLabel` hardcoded (`Swap` / `Market swap`). Not attacker-controlled. | | **Indexer trust** | Compromised-indexer quote risk is pre-existing and documented; this MR adds labeled pre-sign fields (anti-phishing), not a new quote trust path. | | **Secrets / SSRF / deps** | No new dependencies, logging of secrets, or outbound URL construction in the diff. | ### Inline threads None (no medium+ findings). ### Prior review No prior security-review notes on this MR; nothing to re-report.
PlasticDigits (Migrated from gitlab.com) merged commit 049471ed2a into main 2026-06-19 13:09:33 +00:00
PlasticDigits commented 2026-06-19 13:09:34 +00:00 (Migrated from gitlab.com)

mentioned in commit 049471ed2a

mentioned in commit 049471ed2a0714c4aff5b812b4670bcc0499fc75
Sign in to join this conversation.
No reviewers
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!929
No description provided.