Pre-launch: prod build ships source maps (vite.config sourcemap: true) #117

Closed
opened 2026-04-26 05:48:36 +00:00 by Brouie · 13 comments
Brouie commented 2026-04-26 05:48:36 +00:00 (Migrated from gitlab.com)

Found during DEX security checklist gap-fill on Sunday 2026-04-26.

Repro

frontend-dapp/vite.config.ts L70:

build: {
  outDir: 'dist',
  sourcemap: true,
  ...
}

sourcemap: true is unconditional - no env split, no mode === 'production' check. Every npm run build writes .js.map files alongside the bundle output. If the prod hosting serves /dist as-is (typical for a static frontend), the deployed site exposes the full un-minified source via source maps.

Why it matters pre-launch

Source maps don't expose secrets in this codebase - the define: { 'process.env': '{}' } at L64 wipes them at build time. But the maps still:

  • Defeat minification (every internal helper, contract addr, route solver path, private API surface trivially readable)
  • Make targeted attacks easier (e.g. tracing a wallet drain attempt through actual code paths instead of mangled IDs)
  • Leak organisation/team naming conventions visible in dev-only debug helpers
  • Enlarge the deployed payload size noticeably

This is hygiene that the rest of the org already practices:

  • cl8y-bridge-monorepo/packages/frontend/vite.config.ts L71: sourcemap: false (mainnet live)
  • yieldomega/frontend/vite.config.ts: no sourcemap set (Vite default for prod = false)

DEX is the outlier.

Severity

LOW-MEDIUM. Not a vulnerability on its own. Worth fixing pre-mainnet to match the rest of the ecosystem.

Fix options

Option A (simple, matches bridge):

build: {
  outDir: 'dist',
  sourcemap: false,
  ...
}

Option B (keep maps for staging/dev only):

build: {
  outDir: 'dist',
  sourcemap: process.env.NODE_ENV !== 'production',
  ...
}

Option C (hidden source maps - preserve for crash reporting tools, not served publicly):

build: {
  outDir: 'dist',
  sourcemap: 'hidden',
  ...
}

Option C is the strongest if the team uses Sentry / equivalent crash reporting — maps are emitted but not referenced by the bundled JS, so the browser doesn't auto-fetch them.

Acceptance

  • vite.config.ts updated per chosen option
  • npm run build smoke test: confirm /dist no longer contains *.js.map files (Option A/B prod) or that the bundle .js files have no //# sourceMappingURL= trailer (Option C)
  • DEX security checklist row 1.20 (source map leakage) updated to OK in cl8y-ecosystem-qa specs/DEX-Security-Checklist-DRAFT.md

cc @PlasticDigits

Found during DEX security checklist gap-fill on Sunday 2026-04-26. ## Repro frontend-dapp/vite.config.ts L70: ``` build: { outDir: 'dist', sourcemap: true, ... } ``` `sourcemap: true` is unconditional - no env split, no `mode === 'production'` check. Every `npm run build` writes .js.map files alongside the bundle output. If the prod hosting serves /dist as-is (typical for a static frontend), the deployed site exposes the full un-minified source via source maps. ## Why it matters pre-launch Source maps don't expose secrets in this codebase - the `define: { 'process.env': '{}' }` at L64 wipes them at build time. But the maps still: - Defeat minification (every internal helper, contract addr, route solver path, private API surface trivially readable) - Make targeted attacks easier (e.g. tracing a wallet drain attempt through actual code paths instead of mangled IDs) - Leak organisation/team naming conventions visible in dev-only debug helpers - Enlarge the deployed payload size noticeably This is hygiene that the rest of the org already practices: - cl8y-bridge-monorepo/packages/frontend/vite.config.ts L71: `sourcemap: false` (mainnet live) - yieldomega/frontend/vite.config.ts: no `sourcemap` set (Vite default for prod = false) DEX is the outlier. ## Severity LOW-MEDIUM. Not a vulnerability on its own. Worth fixing pre-mainnet to match the rest of the ecosystem. ## Fix options Option A (simple, matches bridge): ``` build: { outDir: 'dist', sourcemap: false, ... } ``` Option B (keep maps for staging/dev only): ``` build: { outDir: 'dist', sourcemap: process.env.NODE_ENV !== 'production', ... } ``` Option C (hidden source maps - preserve for crash reporting tools, not served publicly): ``` build: { outDir: 'dist', sourcemap: 'hidden', ... } ``` Option C is the strongest if the team uses Sentry / equivalent crash reporting — maps are emitted but not referenced by the bundled JS, so the browser doesn't auto-fetch them. ## Acceptance - [ ] vite.config.ts updated per chosen option - [ ] `npm run build` smoke test: confirm /dist no longer contains \*.js.map files (Option A/B prod) or that the bundle .js files have no `//# sourceMappingURL=` trailer (Option C) - [ ] DEX security checklist row 1.20 (source map leakage) updated to OK in cl8y-ecosystem-qa specs/DEX-Security-Checklist-DRAFT.md cc @PlasticDigits
Brouie commented 2026-04-26 05:49:31 +00:00 (Migrated from gitlab.com)

mentioned in commit cl8y-ecosystem-qa@98dddc8a8a762d6c4da82d826efd3392239b000d

mentioned in commit cl8y-ecosystem-qa@98dddc8a8a762d6c4da82d826efd3392239b000d
Brouie commented 2026-04-26 06:02:59 +00:00 (Migrated from gitlab.com)

mentioned in issue #118

mentioned in issue #118
PlasticDigits commented 2026-04-27 02:54:07 +00:00 (Migrated from gitlab.com)

mentioned in commit 0a86ba31ea

mentioned in commit 0a86ba31eadfa3771d4928f0cb991be65f7e906b
PlasticDigits commented 2026-04-27 02:54:25 +00:00 (Migrated from gitlab.com)

Implemented production-only Vite source maps (Option B via `mode`): default `npm run build` / `vite build` (`production`) sets `build.sourcemap: false`; non-production modes (e.g. `vite build --mode staging`) still emit `*.js.map` for staging diagnostics.

Merged to `main`: 0a86ba3 — docs + new agent playbook `skills/AGENTS_FRONTEND_PRODUCTION_BUILD.md`, cross-links from `skills/AGENTS_TERRACLASSIC_GAS.md` and `docs/frontend.md` (anchor `#vite-production-sourcemaps`). Vitest guard: `frontend-dapp/src/viteConfig.build.test.ts` (`@vitest-environment node` + `loadConfigFromFile`). Also fixed missing `AssetInfo` import on `PoolPage.tsx` so `tsc -b` passes for CI.

Out of repo: acceptance asked updating `cl8y-ecosystem-qa` `specs/DEX-Security-Checklist-DRAFT.md` row 1.20 — not in this repo; tracked in `docs/frontend.md` as a follow-up for whoever owns that checklist.

@brouie please verify when you have a moment.

Checklist for verification

  • On latest `main`, `cd frontend-dapp && npm ci && npm run build` completes; `find dist -name '*.js.map' | wc -l` is 0.
  • `rg sourceMappingURL dist -g '*.js'` returns no matches (prod bundle has no map trailer).
  • `npx vite build --mode staging` then `find dist -name '*.js.map' | wc -l` is > 0 (optional sanity for staging pipelines).
  • `npm run test:unit` includes `viteConfig.build.test.ts` and passes.
  • Skim `docs/frontend.md#vite-production-sourcemaps` and `skills/AGENTS_FRONTEND_PRODUCTION_BUILD.md` for wording.
  • Update ecosystem QA DEX security checklist row 1.20 to OK in the separate `cl8y-ecosystem-qa` repo if applicable.

Leaving the issue open per process.

Implemented **production-only** Vite source maps (Option B via \`mode\`): default \`npm run build\` / \`vite build\` (\`production\`) sets \`build.sourcemap: false\`; non-production modes (e.g. \`vite build --mode staging\`) still emit \`*.js.map\` for staging diagnostics. **Merged to \`main\`:** 0a86ba3 — docs + new agent playbook \`skills/AGENTS_FRONTEND_PRODUCTION_BUILD.md\`, cross-links from \`skills/AGENTS_TERRACLASSIC_GAS.md\` and \`docs/frontend.md\` (anchor \`#vite-production-sourcemaps\`). Vitest guard: \`frontend-dapp/src/viteConfig.build.test.ts\` (\`@vitest-environment node\` + \`loadConfigFromFile\`). Also fixed missing \`AssetInfo\` import on \`PoolPage.tsx\` so \`tsc -b\` passes for CI. **Out of repo:** acceptance asked updating \`cl8y-ecosystem-qa\` \`specs/DEX-Security-Checklist-DRAFT.md\` row **1.20** — not in this repo; tracked in \`docs/frontend.md\` as a follow-up for whoever owns that checklist. @brouie please verify when you have a moment. **Checklist for verification** - [ ] On latest \`main\`, \`cd frontend-dapp && npm ci && npm run build\` completes; \`find dist -name '*.js.map' | wc -l\` is **0**. - [ ] \`rg sourceMappingURL dist -g '*.js'\` returns **no** matches (prod bundle has no map trailer). - [ ] \`npx vite build --mode staging\` then \`find dist -name '*.js.map' | wc -l\` is **> 0** (optional sanity for staging pipelines). - [ ] \`npm run test:unit\` includes \`viteConfig.build.test.ts\` and passes. - [ ] Skim \`docs/frontend.md#vite-production-sourcemaps\` and \`skills/AGENTS_FRONTEND_PRODUCTION_BUILD.md\` for wording. - [ ] Update ecosystem QA DEX security checklist row **1.20** to OK in the separate \`cl8y-ecosystem-qa\` repo if applicable. Leaving the issue **open** per process.
Brouie commented 2026-05-01 13:04:59 +00:00 (Migrated from gitlab.com)

Verified on 0a86ba3. 6/6 PASS — closing.

Acceptance items

  • Item 1: npm run build → 0 .js.map files in dist/ — find dist -name '*.js.map' | wc -l returned 0 after clean npm ci && npm run build (built in 13.45s).
  • Item 2: No sourceMappingURL trailers in prod bundle — grep -rl 'sourceMappingURL' dist --include='*.js' returned 0 hits.
  • Item 3: --mode staging still emits maps — npx vite build --mode staging produced 33 .js.map files, build output explicitly shows map: 212.01 kB, map: 488.12 kB, etc. Mode-based logic works as designed.
  • Item 4: vitest includes viteConfig.build.test.ts and passes — 3 tests, all PASS in 96ms (covers prod sourcemap-off, non-prod sourcemap-on, and the GitLab #118 dev-mnemonic rejection test).
  • Item 5: docs/skill wording reads cleanly — docs/frontend.md#vite-production-sourcemaps anchor resolves with invariant table cross-linking #117 + ecosystem-qa row 1.20. skills/AGENTS_FRONTEND_PRODUCTION_BUILD.md has canonical refs table + 3 rules of thumb. Cross-link to AGENTS_TERRACLASSIC_GAS.md is good continuity.
  • Item 6: ecosystem-qa DEX security checklist row 1.20 → OK — pushed as 8ae453a on cl8y-ecosystem-qa main: specs(dex-security): mark row 1.20 source map leakage OK (DEX #117 verified). Row now reads NO — prod build | Fixed by #117 (commit 0a86ba3)... | OK.

Nice clean fix. cc @PlasticDigits

Verified on `0a86ba3`. 6/6 PASS — closing. ### Acceptance items - [x] **Item 1: `npm run build` → 0 `.js.map` files in `dist/`** — `find dist -name '*.js.map' | wc -l` returned 0 after clean `npm ci && npm run build` (built in 13.45s). - [x] **Item 2: No `sourceMappingURL` trailers in prod bundle** — `grep -rl 'sourceMappingURL' dist --include='*.js'` returned 0 hits. - [x] **Item 3: `--mode staging` still emits maps** — `npx vite build --mode staging` produced 33 `.js.map` files, build output explicitly shows `map: 212.01 kB`, `map: 488.12 kB`, etc. Mode-based logic works as designed. - [x] **Item 4: vitest includes `viteConfig.build.test.ts` and passes** — 3 tests, all PASS in 96ms (covers prod sourcemap-off, non-prod sourcemap-on, and the GitLab #118 dev-mnemonic rejection test). - [x] **Item 5: docs/skill wording reads cleanly** — `docs/frontend.md#vite-production-sourcemaps` anchor resolves with invariant table cross-linking #117 + ecosystem-qa row 1.20. `skills/AGENTS_FRONTEND_PRODUCTION_BUILD.md` has canonical refs table + 3 rules of thumb. Cross-link to `AGENTS_TERRACLASSIC_GAS.md` is good continuity. - [x] **Item 6: ecosystem-qa DEX security checklist row 1.20 → OK** — pushed as `8ae453a` on `cl8y-ecosystem-qa` main: `specs(dex-security): mark row 1.20 source map leakage OK (DEX #117 verified)`. Row now reads `NO — prod build | Fixed by #117 (commit 0a86ba3)... | OK`. Nice clean fix. cc @PlasticDigits
Brouie (Migrated from gitlab.com) closed this issue 2026-05-01 13:05:00 +00:00
Brouie commented 2026-05-25 07:59:29 +00:00 (Migrated from gitlab.com)

mentioned in issue #179

mentioned in issue #179
PlasticDigits commented 2026-06-07 12:14:16 +00:00 (Migrated from gitlab.com)

mentioned in issue #337

mentioned in issue #337
Brouie commented 2026-06-08 00:20:36 +00:00 (Migrated from gitlab.com)

mentioned in merge request !834

mentioned in merge request !834
ghost1 commented 2026-06-08 05:24:17 +00:00 (Migrated from gitlab.com)

mentioned in commit f875d5388a

mentioned in commit f875d5388a17e2467de35f7dc805ee7d77e6cea7
PlasticDigits commented 2026-06-08 08:43:13 +00:00 (Migrated from gitlab.com)

mentioned in commit 0e3afcaef3

mentioned in commit 0e3afcaef332b416792e99676407524ae3be2ef3
PlasticDigits commented 2026-06-08 13:42:30 +00:00 (Migrated from gitlab.com)

mentioned in commit 65876e17c7

mentioned in commit 65876e17c74fed89111b3928c9e2229ded5eb4de
Brouie commented 2026-06-29 07:52:30 +00:00 (Migrated from gitlab.com)

mentioned in merge request !953

mentioned in merge request !953
Brouie commented 2026-06-29 07:53:00 +00:00 (Migrated from gitlab.com)

mentioned in issue #421

mentioned in issue #421
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#117
No description provided.