Skip to content

Add Content Security Policy and fix silent error swallowing in subscribe calls#3387

Merged
olgahaha merged 5 commits intomainfrom
copilot/add-content-security-policy-error-handling
Apr 16, 2026
Merged

Add Content Security Policy and fix silent error swallowing in subscribe calls#3387
olgahaha merged 5 commits intomainfrom
copilot/add-content-security-policy-error-handling

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 18, 2026

The app had no CSP restricting WebView content sources, and 14+ .subscribe() calls had no error handler, silently discarding failures in security-sensitive operations (wallet transfers, auth, signup).

Changes

src/index.html — Add Content Security Policy

Adds a CSP meta tag with explicit allowlists:

<meta
  http-equiv="Content-Security-Policy"
  content="default-src 'self';
           frame-src https://*.numbersprotocol.io https://*.bubble.io;
           connect-src https://*.numbersprotocol.io;
           script-src 'self';
           style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
           font-src 'self' https://fonts.gstatic.com;
           img-src 'self' data: blob:;
           media-src 'self' blob:;
           object-src 'none';"
/>
  • frame-src covers the Bubble.io iframes used throughout the app
  • img-src/media-src include blob: for camera capture output
  • object-src 'none' blocks all plugin-based content

Subscribe error handlers — 5 files, 14 locations

Adds error callbacks to all empty .subscribe() calls in:

  • wallets/transfer/transfer.page.ts — transfer operations + route paramMap
  • wallets/wallets.page.ts — iframe events, reload, clipboard
  • signup/signup.page.ts — translation init, form submit
  • contacts/contacts.page.ts — delete action
  • data-policy/data-policy.page.ts — iframe events
.subscribe({
  // eslint-disable-next-line no-console
  error: (err: unknown) => console.error(err),
});
Original prompt

This section details on the original issue you should resolve

<issue_title>[Security][Medium] Missing Content Security Policy and excessive empty-subscribe error swallowing</issue_title>
<issue_description>## Summary

Two related defense-in-depth issues that weaken the app's ability to detect and prevent exploitation:

1. No Content Security Policy (CSP)

src/index.html contains no <meta http-equiv="Content-Security-Policy"> tag. No CSP configuration was found anywhere in the codebase. Without CSP, the WebView has no restrictions on:

  • Which domains can serve iframes, scripts, styles, or images
  • Inline script execution
  • eval() usage

File: src/index.html — no CSP meta tag present in the <head> section.

2. Empty .subscribe() calls swallow errors silently

15+ locations call .subscribe() with no error handler, meaning any Observable errors are silently discarded. This makes it difficult to detect and diagnose security-relevant failures (e.g., failed auth token refresh, network errors during sensitive operations).

Key affected files:

  • src/app/features/wallets/transfer/transfer.page.ts (lines 87, 101, 159, 183) — wallet transfer operations
  • src/app/features/wallets/wallets.page.ts (lines 93, 106, 116, 126, 136) — wallet page operations
  • src/app/features/signup/signup.page.ts (lines 73, 240) — signup flow
  • src/app/features/contacts/contacts.page.ts:49
  • src/app/features/data-policy/data-policy.page.ts:47

Impact

  • CSP: Without CSP, if any XSS vector is exploited (see related SafeResourceUrlPipe issue), there are no browser-level restrictions to limit the damage.
  • Error swallowing: Silent failures in wallet and auth operations could mask security incidents or data loss.

Suggested Fix

  1. Add a CSP meta tag to src/index.html restricting frame-src, script-src, and connect-src to known trusted domains.
  2. Add error handlers to all .subscribe() calls, at minimum logging errors. Consider using a global error handler or the tap({ error: ... }) operator.
<!-- Example CSP for index.html -->
<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; 
               frame-src https://*.numbersprotocol.io https://*.bubble.io; 
               connect-src https://*.numbersprotocol.io; 
               script-src 'self'; 
               style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;">

Generated by Health Monitor with Omni</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 Send tasks to Copilot coding agent from Slack and Teams to turn conversations into code. Copilot posts an update in your thread when it's finished.

Co-authored-by: numbers-official <181934381+numbers-official@users.noreply.github.com>
Copilot AI changed the title [WIP] [Security] Add Content Security Policy and improve error handling Add Content Security Policy and fix silent error swallowing in subscribe calls Mar 18, 2026
Copilot AI requested a review from numbers-official March 18, 2026 16:14
@olgahaha olgahaha marked this pull request as ready for review April 16, 2026 05:14
olgahaha and others added 3 commits April 16, 2026 13:47
The Content-Security-Policy was too restrictive for a Capacitor mobile
app. connect-src only allowed *.numbersprotocol.io, which would silently
block requests to bubble.io APIs (actions, orders, NUM price), GoPro
local server (10.5.5.9), and AppsFlyer analytics at runtime.

CSP for Capacitor apps requires a dedicated effort with comprehensive
domain inventory and full QA coverage across all features.
@olgahaha olgahaha merged commit 917fafd into main Apr 16, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security][Medium] Missing Content Security Policy and excessive empty-subscribe error swallowing

3 participants