security: pentest fixes — webhook sig, CORS, soul-health gate, asset headers #69

Merged
will.anderson merged 2 commits from fix/checkout-auth-reveal into dev 2026-05-11 04:57:05 +00:00
Owner

Summary

  • Stripe webhook forgery (critical): Add HMAC-SHA256 Stripe-Signature verification. Unauthenticated POST could forge payment_intent.succeeded events, increment the founding counter, and trigger Supabase account provisioning for arbitrary emails.
  • CORS on /api/supabase-config: Restrict to neurontechnologies.ai and localhost origins; cross-origin requests get 403.
  • /api/soul-health info leak: Require X-Internal: true header; returns 404 without it. Was publicly leaking soul service URL, network topology, and probe responses.
  • Asset/JS response headers: Add X-Frame-Options, Referrer-Policy, Permissions-Policy, and CSP to static_asset_headers_json and js_headers_json. Previously only HTML/API responses carried the full security header set.
  • __neuron_origin__ state key bug: share_card_page was reading the wrong state key (__neuron_origin__ instead of __origin__), causing empty base URLs in share card OG meta tags.
  • Switch to http_serve_v2/http_set_handler_v2 so the El handler receives request headers as a Map (prerequisite for all header-based checks).

Test plan

  • curl -H "Origin: https://evil.com" /api/supabase-config → 403
  • curl /api/soul-health (no X-Internal) → 404
  • curl -H "X-Internal: true" /api/soul-health → probe results
  • curl -X POST /api/webhooks/stripe (no sig) → 400
  • Asset responses include X-Frame-Options, Referrer-Policy, CSP headers
  • Share cards have correct base URL in OG tags
## Summary - **Stripe webhook forgery (critical)**: Add HMAC-SHA256 `Stripe-Signature` verification. Unauthenticated POST could forge `payment_intent.succeeded` events, increment the founding counter, and trigger Supabase account provisioning for arbitrary emails. - **CORS on `/api/supabase-config`**: Restrict to `neurontechnologies.ai` and `localhost` origins; cross-origin requests get 403. - **`/api/soul-health` info leak**: Require `X-Internal: true` header; returns 404 without it. Was publicly leaking soul service URL, network topology, and probe responses. - **Asset/JS response headers**: Add `X-Frame-Options`, `Referrer-Policy`, `Permissions-Policy`, and `CSP` to `static_asset_headers_json` and `js_headers_json`. Previously only HTML/API responses carried the full security header set. - **`__neuron_origin__` state key bug**: `share_card_page` was reading the wrong state key (`__neuron_origin__` instead of `__origin__`), causing empty base URLs in share card OG meta tags. - Switch to `http_serve_v2`/`http_set_handler_v2` so the El handler receives request headers as a `Map` (prerequisite for all header-based checks). ## Test plan - [ ] `curl -H "Origin: https://evil.com" /api/supabase-config` → 403 - [ ] `curl /api/soul-health` (no X-Internal) → 404 - [ ] `curl -H "X-Internal: true" /api/soul-health` → probe results - [ ] `curl -X POST /api/webhooks/stripe` (no sig) → 400 - [ ] Asset responses include X-Frame-Options, Referrer-Policy, CSP headers - [ ] Share cards have correct base URL in OG tags
will.anderson added 2 commits 2026-05-11 04:56:53 +00:00
- Switch to http_serve_v2/http_set_handler_v2 so request headers are available
  to El handler code (prerequisite for all header-based security checks)

- Stripe webhook (CVE-class): add HMAC-SHA256 signature verification against
  Stripe-Signature header using STRIPE_WEBHOOK_SECRET env var. Previously any
  unauthenticated POST could forge a payment_intent.succeeded event and
  increment the founding counter or trigger Supabase account provisioning for
  arbitrary emails.

- CORS on /api/supabase-config: restrict to neurontechnologies.ai and localhost
  origins only. Cross-origin requests now get 403.

- /api/soul-health: require X-Internal: true header; otherwise return 404.
  Endpoint was publicly accessible and leaked internal soul service URL,
  network topology, and raw probe responses.

- Static asset / JS headers: add X-Frame-Options, Referrer-Policy,
  Permissions-Policy, and Content-Security-Policy to static_asset_headers_json
  and js_headers_json. These were only present on HTML/API responses before.

- Fix state key bug: share_card_page read state_get("__neuron_origin__") but
  the key registered at startup is "__origin__", causing empty base URLs in
  share card og: meta tags.
seo: full audit fixes — meta, og, schema, canonical, sitemap, headings, alts
Dev — Build & local smoke test / build-smoke (pull_request) Successful in 1m57s
43e1245306
- Per-page title/description/canonical/OG tags: about, checkout (per-plan),
  terms, enterprise-terms, success all get unique SEO blocks
- Homepage title updated to em-dash form; meta description adds CTA
- og:site_name added to all pages
- noindex/nofollow on checkout, success, account pages
- Sitemap (/sitemap.xml) with all public pages; robots.txt updated with
  Sitemap directive and Disallow for private paths
- Schema: WebSite type added, Organization gains logo ImageObject, SoftwareApplication
  gains url field, billingIncrement corrected to billingPeriod (ISO 8601 P1M),
  sameAs gains x.com/neurontechai alongside GitHub
- marked.min.js given defer attribute (was render-blocking)
- page_head refactored into page_head_base + page_seo_block + page_open_seo
  for clean inner-page overrides without duplicating the CSS/script block
will.anderson merged commit e914704d86 into dev 2026-05-11 04:57:05 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: neuron-technologies/neuron-web#69