23 KiB
SuperFunnels AI — Security Audit & Process Analysis Report
Target: https://app.superfunnelsai.com/app/funnel-cloner
Date: February 7, 2026
Auditor: Clawdbot Security Assessment
Scope: Unauthenticated + Partially Authenticated (email-unverified account)
Note: Full funnel-creation walkthrough was limited by lack of verified account credentials. Findings below are from the accessible attack surface.
Executive Summary
Overall Security Posture: 🔴 HIGH RISK
SuperFunnels AI has several critical and high-severity vulnerabilities that need immediate attention. The most dangerous is a wildcard CORS misconfiguration with credential reflection across all API endpoints, which could allow any website to make authenticated requests on behalf of logged-in users — potentially stealing GHL (GoHighLevel) session tokens, API keys, and credentials.
The application is built on Laravel + Filament 3 + Livewire 3 + React (for the GHL login component), with Laravel Reverb for WebSockets and Cloudflare for CDN/WAF. While some security basics are in place (CSRF tokens, HttpOnly session cookies, X-Frame-Options), critical gaps exist.
Risk Ratings Summary
| Severity | Count | Key Issues |
|---|---|---|
| 🔴 Critical | 2 | CORS misconfiguration, GHL credential proxying |
| 🟠 High | 3 | Email verification bypass (API), no CSP, exposed internal infrastructure |
| 🟡 Medium | 4 | Stored XSS risk, Livewire version mismatch, Horizon exposed, debug info leaks |
| 🔵 Low | 4 | No CAPTCHA, no SRI, FirstPromoter tracking leak, cookie SameSite=Lax |
| ℹ️ Info | 4 | Tech stack fingerprinting, robots.txt, /up endpoint, WebSocket config |
1. Technology Stack Identification
| Component | Details |
|---|---|
| Framework | Laravel (PHP) |
| Admin Panel | Filament v3.3.47 |
| Frontend | Livewire 3 + Alpine.js + React (GHL component) |
| WebSocket | Laravel Reverb via Pusher protocol |
| CDN/WAF | Cloudflare |
| Reverse Proxy | Nginx (behind Cloudflare) |
| Hosting | app.superfunnelsai.com (104.21.9.96, 172.67.189.52 — Cloudflare IPs) |
| WebSocket Host | ws.app.theagencytoolkit.com (178.156.167.241 — direct IP, NOT behind Cloudflare) |
| Affiliate | FirstPromoter (cid: vbcs0jwr) |
| Monitoring | Cloudflare Web Analytics |
| Queue System | Laravel Horizon (installed, 403-protected) |
| Real-time | Laravel Echo + Reverb |
| GHL Integration | Custom React component with browser extension bridge |
2. Process Walkthrough
2.1 Registration Flow
URL: https://app.superfunnelsai.com/register
Fields collected:
- Name (text, no length/format validation observed)
- Email (email type input)
- Password + Confirm Password
- Terms of Service checkbox
Security observations:
- ✅ CSRF
_tokenhidden field present - ✅ Email verification required after registration
- ✅ Password confirmation required
- ❌ No CAPTCHA — vulnerable to automated account creation
- ❌ No password strength requirements visible (accepted
TestPassword123!) - ❌ Accepts
<script>alert('XSS')</script>as a name (stored XSS risk)
POST to: https://app.superfunnelsai.com/register (standard Laravel form submission)
2.2 Email Verification
URL: https://app.superfunnelsai.com/app/email-verification/prompt
- After registration, redirects to verification prompt
- "Resend it" link available
- Application routes (funnel-cloner, etc.) redirect back to verification
- BUT: API endpoints are accessible without email verification (see Finding #2)
2.3 Login Flow (Filament Auth)
URL: https://app.superfunnelsai.com/app/login
Livewire component: filament.pages.auth.login
Data collected:
- Email address
- Password
- Remember me checkbox
Security observations:
- ✅ CSRF via meta tag + Livewire's X-CSRF-TOKEN header
- ✅ Form submission via Livewire (not traditional POST)
- ✅ Password visibility toggle
- ❌ No CAPTCHA or rate limiting visible
- ❌ "Forgot password" flow untested (but endpoint exists at
/app/password-reset/request)
2.4 GHL (GoHighLevel) Login Flow
This is the core of the funnel-cloner — it requires GHL authentication.
The flow works in two modes:
Mode 1: Direct Login
- User enters GHL email + password into a React modal
- POST to
/api/ghl-session/loginwith credentials - If 2FA required, prompts for OTP code
- If multiple GHL accounts, shows account selector
- On success, stores encrypted session with "Remember" option
- Session stored via
/api/funnel-clone/credentials
Mode 2: Chrome Extension Bridge
- User has a GHL browser extension installed
- Extension sends message via
window.postMessagewith typeGHL_EXTENSION_READY - Extension provides:
token,sessionToken,refreshedToken,backendAuthToken,lcApiAuthToken,apiKey,companyId,userId,userType,locationId - These are POSTed to
/api/ghl-session/extensionwith CSRF token - Session established
2.5 Funnel Cloner (Authenticated)
URL: https://app.superfunnelsai.com/app/funnel-cloner
Could not fully test — requires verified email + GHL session
Based on JS bundle analysis, the funnel cloner:
- Requires active GHL session (checks
/api/funnel-clone/credentials) - Uses real-time updates via Laravel Reverb WebSocket
- Has file upload capabilities (Livewire file upload component)
- Interacts with GHL API using proxied credentials
3. Security Findings
🔴 CRITICAL-1: Wildcard CORS with Credential Reflection
Severity: CRITICAL
CVSS: 9.1
Affected Endpoints: All /api/* routes, /horizon/*
The application reflects any Origin in the Access-Control-Allow-Origin header AND sets Access-Control-Allow-Credentials: true. This is the most dangerous CORS misconfiguration possible.
Proof of Concept:
$ curl -sI -X OPTIONS "https://app.superfunnelsai.com/api/funnel-clone/credentials" \
-H "Origin: https://evil.com" \
-H "Access-Control-Request-Method: GET"
Access-Control-Allow-Origin: https://evil.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET
Access-Control-Allow-Headers: Content-Type, X-CSRF-TOKEN
Impact:
- Any website can make authenticated API requests as the logged-in user
- An attacker can create a malicious page that steals GHL session tokens
- GHL API keys, company IDs, user IDs, and auth tokens can be exfiltrated
- Combined with the
/api/ghl-session/extensionendpoint, an attacker could inject their own session data
Affected endpoints confirmed:
GET /api/funnel-clone/credentials— returns GHL session dataPOST /api/ghl-session/login— initiates GHL loginPOST /api/ghl-session/extension— stores GHL session tokensGET/POST /horizon/*— queue monitoring dashboard
Response headers also expose:
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-Auth-Token, Origin, Authorization, X-API-Key
🔴 CRITICAL-2: GHL Credential Proxying Without Adequate Protection
Severity: CRITICAL
CVSS: 8.5
The application proxies GoHighLevel credentials through its own backend. The /api/ghl-session/extension endpoint accepts and stores:
{
"refresh_token": "...",
"token": "...",
"refreshed_token": "...",
"backend_auth_token": "...",
"lc_api_auth_token": "...",
"api_key": "...",
"company_id": "...",
"user_id": "...",
"user_type": "...",
"location_id": "...",
"remember": true
}
Impact:
- GHL API keys and auth tokens pass through the SuperFunnels server
- Combined with CORS vulnerability, these can be stolen cross-origin
- The "Remember session (encrypted)" feature stores GHL credentials server-side
- If the SuperFunnels database is compromised, all stored GHL sessions are exposed
- The direct login flow sends GHL email+password to
/api/ghl-session/login— meaning SuperFunnels has access to plaintext GHL credentials during transit
🟠 HIGH-1: API Accessible Without Email Verification
Severity: HIGH
CVSS: 7.5
After registration (without email verification), API endpoints return data:
GET /api/funnel-clone/credentials → 200 OK
{"session":{"exists":false,"updated_at":null,"storage_state":null,"is_valid":false}}
Impact:
- Automated account creation + API abuse
- No email verification means no identity validation before API access
- Could be used to enumerate API endpoints and functionality
🟠 HIGH-2: No Content-Security-Policy Header
Severity: HIGH
CVSS: 7.0
The application does not set a Content-Security-Policy header. The meta tag check returned none.
Impact:
- XSS attacks can load external scripts, exfiltrate data, and execute arbitrary code
- No restriction on inline scripts, eval(), or external resource loading
- Combined with stored XSS vectors (see MEDIUM-1), this significantly increases attack impact
🟠 HIGH-3: Exposed Internal Infrastructure via WebSocket
Severity: HIGH
CVSS: 6.8
The WebSocket server at ws.app.theagencytoolkit.com (IP: 178.156.167.241) is NOT behind Cloudflare. This exposes:
- Direct server IP — bypasses Cloudflare WAF/DDoS protection
- Reverb key:
h7c0rpv5d85eqkixcops(hardcoded in JS) - Alternative domain:
app.theagencytoolkit.comredirects (308) toapp.superfunnelsai.com - WebSocket auth endpoint:
/broadcasting/auth(requires session cookie)
Proof:
ws.app.theagencytoolkit.com → 178.156.167.241 (direct IP, not Cloudflare)
app.superfunnelsai.com → 104.21.9.96, 172.67.189.52 (Cloudflare)
🟡 MEDIUM-1: Stored XSS Risk in Registration
Severity: MEDIUM
CVSS: 6.1
The registration form accepts <script>alert('XSS')</script> as a valid name. This was successfully stored (registration completed, email verification sent to xsstest@test.com with the XSS payload name).
Impact:
- If the name is rendered unsanitized anywhere (admin panel, user lists, emails), XSS will execute
- Laravel's Blade
{{ }}escapes by default, but Livewire/Filament components or{!! !!}usage could bypass this - Email templates may render the name unsanitized (HTML email XSS)
🟡 MEDIUM-2: Livewire Assets Version Mismatch
Severity: MEDIUM
CVSS: 5.3
A console warning is present:
Livewire: The published Livewire assets are out of date
Impact:
- Published assets don't match the installed Livewire version
- Could indicate missed security patches in frontend assets
- May cause functionality issues or expose known vulnerabilities
🟡 MEDIUM-3: Laravel Horizon Accessible (403, Not 404)
Severity: MEDIUM
CVSS: 5.0
The /horizon endpoint returns 403 (not 404), confirming Horizon is installed:
GET /horizon → 403 (with wildcard CORS headers!)
GET /horizon/api/stats → 403
GET /horizon/api/jobs/recent → 403
Impact:
- Confirms queue system usage (useful for attackers mapping the application)
- If authorization middleware is misconfigured or bypassed, exposes job queue data
- The wildcard CORS on Horizon is especially concerning
🟡 MEDIUM-4: Server Error on Log Viewer
Severity: MEDIUM
CVSS: 4.5
GET /log-viewer → 500 Internal Server Error
With wildcard CORS headers in the response.
Impact:
- Confirms log-viewer package is installed
- 500 error may indicate misconfiguration that could be exploited
- Server errors may leak stack traces in certain configurations
🔵 LOW-1: No CAPTCHA on Registration or Login
Severity: LOW
CVSS: 3.7
No CAPTCHA (reCAPTCHA, hCaptcha, Turnstile) on:
- Registration form
- Login form
- Password reset form
Impact:
- Automated account creation (spam/abuse)
- Credential stuffing attacks
- Brute force on login (though CSRF adds friction)
🔵 LOW-2: No Subresource Integrity (SRI) on External Scripts
Severity: LOW
CVSS: 3.5
External scripts loaded without SRI hashes:
<script src="https://cdn.firstpromoter.com/fpr.js" async></script>
<script src="https://static.cloudflareinsights.com/beacon.min.js/vcd15cbe7772f49c399c6a5babf22c1241717689176015"></script>
Impact:
- If CDN is compromised, malicious code could be injected
- Especially concerning with no CSP to limit script sources
🔵 LOW-3: FirstPromoter Customer ID Exposed
Severity: LOW
CVSS: 2.0
fpr("init", {cid:"vbcs0jwr"});
Impact:
- Reveals affiliate tracking program details
- Could be used for competitive intelligence
🔵 LOW-4: Cookie SameSite=Lax (Not Strict)
Severity: LOW
CVSS: 2.5
Set-Cookie: XSRF-TOKEN=...; secure; samesite=lax
Set-Cookie: superfunnels_ai_session=...; secure; httponly; samesite=lax
While Lax is generally acceptable, Strict would provide better CSRF protection. However, the session cookie properly has HttpOnly and Secure flags.
ℹ️ INFO-1: Technology Stack Easily Fingerprinted
- Filament admin panel identified via Livewire component names (
filament.pages.auth.login) - Laravel identified via cookie naming (
XSRF-TOKEN,superfunnels_ai_session) - Livewire version detectable via published assets warning
- Pusher/Reverb configuration visible in client-side JavaScript
- Alpine.js usage confirmed via event dispatching patterns
ℹ️ INFO-2: Health Check Endpoint Exposed
GET /up → 200 OK
"Application up - HTTP request received. Response rendered in 89ms."
Reveals server response time and application status.
ℹ️ INFO-3: Debug Logging in Client-Side Code
The notification listener script includes extensive console.log and console.warn debug output:
console.log("🔍 User ID detection debug:", {...})
console.warn("🔇 No user ID found, cannot listen for notifications")
console.warn("🔍 Debug - All available data:", {filamentData, Laravel, metaTagsCount, allMetaTags})
This exposes internal data structures to anyone with browser DevTools open.
ℹ️ INFO-4: URL Parameter Modal Injection
The openModal URL parameter accepts arbitrary modal IDs and dispatches Alpine.js events:
window.dispatchEvent(new CustomEvent('open-modal', {
detail: { id: modalId }
}));
While not directly exploitable for XSS (the value goes into querySelector and CustomEvent detail), it could potentially trigger unintended UI actions.
4. Network Analysis
API Endpoints Discovered
| Endpoint | Method | Auth Required | Purpose |
|---|---|---|---|
/api/funnel-clone/credentials |
GET | Yes (unverified OK) | Get GHL session status |
/api/funnel-clone/credentials |
DELETE | Yes | Forget stored GHL session |
/api/ghl-session/login |
POST | Yes + CSRF | Initiate GHL login |
/api/ghl-session/extension |
POST | Yes + CSRF | Store GHL session from extension |
/api/first-login-video/ack |
POST | Yes + CSRF | Acknowledge first-login video shown |
/livewire/update |
POST | CSRF | Livewire component updates |
/broadcasting/auth |
POST | Session | WebSocket channel authorization |
/broadcasting/user-auth |
POST | Session | WebSocket user authentication |
External Services Called
| Service | Domain | Purpose |
|---|---|---|
| Cloudflare | static.cloudflareinsights.com |
Web analytics |
| FirstPromoter | cdn.firstpromoter.com |
Affiliate tracking |
| Bunny Fonts | fonts.bunny.net |
Web fonts |
| Google Cloud Storage | storage.googleapis.com/msgsndr/... |
Media/videos |
| Laravel Reverb | ws.app.theagencytoolkit.com |
Real-time WebSocket |
Response Header Analysis
| Header | Value | Assessment |
|---|---|---|
X-Frame-Options |
SAMEORIGIN |
✅ Good |
X-XSS-Protection |
1; mode=block |
⚠️ Deprecated (CSP preferred) |
X-Content-Type-Options |
nosniff |
✅ Good |
Content-Security-Policy |
MISSING | ❌ Critical gap |
Strict-Transport-Security |
MISSING | ⚠️ Should be set |
Referrer-Policy |
MISSING | ⚠️ Should be set |
Permissions-Policy |
MISSING | ⚠️ Should be set |
Cache-Control |
no-cache, no-store, private |
✅ Good for auth pages |
Server |
cloudflare / nginx |
ℹ️ Mixed (Cloudflare + origin leak) |
5. Client-Side Analysis
JavaScript Bundles
| File | Size | Contents |
|---|---|---|
app-CQli-r76.js |
222 KB | Axios, Pusher, Echo, GHL login React app |
useGhlHttpLogin-B2Y3P8yM.js |
158 KB | React, GHL login form components |
livewire.min.js |
Large | Livewire core (outdated published version) |
filament-monaco-editor-scripts.js |
— | Monaco editor (code editing capability) |
filament-code-field.js |
— | Code field component |
filament-code-editor.js |
— | Code editor component |
Hardcoded Values Found
| Item | Value | Risk |
|---|---|---|
| Reverb/Pusher Key | h7c0rpv5d85eqkixcops |
Medium (public key, but reveals infra) |
| WebSocket Host | ws.app.theagencytoolkit.com |
High (direct IP exposed) |
| FirstPromoter CID | vbcs0jwr |
Low |
| Auth endpoint | /broadcasting/auth |
Info |
| GCP Storage Bucket | storage.googleapis.com/msgsndr/Sr99nTAsuyCabfQCL1JQ |
Info |
localStorage Data
{
"theme": "light",
"pusherTransportTLS": {"timestamp":1770427824413,"transport":"xhr_streaming","latency":3007},
"isOpen": "true",
"collapsedGroups": "null"
}
No sensitive data in localStorage. ✅
sessionStorage Data
{}
Clean (GHL login return URL stored temporarily during login flow).
Cookie Security
| Cookie | Secure | HttpOnly | SameSite | Assessment |
|---|---|---|---|---|
XSRF-TOKEN |
✅ | ❌ | Lax | Expected (JS needs access) |
superfunnels_ai_session |
✅ | ✅ | Lax | ✅ Good |
6. Input Validation Results
Registration Form
| Payload | Field | Result |
|---|---|---|
<script>alert('XSS')</script> |
Name | ⚠️ Accepted — stored in DB |
xsstest@test.com |
Accepted (valid format) | |
TestPassword123! |
Password | Accepted |
Note: Full XSS execution testing could not be completed as the name value needs to be rendered in authenticated views (admin dashboard, user lists, etc.) to confirm if it executes. However, the storage of unvalidated HTML in the name field is a vulnerability regardless.
CSRF Protection
| Endpoint | CSRF Protected | Method |
|---|---|---|
| Registration | ✅ _token hidden field |
HTML form |
| Login | ✅ via Livewire meta tag | AJAX |
| API routes | ✅ CSRF required | Returns 419 on mismatch |
| GHL session endpoints | ✅ X-CSRF-TOKEN header | AJAX |
Authentication Bypass
| Attempt | Result |
|---|---|
Access /app/funnel-cloner without email verify |
Redirected to verify page ✅ |
Access /api/funnel-clone/credentials without email verify |
200 OK — data returned ❌ |
| Access API without any auth | 401 Unauthenticated ✅ |
7. Recommendations
🔴 IMMEDIATE (Critical — Fix Now)
-
Fix CORS Configuration
- Remove wildcard origin reflection
- Whitelist specific allowed origins:
['https://app.superfunnelsai.com'] - Never combine
Access-Control-Allow-Origin: *withAccess-Control-Allow-Credentials: true - In Laravel, update
config/cors.php:'allowed_origins' => ['https://app.superfunnelsai.com'], 'supports_credentials' => true,
-
Audit GHL Credential Flow
- Consider using OAuth 2.0 with GHL instead of proxying raw credentials
- If credential proxying is required, ensure encryption at rest with per-user keys
- Implement token rotation for stored sessions
- Add warning/consent for users about credential handling
🟠 HIGH PRIORITY (Fix This Week)
-
Enforce Email Verification on API Routes
- Add
verifiedmiddleware to all API routes:Route::middleware(['auth', 'verified'])->group(function () { Route::get('/api/funnel-clone/credentials', ...); });
- Add
-
Implement Content-Security-Policy
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.firstpromoter.com https://static.cloudflareinsights.com 'nonce-{random}'; style-src 'self' https://fonts.bunny.net 'unsafe-inline'; font-src 'self' https://fonts.bunny.net; img-src 'self' data: https:; connect-src 'self' wss://ws.app.theagencytoolkit.com; frame-src 'self' -
Move WebSocket Behind Cloudflare
ws.app.theagencytoolkit.comshould use Cloudflare proxy- This exposes the origin server IP, bypassing all Cloudflare protections
🟡 MEDIUM PRIORITY (Fix This Sprint)
-
Add Input Validation on Name Field
- Strip HTML tags from name input
- Add maximum length validation
- Consider alphanumeric + common characters only regex
-
Update Livewire Published Assets
php artisan livewire:publish --assets -
Remove or Properly Secure Horizon & Log Viewer
- Ensure these return 404 (not 403/500) for unauthenticated users
- Or properly gate behind admin authentication
-
Remove Debug Logging from Production
- Remove all
console.log/console.warndebug statements from production JavaScript - Especially the user ID detection debug output
- Remove all
🔵 LOW PRIORITY (Backlog)
- Add CAPTCHA — Cloudflare Turnstile recommended (already on Cloudflare)
- Add SRI hashes to external script tags
- Add missing security headers:
Strict-Transport-Security: max-age=31536000; includeSubDomainsReferrer-Policy: strict-origin-when-cross-originPermissions-Policy: camera=(), microphone=(), geolocation=()
- Consider SameSite=Strict for session cookie
- Remove
/upendpoint from public access or add authentication
8. Limitations
This audit was conducted with the following limitations:
- No verified account access — Could not test the full funnel-cloner workflow
- No GHL account integration — Could not test the GHL login and credential storage flow end-to-end
- No admin panel access — Could not verify stored XSS execution in admin views
- Black-box testing only — No source code access
- No load/stress testing — Rate limiting not fully verified
- No mobile testing — Desktop browser only
- Single session — No multi-user interaction testing
Recommended Next Steps
-
Provide authenticated access (verified account + GHL integration) for deep testing of:
- Funnel creation workflow
- GHL session management
- File upload functionality
- Template testing
- IDOR testing between user accounts
-
Source code review (if available) for:
- Server-side credential encryption implementation
- Database schema for GHL token storage
- Middleware chain verification
- Rate limiting implementation
-
Penetration testing with:
- WebSocket protocol testing
- Livewire component fuzzing
- API endpoint enumeration behind auth
Report generated by Clawdbot Security Assessment
All findings should be verified and triaged by the development team before implementing fixes.



