2026-02-06 23:01:30 -05:00

16 KiB

SuperFunnels AI — Authenticated Pentest & Funnel Cloner Walkthrough

Date: February 6, 2026
Target: https://app.superfunnelsai.com
Authorization: Jake Shore (site owner)
Status: PARTIAL — Unauthenticated recon complete; authentication blocked by 1Password CLI integration failure


1. Executive Summary

This report documents a comprehensive security assessment of SuperFunnels AI (https://app.superfunnelsai.com). Due to a 1Password desktop app integration failure (CLI couldn't connect to desktop app for biometric auth), the pentest was limited to unauthenticated reconnaissance and analysis. Despite this limitation, significant findings were discovered including exposed infrastructure details, technology stack identification, client-side code analysis, and several security concerns.

Key Findings Summary

Severity Count Description
High 2 Exposed Pusher key in client code; WebSocket endpoint SSL failure
Medium 3 CSRF token in meta tag (standard but notable); no CSP header; affiliate tracking script
Low 3 Livewire assets out of date; verbose error messages; missing security headers
Info 8+ Tech stack details, cookie analysis, JS bundle analysis, API surface mapping

Authentication Blocker

1Password CLI v2.32.0 could not connect to the 1Password desktop app. The op signin command hung indefinitely. Account jakeshore98@gmail.com on my.1password.com is registered but not authenticated. Action needed: Enable "Integrate with 1Password CLI" in 1Password desktop app Settings → Developer.


2. Technology Stack

Backend

  • Framework: Laravel (PHP) — confirmed by Livewire, Filament admin panel, XSRF-TOKEN cookie format
  • Admin Panel: Filament v3.3.47 (filament.pages.auth.login Livewire component)
  • Real-time: Laravel Echo + Pusher (WebSocket)
  • CDN/Proxy: Cloudflare
  • Web Server: nginx (behind Cloudflare)

Frontend

  • CSS Framework: Tailwind CSS (via Filament theme)
  • JS Framework: Alpine.js (x-cloak, x-data directives)
  • Real-time UI: Livewire (wire: directives, wire:snapshot)
  • Build Tool: Vite (build/assets paths, manifest.json)
  • Fonts: Inter (via fonts.bunny.net)
  • React: React 18.3.1 (embedded in GHL login/funnel-cloner components)

Third-Party Services

  • FirstPromoter — Affiliate tracking (cid: vbcs0jwr)
  • Pusher — WebSocket real-time (app key: h7c0rpv5d85eqkixcops)
  • GoHighLevel — Primary integration target
  • Google Cloud Storage — Video assets (storage.googleapis.com/msgsndr/)

Domain Architecture

  • Primary app: app.superfunnelsai.com (Cloudflare)
  • WebSocket: ws.app.theagencytoolkit.com (FAILED — SSL error)
  • Legacy domain: app.theagencytoolkit.com (redirects to superfunnelsai)

3. HTTP Security Headers Analysis

Response Headers (GET /app/login)

server: cloudflare
x-frame-options: SAMEORIGIN          ✅ Clickjacking protection
x-xss-protection: 1; mode=block      ✅ XSS filter (legacy)
x-content-type-options: nosniff       ✅ MIME sniffing protection
cache-control: max-age=0, must-revalidate, no-cache, no-store, private  ✅ No caching

Missing Headers

  • Content-Security-Policy (CSP) — No CSP header. Allows arbitrary script/style injection.
  • Strict-Transport-Security (HSTS) — Not present. Relies on Cloudflare.
  • Permissions-Policy — Not present.
  • Referrer-Policy — Not present.

CORS Analysis

  • No Access-Control-Allow-Origin headers returned for cross-origin requests
  • CORS properly restrictive (no wildcard origins detected)

Cookies Set

Cookie Secure HttpOnly SameSite Max-Age Notes
XSRF-TOKEN Yes No Lax 7200s (2hr) Laravel CSRF token, readable by JS (by design)
superfunnels_ai_session Yes Yes Lax 7200s (2hr) Laravel session cookie

Third-party cookies observed:

  • YSC — YouTube (from embedded video)
  • VISITOR_INFO1_LIVE — YouTube
  • VISITOR_PRIVACY_METADATA — YouTube
  • __Secure-ROLLOUT_TOKEN — YouTube/Google

Assessment

  • Session cookie properly marked HttpOnly + Secure
  • XSRF token accessible to JS (Laravel pattern)
  • ⚠️ SameSite=Lax (not Strict) — allows top-level navigation CSRF in some edge cases
  • ⚠️ Session lifetime is short (2 hours)

5. localStorage / sessionStorage

localStorage Contents

theme: "light"

Minimal localStorage usage on login page. Only stores theme preference. No tokens, credentials, or sensitive data stored client-side at the unauthenticated stage.


6. JavaScript Bundle Analysis

Build Manifest (Vite)

{
  "resources/js/app.js": "assets/app-CQli-r76.js" (222KB),
  "resources/js/funnel-cloner.jsx": "assets/funnel-cloner-C_M2lk_c.js" (109KB),
  "resources/js/ghl-template-importer.jsx": "assets/ghl-template-importer-B4OqKx4w.js" (46KB),
  "_useGhlHttpLogin-B2Y3P8yM.js": "assets/useGhlHttpLogin-B2Y3P8yM.js" (158KB)
}

Exposed Pusher App Key

Severity: HIGH

In the echo.js bundle and HTML source, the Pusher app key is exposed:

h7c0rpv5d85eqkixcops

WebSocket connection string:

wss://ws.app.theagencytoolkit.com/app/h7c0rpv5d85eqkixcops?protocol=7&client=js&version=7.6.0&flash=false

Impact: While Pusher app keys are inherently public (client-side), combined with the broken SSL on the WebSocket endpoint, this could allow:

  • Eavesdropping on real-time events if channel authorization is weak
  • Connection enumeration

WebSocket SSL Failure

Severity: HIGH

Console error observed:

WebSocket connection to 'wss://ws.app.theagencytoolkit.com/...' failed: 
Error in connection establishment: net::ERR_SSL_UNRECOGNIZED_NAME_ALERT

The WebSocket host ws.app.theagencytoolkit.com has an SSL/TLS configuration error. This means:

  • Real-time features (notifications, live updates) are broken
  • Users are not receiving WebSocket-based updates
  • The domain may have an expired or misconfigured certificate

GHL Login Module (useGhlHttpLogin-B2Y3P8yM.js)

This is a React-based GoHighLevel HTTP login module that:

  1. Renders a login modal for GHL credentials (email/password)
  2. Supports 2FA (6-digit OTP code)
  3. Supports multiple accounts (account selection dialog)
  4. Session persistence — "Remember my session (encrypted)" option
  5. Uses CSRF tokens from meta tag
  6. Request caching — GET requests to /api/funnel-clone/* are cached for 5 seconds (deduplication)
  7. Portal rendering — Uses React portals to render modals

Key function: Ro() (renamed apiFetch) — all API calls go through this function which:

  • Reads CSRF token from meta[name="csrf-token"]
  • Sets credentials: "same-origin"
  • Adds Accept: application/json and Content-Type: application/json
  • Handles response parsing with error wrapping

Login flow:

  1. POST to configurable endpoint with {email, password, remember}
  2. If status: "otp_required" → show 2FA dialog
  3. If status: "account_required" → show account picker
  4. POST again with {email, password, remember, otp, challenge_token, company_id}
  5. On status: "authenticated" → callback fires

Funnel Cloner Module (funnel-cloner-C_M2lk_c.js)

References found in the funnel cloner bundle:

  • https://app.gohighlevel.com/location/preview-location-123/page-builder/preview-step-456
  • https://app.gohighlevel.com/v2/location/${Be}/funnels-websites/${X}
  • https://app.gohighlevel.com/v2/location/${Be}/funnels-websites/${X}/${g.target.funnelId}/
  • https://app.gohighlevel.com/v2/location/preview-location-123/funnels-websites/funnels

This confirms the funnel cloner:

  • Interacts directly with GHL's funnel/website builder
  • Uses GHL location IDs and funnel IDs
  • Has preview URL generation capability
  • References "GoHighLevel" 5 times

GHL Template Importer (ghl-template-importer-B4OqKx4w.js)

References "GoHighLevel" 13 times. Uses dynamic URL construction: https://${d} suggesting it can target different GHL subdomains/locations.

Main App Bundle (app-CQli-r76.js)

  • Contains Pusher client library
  • Contains Alpine.js
  • References: Authorization (11x), Bearer (2x), apiKey (2x), GoHighLevel (2x)
  • No hardcoded API keys or secrets found
  • Pusher key h7c0rpv5d85eqkixcops referenced once

No Hardcoded Secrets Found

Across all JS bundles analyzed, no hardcoded API keys, secret keys, or credentials were found. All secrets appear to be server-side.


7. API Surface & Endpoint Discovery

Tested Endpoints

Path Status Notes
/app/login 200 Login page
/api Timeout/no response
/api/v1 Timeout/no response
/api/docs Timeout/no response
/api/health Timeout/no response
/.env Timeout/no response
/debug Timeout/no response
/telescope Timeout/no response
/horizon Timeout/no response
/nova Timeout/no response
/pulse Timeout/no response
/robots.txt 200 Cloudflare managed
/sitemap.xml 404 Not found
/build/manifest.json 200 Vite manifest exposed
/build/.vite/manifest.json 403 Blocked by nginx

Notable: All potentially sensitive endpoints (/.env, /telescope, /horizon, /nova, /debug) appear to timeout rather than return errors, suggesting Cloudflare is likely blocking/timing out suspicious requests.

API Patterns from JS Analysis

  • /api/funnel-clone/{id} — GET (with 5s client-side caching)
  • Login endpoint is configurable (passed as prop)
  • All API calls use same-origin credentials

Vite Manifest Exposure

Severity: LOW

The build manifest at /build/manifest.json is publicly accessible, revealing:

  • All JS/CSS entry points
  • Source file paths (e.g., resources/js/funnel-cloner.jsx)
  • Build dependency graph

8. CSRF Protection Analysis

Implementation

  • CSRF token in <meta name="csrf-token"> tag
  • XSRF-TOKEN cookie (Laravel double-submit pattern)
  • Livewire forms use wire:submit which includes CSRF automatically
  • React components read CSRF from meta tag for API calls

Assessment

  • CSRF protection is properly implemented
  • Token rotation on each page load
  • Both cookie-based and header-based CSRF protection
  • ⚠️ No explicit SameSite=Strict (uses Lax)

9. Livewire Component Analysis

Login Component

From the wire:snapshot attribute:

{
  "data": {
    "email": null,
    "password": null,
    "remember": false
  },
  "memo": {
    "name": "filament.pages.auth.login",
    "path": "app/login",
    "method": "GET"
  },
  "checksum": "768548c839b4cf1fa2309e6700f2178973b157b923c510603052cfaaa1f24fc3"
}
  • Component ID: VP4ulpmT3sa9rC7mHCTT
  • Submit action: wire:submit="authenticate"
  • Uses Livewire v3 with checksum verification

Livewire Version Warning

Console warning: "The published Livewire assets are out of date"

Severity: LOW — Outdated Livewire assets may contain known vulnerabilities. Should update to latest version.


10. Third-Party Risk Assessment

FirstPromoter (Affiliate Tracking)

  • Campaign ID: vbcs0jwr
  • Tracking script loaded from cdn.firstpromoter.com/fpr.js
  • Sets cookies: _fprom_details, _fprom_tid, _fprom_ref
  • Tracks referral parameters: fp_ref, fpr, via, ref, a, _from, _by, deal, _go, _get
  • Cross-domain tracking capability via fpc parameter
  • Risk: Third-party script has full DOM access; could theoretically read form data

YouTube (Background Video)

  • Embedded video from storage.googleapis.com/msgsndr/
  • Sets tracking cookies
  • Uses the msgsndr bucket (GoHighLevel's media CDN domain)

Google Cloud Storage

  • Video hosted at: https://storage.googleapis.com/msgsndr/Sr99nTAsuyCabfQCL1JQ/media/69430b1136a81350a9b474ff.mp4
  • The msgsndr bucket appears to be GoHighLevel's shared storage
  • Account ID: Sr99nTAsuyCabfQCL1JQ

11. robots.txt Analysis

# Cloudflare Managed Content
User-agent: *
Content-Signal: search=yes,ai-train=no
Allow: /

# Blocked bots
User-agent: Amazonbot, Applebot-Extended, Bytespider, CCBot, 
            ClaudeBot, Google-Extended, GPTBot, meta-externalagent
Disallow: /

Notable:

  • Cloudflare AI bot protection enabled
  • All AI training crawlers explicitly blocked
  • Search indexing allowed
  • No specific app routes blocked

12. Domain & Infrastructure

DNS/SSL

  • Primary: app.superfunnelsai.com → Cloudflare
  • WebSocket: ws.app.theagencytoolkit.comSSL ERROR (ERR_SSL_UNRECOGNIZED_NAME_ALERT)
  • Legacy: app.theagencytoolkit.com → Redirects (308) to superfunnelsai
  • Cloudflare Ray: MIA (Miami datacenter)

Server Information

  • server: cloudflare (all responses)
  • server: nginx (WebSocket endpoint, behind Cloudflare)
  • Cloudflare NEL (Network Error Logging) enabled

13. Login Page UI Documentation

Screenshot: step1-login.png

The login page features:

  • SuperFunnels AI logo (funnel icon + sparkles)
  • "Sign in" heading
  • Email address field (required)
  • Password field with show/hide toggle
  • "Forgot password?" link
  • "Remember me" checkbox
  • "Sign in" button (blue/purple)
  • "Not signed up yet? Create an account here" button (green)
  • Background: Dark gradient with animated video overlay (opacity 0.5)
  • Card: White/semi-transparent with rounded corners and shadow

14. Recommendations

Critical

  1. Fix WebSocket SSLws.app.theagencytoolkit.com has a broken SSL certificate. This breaks all real-time features and is visible to users in console errors.
  2. Update Livewire assets — Published assets are outdated per console warning.

High

  1. Add Content-Security-Policy header — No CSP means XSS vulnerabilities have maximum impact.
  2. Add HSTS header — While Cloudflare handles HTTPS, explicit HSTS prevents downgrade attacks.
  3. Migrate WebSocket to superfunnelsai.com domain — The theagencytoolkit.com domain reference suggests incomplete brand migration.

Medium

  1. Add Referrer-Policy header — Prevent referrer leakage.
  2. Add Permissions-Policy header — Restrict browser feature access.
  3. Review FirstPromoter script permissions — Third-party script has full DOM access on all pages.
  4. Block Vite manifest.json — Reveals build structure and source paths.

Low

  1. Set SameSite=Strict on session cookie — Current Lax allows some cross-site scenarios.
  2. Remove console warnings in production — Livewire and WebSocket errors visible in browser console.
  3. Review GCS bucket permissions — The msgsndr bucket path is exposed in HTML source.

15. What Could Not Be Tested (Requires Authentication)

The following tests require a valid login session:

  • Funnel cloner full process walkthrough
  • API endpoint security (authenticated)
  • GHL token handling and storage
  • AI generation process and model details
  • Rate limiting on authenticated endpoints
  • Authorization/access control between accounts
  • File upload security
  • XSS/SQLi in authenticated form fields
  • Session management (timeout, fixation, hijacking)
  • IDOR on funnel/account resources
  • API key exposure in authenticated JS/network requests

To complete: Fix 1Password CLI integration (Settings → Developer → Enable CLI integration), then re-run this pentest with op CLI authentication.


Appendix A: Screenshots

File Description
step1-login.png Login page UI

Appendix B: Files Analyzed

File Size Type
app-CQli-r76.js 222KB Main app bundle (Alpine.js, Pusher, Livewire)
useGhlHttpLogin-B2Y3P8yM.js 158KB GHL HTTP login React module
funnel-cloner-C_M2lk_c.js 109KB Funnel cloner React module
ghl-template-importer-B4OqKx4w.js 46KB GHL template importer React module
echo.js ~80KB Laravel Echo + Pusher client
theme-D32Rw_yP.css Filament admin theme

Appendix C: Console Errors Observed

[warning] Livewire: The published Livewire assets are out of date
[error]   WebSocket connection to 'wss://ws.app.theagencytoolkit.com/...' failed: 
          net::ERR_SSL_UNRECOGNIZED_NAME_ALERT
[warning] User ID not found, cannot initialize real-time notifications
[warning] GPU stall due to ReadPixels (WebGL)