The OpenConnector User API implements comprehensive security measures to protect against various attack vectors including Cross-Site Scripting (XSS) attacks and brute force login attempts.
Our security implementation includes multiple layers of protection:
- Input Validation & Sanitization
- Rate Limiting & Brute Force Protection
- Security Headers
- Session Management
- Logging & Monitoring
All user inputs are automatically sanitized through our SecurityService:
// Automatic sanitization of all inputs
$sanitizedData = $this->securityService->sanitizeInput($data);Features:
- HTML entity encoding to prevent script injection
- Removal of dangerous patterns (script tags, event handlers)
- Null byte filtering
- Length limiting to prevent DoS attacks
Every API response includes security headers:
X-Frame-Options: DENY- Prevents clickjackingX-Content-Type-Options: nosniff- Prevents MIME sniffingX-XSS-Protection: 1; mode=block- Browser XSS protectionContent-Security-Policy- Restricts resource loadingReferrer-Policy- Controls referrer information
Login credentials undergo strict validation:
// Username validation
- Minimum 2 characters
- No dangerous characters (<, >, ', ', /, \)
- Maximum length limits
- Character encoding validation
// Password validation
- Maximum length limits (prevents DoS)
- No HTML encoding (preserves actual password)The system implements sophisticated rate limiting:
- Limit: 5 failed attempts per 15-minute window
- Action: Progressive delays then account lockout
- Duration: 1 hour lockout after threshold
- Limit: 5 failed attempts per 15-minute window
- Action: IP address blocking
- Duration: 1 hour lockout after threshold
- Base Delay: 2 seconds
- Escalation: Exponential backoff (2s → 4s → 8s → 16s → 32s → 60s max)
- Reset: Successful login clears delays
// Automatic lockout triggers
if ($userAttempts >= 5) {
// Lock account for 1 hour
$lockoutUntil = time() + 3600;
$this->cache->set($userLockoutKey, $lockoutUntil, 3600);
}- Tracks failed attempts per IP address
- Blocks suspicious IP addresses automatically
- Considers proxy headers (X-Forwarded-For, etc.)
- Validates IP formats to prevent spoofing
All security events are logged with contextual information:
failed_login_attempt- Invalid credentialsrate_limit_exceeded- Too many attemptsuser_locked_out- Account temporarily disabledip_locked_out- IP address blockedsuccessful_login- Authentication succeededlogin_attempt_during_lockout- Attempt during lockout period
{
'event': 'failed_login_attempt',
'username': 'sanitized_username',
'ip_address': '192.168.1.1',
'reason': 'invalid_credentials',
'user_attempts': 3,
'ip_attempts': 2,
'timestamp': '2024-01-15 14:30:22'
}The SecurityService class provides:
// Rate limiting check
$rateLimitCheck = $this->securityService->checkLoginRateLimit($username, $clientIp);
// Input sanitization
$sanitizedInput = $this->securityService->sanitizeInput($input);
// Credential validation
$validation = $this->securityService->validateLoginCredentials($credentials);
// Security headers
$response = $this->securityService->addSecurityHeaders($response);
// IP address detection
$clientIp = $this->securityService->getClientIpAddress($request);Security data is stored using NextCloud's distributed cache:
- Storage: Redis/Memcached (configurable)
- Persistence: Automatic expiration
- Scalability: Works across multiple servers
- Performance: Fast read/write operations
400 Bad Request- Invalid input or missing credentials401 Unauthorized- Authentication failed429 Too Many Requests- Rate limit exceeded403 Forbidden- Account disabled or insufficient permissions
Rate Limited:
{
'error': 'Too many login attempts. Please wait before trying again.',
'retry_after': 8,
'lockout_until': null
}Account Locked:
{
'error': 'Account temporarily locked due to too many failed login attempts',
'retry_after': null,
'lockout_until': 1705334622
}Successful Login:
{
'message': 'Login successful',
'user': { /* user data */ },
'session_created': true
}You can adjust these constants in SecurityService.php:
private const RATE_LIMIT_ATTEMPTS = 5; // Max attempts per window
private const RATE_LIMIT_WINDOW = 900; // 15 minutes in seconds
private const LOCKOUT_DURATION = 3600; // 1 hour in seconds
private const PROGRESSIVE_DELAY_BASE = 2; // Base delay in seconds
private const MAX_PROGRESSIVE_DELAY = 60; // Maximum delay in secondsCustomize security headers in the addSecurityHeaders() method:
// Content Security Policy
$response->addHeader('Content-Security-Policy', "default-src 'none'; frame-ancestors 'none';");
// Cache Control
$response->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, private');// ✅ Correct - Use SecurityService
$response = $this->securityService->addSecurityHeaders($response);
// ❌ Incorrect - Direct response
return new JSONResponse($data);// ✅ Correct - Sanitize inputs
$sanitizedData = $this->securityService->sanitizeInput($data);
// ❌ Incorrect - Direct usage
$username = $_POST['username']; // Never do this// ✅ Correct - Validate first
$validation = $this->securityService->validateLoginCredentials($credentials);
if (!$validation['valid']) {
return error_response($validation['error']);
}
// ❌ Incorrect - Process without validation
$user = $this->userManager->checkPassword($username, $password);All authentication attempts should be logged for monitoring and analysis.
Avoid revealing system information:
// ✅ Correct - Generic message
return new JSONResponse(['error' => 'Invalid username or password']);
// ❌ Incorrect - Reveals information
return new JSONResponse(['error' => 'User john.doe does not exist']);- Failed Login Rate - Sudden spikes may indicate attacks
- Lockout Events - High frequency suggests ongoing attacks
- IP Blocking - Geographic patterns may reveal bot networks
- Response Times - Delays may indicate DoS attempts
Search for security events in logs:
# Find failed login attempts
grep 'failed_login_attempt' /var/log/nextcloud.log
# Find rate limit exceeded events
grep 'rate_limit_exceeded' /var/log/nextcloud.log
# Find lockout events
grep 'locked_out' /var/log/nextcloud.logEnsure all API endpoints are served over HTTPS to prevent credential interception.
Keep NextCloud and all dependencies updated to the latest versions.
Implement password complexity requirements at the application level.
Consider implementing 2FA for additional security layers.
Perform regular penetration testing and security audits.
Consider using a WAF for additional protection against common attacks.
The OpenConnector User API implements industry-standard security practices to protect against both XSS attacks and brute force attempts. The multi-layered approach ensures comprehensive protection while maintaining usability for legitimate users.
For any security concerns or questions, please refer to the code documentation or contact the development team.