Testing Minecraft Authentication Systems - Security and Login Flow
Learn how to test authentication plugins like AuthMe, validate Microsoft/Mojang auth, and ensure secure login flows on your Minecraft server
Understanding Minecraft Authentication
Authentication determines who can join your server and how their identity is verified. The authentication system is your server's first line of defense against unauthorized access.
Authentication Types
Online Mode (Default)
online-mode=trueHow it works:
- Player connects to server
- Server contacts Mojang/Microsoft authentication servers
- Authentication servers verify player owns the account
- Server accepts or rejects connection based on verification
Pros:
- Secure - players must own valid Minecraft accounts
- No impersonation - UUIDs tied to real accounts
- Automatic - no additional plugins needed
Cons:
- Requires internet connection
- Mojang/Microsoft servers must be reachable
- Can't play if authentication servers are down
Offline Mode
online-mode=falseHow it works:
- Player connects with any username
- Server accepts connection without verification
- No authentication check performed
Pros:
- Works offline
- No external dependencies
- Useful for testing/development
Cons:
- CRITICAL SECURITY RISK: Anyone can impersonate any player
- No protection against fake accounts
- Vulnerable to exploitation
Never use offline mode on public servers without authentication plugins! Anyone can join with any username, including admin accounts. This is a critical security vulnerability that can lead to complete server compromise.
When to use offline mode:
- Local testing/development
- Behind a proxy (proxy handles authentication)
- NEVER on a public server without additional authentication
Plugin-Based Authentication
For offline mode servers, authentication plugins provide login security:
| Plugin | Type | Security Level | Use Case |
|---|---|---|---|
| AuthMe | Password-based | Good | Public offline servers |
| FastLogin | Hybrid online/offline | Excellent | Mixed authentication |
| JPremium | Account validation | Good | Cracked + premium support |
| nLogin | Simple password | Moderate | Small servers |
AuthMe: Deep Dive
AuthMe is the most popular authentication plugin for offline mode servers.
Installation
# Download AuthMe
wget https://github.com/AuthMe/AuthMeReloaded/releases/download/5.6.0/AuthMe-5.6.0.jar
# Place in plugins folder
mv AuthMe-5.6.0.jar plugins/
# Start server (config auto-generates)
java -jar paper.jarCore Configuration
config.yml:
settings:
# Session system - players stay logged in between rejoins
sessions:
enabled: true
timeout: 10 # Minutes before requiring re-login
# Registration settings
registration:
# Require registration
enabled: true
# Force players to register before playing
force: true
# Message interval (seconds) for unregistered players
messageInterval: 5
# Allow only 1 account per IP (prevent spam accounts)
maxRegPerIp: 1
# Password security
security:
# Minimum password length
minPasswordLength: 5
# Maximum password length
maxPasswordLength: 30
# Unsafe passwords (dictionary check)
unsafePasswords:
- '123456'
- 'password'
- 'qwerty'
- 'username' # Prevents using username as password
# Timeout before kick if not logged in
timeout:
kick: 30 # Seconds
# Restrict unlogged players
restrictions:
# Commands unlogged players can use
allowCommands:
- '/login'
- '/register'
- '/l'
- '/reg'
# Prevent movement before login
allowMovement: false
# Prevent block interactions
allowChat: falseDatabase Configuration
AuthMe supports multiple database backends:
SQLite (Default - File-based):
DataSource:
backend: 'SQLITE'
mySQLDatabase: 'authme'
mySQLTablename: 'authme'MySQL (Recommended for production):
DataSource:
backend: 'MYSQL'
mySQLHost: 'localhost'
mySQLPort: '3306'
mySQLDatabase: 'minecraft_authme'
mySQLUsername: 'authme_user'
mySQLPassword: 'secure_password_here'
mySQLTablename: 'authme'
mySQLPoolSize: 10Setup MySQL:
-- Create database
CREATE DATABASE minecraft_authme;
-- Create user
CREATE USER 'authme_user'@'localhost' IDENTIFIED BY 'secure_password_here';
-- Grant permissions
GRANT ALL PRIVILEGES ON minecraft_authme.* TO 'authme_user'@'localhost';
FLUSH PRIVILEGES;Password Hashing
AuthMe hashes passwords for security:
security:
# Hashing algorithm
# Options: SHA256, BCRYPT, BCRYPT2Y (recommended)
passwordHash: 'BCRYPT2Y'
# BCrypt cost factor (higher = more secure, slower)
# 10 = good balance, 12+ for high security
bCryptLog2Rounds: 10Never use SHA256 for password hashing! SHA256 is vulnerable to rainbow table attacks. Always use BCRYPT or BCRYPT2Y for secure password storage.
Hashing comparison:
| Algorithm | Security | Speed | Recommended |
|---|---|---|---|
| SHA256 | Moderate | Fast | No - vulnerable to rainbow tables |
| BCRYPT | Good | Slower | Yes |
| BCRYPT2Y | Best | Slower | Yes - most secure |
Testing Authentication Systems
Proper testing ensures your authentication actually protects players.
Test 1: Registration Flow
Objective: Verify new players can register
- Join server with new account
- Attempt to move/interact
- Execute
/register <password> <password> - Verify login successful
Expected behavior:
[Initial join]
> Player frozen in place
> Chat restricted
> Repeated message: "Please register with /register <password> <password>"
[After /register password123 password123]
> Registration successful message
> Player can move and interact
> Player entry created in databaseCommon issues:
| Issue | Cause | Fix |
|---|---|---|
| Can move before registering | allowMovement: true | Set to false |
| Command doesn't work | Permission issue | Grant authme.register |
| "Too many accounts" | IP limit exceeded | Increase maxRegPerIp or change IP |
Test 2: Login Flow
Objective: Verify returning players must login
- Register account (see Test 1)
- Disconnect
- Reconnect
- Verify frozen until
/login <password>
Expected behavior:
[Upon rejoin]
> Player spawned but frozen
> Message: "Please login with /login <password>"
[After /login password123]
> Login successful
> Player can interact normallyTest 3: Session Persistence
Objective: Test session timeout
- Login successfully
- Disconnect
- Reconnect within session timeout (default: 10 minutes)
- Verify auto-login
Expected behavior:
[Rejoin within 10 minutes]
> Automatic login
> No /login required
> Message: "Session login successful"
[Rejoin after 10+ minutes]
> Requires /login againConfiguration:
settings:
sessions:
enabled: true
timeout: 10 # MinutesTest 4: Password Security
Objective: Unsafe passwords are rejected
- Attempt
/register 123456 123456 - Verify rejection
Expected behavior:
> Error: "This password is not secure!"
> Registration failsTest with username-as-password:
Username: TestPlayer
Command: /register TestPlayer TestPlayer
Expected: Rejected (matches username)Test 5: Brute Force Protection
Objective: Prevent password guessing attacks
Configuration:
security:
# Limit login attempts
maxLoginTries: 3
# Timeout after max attempts (minutes)
tempBanLength: 5Test:
- Login with wrong password 3 times
- Verify temporary ban
Expected behavior:
[Attempt 1] /login wrongpass
> Error: "Wrong password!"
[Attempt 2] /login wrongpass2
> Error: "Wrong password! (2/3 attempts remaining)"
[Attempt 3] /login wrongpass3
> Kicked: "Too many failed login attempts. Try again in 5 minutes."Test 6: Database Persistence
Objective: Verify accounts persist across restarts
- Register account
- Stop server
- Start server
- Login with registered account
Expected: Login succeeds (data persisted to database)
Verify database:
-- Check user exists
SELECT * FROM authme WHERE username = 'TestPlayer';
-- Should return row with:
-- - username
-- - hashed password
-- - registration IP
-- - registration dateTest 7: Multi-Account Limits
Objective: Prevent spam accounts from same IP
Configuration:
registration:
maxRegPerIp: 1Test:
- Register account "Player1" from IP 1.2.3.4
- Attempt to register "Player2" from same IP
Expected:
> Error: "You have registered too many accounts from this IP address!"Override for testing:
# Temporarily allow more accounts
/authme setmaxreg 1.2.3.4 3
# Set to 0 for unlimited
/authme setmaxreg 1.2.3.4 0Test 8: Command Restrictions
Objective: Unlogged players can't execute commands
Configuration:
restrictions:
allowCommands:
- '/login'
- '/register'Test:
- Join without logging in
- Attempt
/help,/spawn,/warp
Expected: All commands blocked except /login and /register
Test 9: Chat Restrictions
Objective: Unlogged players can't chat
Configuration:
restrictions:
allowChat: falseTest:
- Join without logging in
- Send chat message
Expected: Message blocked, reminder to login
Test 10: Kick Timeout
Objective: Idle players are kicked
Configuration:
timeout:
kick: 30 # SecondsTest:
- Join server
- Don't login
- Wait 30 seconds
Expected: Kicked with message "Login timeout"
Testing with Multiple Accounts
Authentication systems must handle concurrent logins, account switching, and edge cases.
Test Case: Simultaneous Registrations
Setup:
- 10 players join simultaneously
- All attempt to register
Expected:
- All registrations processed
- No race conditions or database conflicts
- Each gets unique entry
How to test: Use bot clients to connect concurrently
Test Case: Account Impersonation Prevention
Scenario: Player "Notch" is registered. Can someone else join as "notch" (lowercase)?
Test:
- Register account "Notch"
- Disconnect
- Join as "notch" (lowercase)
Expected behavior:
Depends on configuration:
settings:
# Case-sensitive usernames
forceSingleSession: true
preventOtherCase: true # RecommendedEnable preventOtherCase to prevent account impersonation! Without this setting, attackers can create "notch" to impersonate "Notch" accounts, leading to confusion and potential exploitation.
With preventOtherCase: true:
- "notch" sees: "This username is already registered with a different case!"
Without protection:
- "notch" and "Notch" treated as separate accounts (bad!)
Test Case: Password Change Flow
Test:
- Register with password "oldpass"
- Execute
/changepassword oldpass newpass - Disconnect and reconnect
- Login with "newpass"
Expected: New password works, old password fails
Test Case: Account Recovery
Configuration:
settings:
# Email recovery
emailRecovery: trueTest:
- Register with email:
/register password123 password123 player@example.com - Execute
/forgot - Check email for recovery code
Note: Requires SMTP configuration and email server access
Microsoft/Mojang Authentication Testing
For online-mode servers or premium account verification, you'll interact with Mojang's authentication API to validate genuine Minecraft accounts.
Test 1: Valid Premium Account
Test:
- Join with legitimate Minecraft account
- Verify immediate connection (no additional login)
Expected: Seamless join, no authentication prompts
Test 2: Cracked Client Rejection
Test:
- Attempt to join with cracked/offline client
- Verify rejection
Expected:
> "Failed to verify username!"
> or
> "Invalid session"Test 3: Account Switching
Test:
- Join with Account A
- Disconnect
- Join with Account B (same PC)
Expected: Both accounts work independently, separate UUIDs
Hybrid Authentication: FastLogin
FastLogin allows both premium (online) and cracked (offline) players.
How it works:
- Player connects
- FastLogin checks if account is premium (Mojang database)
- Premium players auto-login (no password)
- Cracked players must use
/login(requires AuthMe)
Configuration:
autoLogin:
enabled: true
# If premium account exists, auto-login
# If not, require password via AuthMe
autoRegister: falseTesting:
Test 1: Premium Player
Account: RealMinecraftPlayer (premium)
Expected: Auto-login, no password requiredTest 2: Cracked Player
Account: CrackedPlayer (not premium)
Expected: Must /register and /login via AuthMeTest 3: Premium Player on Cracked Client
Scenario: Premium account name, but using cracked client
Expected: Rejected (can't impersonate premium player)Security Testing
Authentication security is critical. Test for vulnerabilities.
SQL Injection Testing
Only test on your own server with explicit permission. Testing SQL injection on servers you don't own is illegal and unethical.
Test:
/register ' OR '1'='1 password
/login ' OR '1'='1Expected: Commands fail, special characters escaped
If SQL injection succeeds, update AuthMe immediately! A successful SQL injection attack means your database is compromised and attackers can access all user accounts, passwords, and potentially execute arbitrary code on your server.
Timing Attack Testing
Attack concept: Measure response time differences to determine if username exists.
Test:
/login ExistingUser wrongpass # Time response
/login NonExistentUser wrongpass # Time responseGood: Both take similar time (constant-time comparison) Bad: Existing user takes longer (reveals user exists)
Modern AuthMe versions prevent this with constant-time operations.
Session Hijacking Testing
Test:
- Login as Player1
- Note session token (if visible in logs - shouldn't be!)
- Attempt to use token from different IP
Expected: Session invalidated, requires re-login
Configuration:
settings:
sessions:
enabled: true
# Validate IP matches session IP
ipCheck: trueAlways enable ipCheck for session security! Without IP validation, stolen session tokens can be used from any location to access player accounts.
Automated Testing with Bots
Manual authentication testing is tedious. Bots enable comprehensive, repeatable tests.
Why Bots for Auth Testing?
Manual testing limitations:
- Can't test 100 concurrent registrations
- Difficult to test timing attacks
- Hard to reproduce edge cases consistently
Bots provide:
- Concurrent registration testing (10, 50, 100+ accounts)
- Automated login/logout cycles
- Consistent, repeatable test scenarios
- Load testing on authentication system
Test Scenarios
Scenario 1: Mass Registration
Objective: Verify system handles many registrations
Setup:
- Configure 50 bots with unique accounts
- All attempt to register simultaneously
Test:
1. All bots connect
2. Each sends /register <unique_password> <unique_password>
3. Monitor success rate and database entries
Expected:
- 100% registration success
- All accounts in database
- No race conditions or conflictsScenario 2: Login Attempt Load
Objective: Test authentication system under load
Setup:
- 100 registered bot accounts
- All disconnected
Test:
1. All bots reconnect simultaneously
2. All execute /login <password>
3. Monitor login success rate
Expected:
- All logins succeed
- No timeouts or failures
- Database handles concurrent auth checksScenario 3: Brute Force Simulation
Objective: Verify brute force protection works
Setup:
- 1 registered account
- Bot attempts multiple wrong passwords
Test:
1. Bot connects
2. Bot tries wrong password 10 times rapidly
3. Monitor if temporary ban triggers
Expected:
- After 3 attempts (or configured limit), bot is kicked/banned
- Further attempts blocked during ban periodScenario 4: Session Timeout Testing
Objective: Verify session expiration works correctly
Setup:
- Bot logs in successfully
- Session timeout set to 2 minutes
Test:
1. Bot disconnects
2. Bot reconnects after 1 minute
3. Verify auto-login
4. Bot disconnects
5. Bot reconnects after 3 minutes
6. Verify /login required
Expected:
- < 2 minutes: Auto-login
- > 2 minutes: Manual login requiredScenario 5: Account Limit Bypass Attempt
Objective: Ensure IP-based account limits work
Setup:
- maxRegPerIp = 1
- Bots use same IP (proxy)
Test:
1. Bot 1 registers successfully
2. Bot 2 (same IP) attempts to register
3. Verify rejection
Expected:
- Bot 1 succeeds
- Bot 2 gets "too many accounts" errorUsing Bots for Authentication Testing
Bot tools can simulate realistic authentication flows:
Basic Configuration:
Target: your-server.com:25565
Bot Count: 10
Account Type: Offline (custom usernames)
Test Flow:
1. Connect bots sequentially
2. Each bot attempts registration
3. Monitor success/failure rates
4. Verify all accounts in databaseAdvanced: Login Cycle Test
Setup: 50 pre-registered bot accounts
Test Flow:
1. All bots connect (staggered, 1 second apart)
2. All bots execute /login <password>
3. Bots remain connected for 2 minutes
4. All bots disconnect
5. Wait 30 seconds
6. Repeat cycle 10 times
Monitor:
- Login success rate per cycle
- Any authentication errors
- Database connection pool exhaustion
- Memory leaks in auth pluginWhat to Monitor:
# Server-side
tail -f logs/latest.log | grep -i "authme\|login\|register"
# Database connections
# For MySQL
mysql> SHOW PROCESSLIST;
# Check AuthMe database
mysql> SELECT COUNT(*) FROM authme;
# Server performance
/spark tpsInterpreting Results:
Good Results:
✅ All bot registrations succeeded
✅ All bot logins succeeded
✅ No authentication errors in logs
✅ Database entries match bot count
✅ TPS remained 19-20 during auth load
Problems:
❌ Some registrations failed (database issue?)
❌ Login timeouts (slow database queries?)
❌ Errors: "Too many connections" (connection pool too small)
❌ TPS dropped to 15 during auth (performance issue)Performance Benchmarking:
Test: 100 bots register simultaneously
Good: All complete within 10 seconds
Acceptable: All complete within 30 seconds
Poor: Timeouts or failures
If poor:
- Increase database connection pool
- Optimize database indexes
- Use MySQL instead of SQLite
- Upgrade server CPUBest Practices Summary
- Use online mode when possible (most secure)
- If offline mode necessary, always use authentication plugin (AuthMe)
- Use BCRYPT2Y hashing for passwords
- Enable session timeout for security (10-15 minutes)
- Limit registrations per IP to prevent spam accounts
- Set strong minimum password requirements (8+ characters, complexity)
- Use MySQL for production (better performance than SQLite)
- Enable brute force protection (max 3-5 login attempts)
- Test with concurrent logins to ensure no race conditions
- Monitor authentication logs for suspicious activity
Conclusion
Authentication is your server's front door—if it's weak, nothing else matters. Whether using online mode, offline mode with AuthMe, or hybrid systems like FastLogin, thorough testing ensures your authentication actually protects your players.
Key takeaways:
- Never use offline mode without authentication plugin on public servers
- Test all flows: registration, login, password change, recovery
- Load test authentication to ensure it handles peak player counts
- Security test for vulnerabilities like SQL injection and timing attacks
- Use bots for comprehensive, repeatable testing at scale
With proper configuration and testing, your authentication system will protect player accounts while providing a smooth login experience. Players trust you with their progress, inventories, and permissions—don't let them down with weak authentication.
Remember: An untested authentication system is an insecure authentication system.