Typebot is a widely deployed open-source conversational form and chatbot builder (Typeform/Intercom alternative) used for lead generation, customer onboarding, and data collection — it stores all visitor responses including names, email addresses, phone numbers, and any other data collected during chat flows. Key assessment areas: NEXTAUTH_SECRET signs authentication tokens; the builder API exposes all chatbot flow configurations; the results API provides access to all visitor submissions including PII; PostgreSQL stores all data; and S3/MinIO stores file uploads from form submissions. Typebot compromise exposes lead generation pipeline data and customer PII collected through embedded chatbots. This guide covers systematic Typebot security assessment.
# Typebot — authentication and API token testing
TYPEBOT_URL="https://typebot.example.com"
# Typebot uses email magic link or OAuth (Google/GitHub) — no password by default
# Check if email/password auth is enabled (NEXTAUTH_URL + credentials provider)
# Some deployments add custom credentials
# Test admin access if credentials provider is enabled
for CRED in "admin@example.com:admin" "admin@typebot.io:password"; do
EMAIL=$(echo $CRED | cut -d: -f1)
PASS=$(echo $CRED | cut -d: -f2)
AUTH=$(curl -s -X POST "${TYPEBOT_URL}/api/auth/callback/credentials" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "email=${EMAIL}&password=${PASS}" 2>/dev/null)
echo "${EMAIL}/${PASS}: $(echo $AUTH | head -c 60)"
done
# API token (generated in Typebot account settings)
API_TOKEN="your-typebot-api-token"
curl -s "${TYPEBOT_URL}/api/typebots" \
-H "Authorization: Bearer ${API_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
typebots = d.get('typebots',[])
print(f'Typebots: {len(typebots)}')
for t in typebots[:5]:
print(f' [{t.get(\"id\")}] {t.get(\"name\")} published={t.get(\"publishedTypebotId\")}')
" 2>/dev/null
# Check if workspace allows open invitation
# NEXT_PUBLIC_MULTI_USER_MODE / ADMIN_EMAIL controls access
# Typebot API — chatbot configuration and visitor response enumeration
TYPEBOT_URL="https://typebot.example.com"
API_TOKEN="your-typebot-api-token"
# Get all typebots (chatbot definitions)
curl -s "${TYPEBOT_URL}/api/typebots" \
-H "Authorization: Bearer ${API_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
typebots = d.get('typebots',[])
print(f'Typebots: {len(typebots)}')
for t in typebots[:10]:
# Each typebot contains the complete flow definition including all questions,
# conditional logic, integrations (webhooks, email, CRM), and variable names
print(f' [{t.get(\"id\")}] {t.get(\"name\")} updated={str(t.get(\"updatedAt\",\"\"))[:10]}')
" 2>/dev/null
# Get chatbot details including full flow configuration
TYPEBOT_ID="your-typebot-id"
curl -s "${TYPEBOT_URL}/api/typebots/${TYPEBOT_ID}" \
-H "Authorization: Bearer ${API_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
tb = d.get('typebot',{})
# groups contain all chat flow blocks including:
# - Text blocks (questions asked)
# - Input blocks (what data is collected: email, phone, name, etc.)
# - Integration blocks (webhooks, Zapier, Google Sheets, etc.)
# - Logic blocks (conditional routing)
groups = tb.get('groups',[])
print(f'Typebot: {tb.get(\"name\")} groups/blocks: {len(groups)}')
for g in groups[:5]:
print(f' Block group: {g.get(\"title\",\"\")}')
for block in g.get('blocks',[])[:3]:
print(f' block type={block.get(\"type\",\"\")}')
" 2>/dev/null
# Get all visitor results (form submissions with PII)
curl -s "${TYPEBOT_URL}/api/typebots/${TYPEBOT_ID}/results?limit=100" \
-H "Authorization: Bearer ${API_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
results = d.get('results',[])
total = d.get('total',len(results))
print(f'Results: {total} total, showing {len(results)}')
for r in results[:5]:
print(f' [{r.get(\"id\")}] created={str(r.get(\"createdAt\",\"\"))[:10]} isCompleted={r.get(\"isCompleted\")}')
# Answers contain the actual visitor responses
for ans in r.get('answers',[])[:5]:
print(f' {ans.get(\"blockId\",\"\")}: {str(ans.get(\"content\",\"\"))[:60]}')
" 2>/dev/null
# Export all results as CSV
curl -s "${TYPEBOT_URL}/api/typebots/${TYPEBOT_ID}/results/export" \
-H "Authorization: Bearer ${API_TOKEN}" 2>/dev/null | head -5
# Typebot NEXTAUTH_SECRET and database credential extraction
# .env file — Typebot configuration
cat /app/.env 2>/dev/null | grep -E "NEXTAUTH_SECRET|DATABASE_URL|S3_|SMTP|GOOGLE_|GITHUB_|ADMIN_EMAIL"
# NEXTAUTH_SECRET — JWT signing key for NextAuth sessions
# DATABASE_URL — PostgreSQL connection string
# S3_* — file upload storage credentials
# SMTP_* / MAILER_* — email credentials
# GOOGLE_CLIENT_ID/SECRET — OAuth credentials
# GITHUB_CLIENT_ID/SECRET — OAuth credentials
# Docker environment variables
docker inspect typebot-builder 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
for c in d:
for e in c.get('Config',{}).get('Env',[]):
if any(k in e for k in ['NEXTAUTH','DATABASE','S3','SMTP','GOOGLE','GITHUB','SECRET','PASSWORD','ACCESS_KEY']):
print(e)
" 2>/dev/null
# PostgreSQL — all typebot and result data
DB_URL="postgresql://typebot:PASSWORD@localhost/typebot"
psql "$DB_URL" 2>/dev/null << 'EOF'
-- All typebot definitions
SELECT t.id, t.name, t.workspace_id,
t.created_at, t.updated_at, t.is_archived
FROM TypeBot t
ORDER BY t.updated_at DESC
LIMIT 20;
EOF
-- All results (visitor submissions)
psql "$DB_URL" 2>/dev/null << 'EOF'
SELECT r.id, r.typebot_id, r.is_completed,
r.created_at, r.variables::text
FROM Result r
ORDER BY r.created_at DESC
LIMIT 20;
EOF
-- variables JSONB: all collected visitor data (name, email, phone, custom vars)
-- All individual answers
psql "$DB_URL" 2>/dev/null << 'EOF'
SELECT a.id, a.result_id, a.block_id,
a.group_id, a.content, a.created_at
FROM Answer a
ORDER BY a.created_at DESC
LIMIT 30;
EOF
-- content column: individual answer content (email addresses, names, phone numbers, etc.)
| Security Test | Method | Risk |
|---|---|---|
| NEXTAUTH_SECRET extraction and session token forgery | Read .env NEXTAUTH_SECRET — NextAuth JWT signing key; forge valid session tokens for any Typebot user including admin; full access to all chatbots and visitor responses | Critical |
| Visitor PII bulk export via Results API | GET /api/typebots/{id}/results/export — all visitor submissions as CSV including names, emails, phones, and custom data; complete GDPR-regulated data in one request | High |
| PostgreSQL Answer table PII extraction | SELECT content FROM Answer — all individual visitor answer content; complete record of every response to every chatbot question by every visitor | High |
| Chatbot flow configuration and integration secret extraction | GET /api/typebots/{id} — complete chatbot flow with all integration configs including webhook URLs, Google Sheets API keys, CRM credentials embedded in integration blocks | High |
| S3/MinIO access key extraction for visitor file download | Read S3_ACCESS_KEY and S3_SECRET_KEY from .env — direct access to all visitor uploaded files outside Typebot access controls | High |
Ironimo tests Typebot deployments for NEXTAUTH_SECRET extraction and session token forgery, visitor PII bulk export via Results API, PostgreSQL Answer table complete visitor response extraction, chatbot integration secret extraction (webhook URLs, Google Sheets keys, CRM credentials), S3 file upload storage credential exposure, visitor file access without authorization, Docker environment variable exposure, ADMIN_EMAIL access testing, workspace invitation bypass, and multi-user mode access boundary assessment.
Start free scan