This Google Authenticator plugin implements multiple layers of security to protect your WordPress/ClassicPress installation:
Feature: Secret key generation uses PHP's random_int() function.
Why: The random_int() function provides cryptographically secure pseudo-random integers (CSPRNG), ensuring that generated 2FA secrets cannot be predicted or brute-forced.
Location: create_secret() function
Feature: OTP verification uses constant-time comparison via hash_equals().
Why: Direct comparison of OTP codes can leak information through timing differences, allowing attackers to potentially guess valid codes. The hash_equals() function prevents this by taking the same amount of time regardless of where strings differ.
Location: verify() function
Feature: Maximum of 5 failed authentication attempts per 15 minutes per user.
Why: Prevents brute-force attacks on OTP codes by limiting the number of attempts an attacker can make.
Implementation:
- Failed attempts are tracked using WordPress transients
- Counter resets automatically after 15 minutes
- Counter is cleared immediately upon successful authentication
Location: check_otp() function
Feature: AJAX secret generation requires the read capability.
Why: Prevents unauthorized users from generating or regenerating 2FA secrets for other accounts.
Location: ajax_callback() function
Feature: Proper bounds checking in Base32 decoder without error suppression.
Why: Error suppression operators (@) can hide security vulnerabilities. Explicit bounds checking ensures all edge cases are handled securely.
Location: base32.php decode() function
Feature: All user inputs are sanitized using WordPress sanitization functions.
Why: Prevents XSS and injection attacks by ensuring all data is properly escaped and validated.
Location: Throughout the plugin
✅ Brute Force Attacks - Rate limiting prevents automated guessing of OTP codes
✅ Timing Attacks - Constant-time comparison prevents information leakage
✅ Predictable Secrets - Cryptographically secure random generation
✅ Unauthorized Access - Capability checks on sensitive operations
✅ Replay Attacks - Time-slot tracking prevents OTP code reuse
✅ Man-in-the-Middle Attacks - Time-slot validation detects repeated logins
Wait Period: 15 minutes
Manual Reset:
DELETE FROM wp_options WHERE option_name LIKE '%ga_login_attempts_%';Option 1: Administrator Disable
- WordPress Admin → Users → Edit User
- Uncheck "Active" under Google Authenticator Settings
- User can log in with password only
Option 2: Database Reset
UPDATE wp_usermeta
SET meta_value = 'disabled'
WHERE meta_key = 'googleauthenticator_enabled'
AND user_id = [USER_ID];Option 3: Plugin Deactivation
- Via WP Admin: Plugins → Deactivate Google Authenticator
- Via FTP/SSH: Rename plugin directory or delete it
If you're completely locked out:
-
Via FTP/SSH: Delete the plugin directory
rm -rf wp-content/plugins/google-authenticator/
-
Via Database: Disable for all users
UPDATE wp_usermeta SET meta_value = 'disabled' WHERE meta_key = 'googleauthenticator_enabled';
When setting up 2FA:
- ✅ Write down the secret code displayed on screen
- ✅ Take a screenshot of the QR code (store securely)
- ✅ Test OTP generation before logging out
- ✅ Keep recovery access (don't enable 2FA on your only admin account first)
- Android: Authenticator Plus - Supports backup/restore
- iOS: Authy - Multi-device synchronization
- Desktop: Authy Desktop - Backup across devices
- Max Attempts: 5 failures
- Time Window: 15 minutes
- Scope: Per user account
- Storage: WordPress transients (wp_options table)
ga_login_attempts_[USER_ID]
DELETE FROM wp_options
WHERE option_name = 'ga_login_attempts_[USER_ID]';When two-screen authentication is enabled:
- Credentials are NOT stored in hidden form fields
- Session-based storage is used instead
- Session data is cleared immediately after successful authentication
Session variables used:
$_SESSION['ga_pending_user']- Username$_SESSION['ga_pending_pass']- Password (hashed)$_SESSION['ga_pending_remember']- Remember me preference$_SESSION['ga_pending_redirect']- Redirect destination
Note: Session data is automatically cleared on successful login or session timeout.
If you discover a security vulnerability:
- DO NOT create a public GitHub issue
- Email: security@[your-domain] (if available)
- Subject: "Google Authenticator Security Issue"
- Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
- Acknowledgment: Within 48 hours
- Initial Assessment: Within 7 days
- Fix Timeline: Depends on severity (critical issues prioritized)
This plugin follows semantic versioning with security considerations:
- Major versions (X.0.0): Breaking changes
- Minor versions (0.X.0): New features
- Patch versions (0.0.X): Bug fixes and security updates
Subscribe to updates:
- GitHub: Watch the repository for releases
- WordPress.org: Plugin update notifications
- ✅ Follows OWASP secure coding practices
- ✅ Compatible with PHP 8.0, 8.1, 8.2, 8.3, 8.4
- ✅ Tested with WordPress 6.7 and ClassicPress
- ✅ Implements TOTP (RFC 6238)
- ✅ Uses HMAC-SHA1 (RFC 2104)
- ✅ Implemented cryptographically secure random number generation
- ✅ Added constant-time comparison for OTP verification
- ✅ Implemented rate limiting (5 attempts/15 min)
- ✅ Added capability checks to AJAX handlers
- ✅ Removed error suppression with proper bounds checking
- ✅ Enhanced input sanitization
- PHP 8.4 compatibility
- Type safety improvements
- Strict type declarations
- Test on non-admin account first
- Keep emergency access (another admin without 2FA)
- Regular security audits of active 2FA users
- Monitor failed login attempts
- Keep plugin updated
- Secure your mobile device with a PIN/biometric lock
- Back up your secret key in a secure location
- Use a reputable authenticator app
- Don't share OTP codes with anyone
- Report suspicious activity immediately
This security documentation is licensed under CC BY-NC-ND 4.0
Last Updated: November 2025 Plugin Version: 0.55 Maintainer: Ojārs Kapteinis