Security Considerations #

Comprehensive security guide for Server Monitor plugin deployment, covering authentication, data protection, and best practices.

Security Architecture #

Multi-Layered Security #

The Server Monitor plugin implements security at multiple levels:

  • Application Layer - Authentication, authorization, input validation
  • Database Layer - Organization isolation, encrypted data
  • Network Layer - API key protection, HTTPS enforcement
  • Infrastructure Layer - Server hardening, access controls

Threat Model #

Protected Assets:

  • Server endpoint URLs (may reveal infrastructure)
  • User contact information (email, phone)
  • Organization data and relationships
  • Monitoring status and uptime data
  • Communication logs and costs

Threat Vectors:

  • Unauthorized access to monitoring data
  • Cross-organization data leakage
  • API key compromise
  • Injection attacks via server endpoints
  • Social engineering for notification access

Authentication and Authorization #

User Authentication #

SaasBase Integration:

// Authentication handled by SaasBase
$user = BackendAuth::getUser();
if (!$user) {
    return Redirect::to('backend/auth/signin');
}

Multi-Factor Authentication:

  • Inherits MFA settings from SaasBase
  • Organization admins should enable MFA
  • Consider mandatory MFA for organizations with sensitive infrastructure

Authorization Controls #

Organization-Based Access:

// Users can only access their organization's data
public $implement = ['@'.\Albrightlabs\SaasBase\Behaviors\OwnableBehavior::class];

// Automatic scoping applied to all queries
$servers = Server::all(); // Only returns current user's organization servers

Role-Based Permissions:

// Organization admin check
if (!$user->is_organization_admin && !str_contains($user->email, '@albrightlabs.com')) {
    Flash::error('Access denied. You must be an organization administrator.');
    return Redirect::to('backend');
}

API Access Control:

// API key validation
$validApiKey = Config::get('albrightlabs.servermonitor::config.api_key');
if (!$validApiKey || $api_key !== $validApiKey) {
    return response()->json(['success' => false, 'message' => 'Invalid API key'], 403);
}

Data Protection #

Data Encryption #

In Transit:

  • All API communications over HTTPS
  • Email notifications via encrypted SMTP
  • Database connections with SSL/TLS

At Rest:

  • Database encryption for sensitive fields
  • API keys stored in environment variables
  • Log files with restricted permissions

Implementation:

# Force HTTPS in production
APP_ENV=production
APP_DEBUG=false
FORCE_HTTPS=true

# Database encryption
DB_SSL_MODE=require
DB_SSL_CERT=/path/to/client-cert.pem
DB_SSL_KEY=/path/to/client-key.pem
DB_SSL_CA=/path/to/ca-cert.pem

Data Minimization #

Principle of Least Data:

// Only collect necessary information
$server = new Server();
$server->title = $input['title'];          // Required for identification
$server->endpoint = $input['endpoint'];    // Required for monitoring
// No collection of additional metadata unless necessary

Automatic Data Purging:

// Plan-based log retention
'plans' => [
    'free' => ['log_retention_days' => 7],
    'basic' => ['log_retention_days' => 30],
    'pro' => ['log_retention_days' => 90],
    'enterprise' => ['log_retention_days' => 90],
]

Personal Data Handling #

PII Protection:

  • Email addresses encrypted in notifications settings
  • Phone numbers hashed when not in use
  • Communication logs anonymized after retention period

GDPR Compliance Considerations:

// Right to erasure implementation
public function deleteUserData($userId)
{
    // Remove user from notification settings
    $settings = NotificationSetting::all();
    foreach ($settings as $setting) {
        $admins = $setting->administrators;
        $admins = array_filter($admins, function($admin) use ($userId) {
            return $admin['user_id'] !== $userId;
        });
        $setting->administrators = $admins;
        $setting->save();
    }

    // Anonymize communication logs
    AlertLog::where('recipient', 'LIKE', "%{$userEmail}%")
        ->update(['recipient' => 'ANONYMIZED']);
}

API Security #

API Key Management #

Strong Key Generation:

# Generate cryptographically secure API key
openssl rand -base64 32

# Or using PHP
php -r "echo base64_encode(random_bytes(32));"

Key Rotation:

#!/bin/bash
# rotate-api-key.sh - Run monthly

OLD_KEY=$(grep SERVER_MONITOR_API_KEY .env | cut -d'=' -f2)
NEW_KEY=$(openssl rand -base64 32)

# Update environment
sed -i "s/SERVER_MONITOR_API_KEY=$OLD_KEY/SERVER_MONITOR_API_KEY=$NEW_KEY/" .env

# Update cron jobs
crontab -l | sed "s/$OLD_KEY/$NEW_KEY/g" | crontab -

# Restart application
php artisan config:clear
supervisorctl restart servermonitor-*:*

echo "API key rotated from $OLD_KEY to $NEW_KEY"

Key Storage Security:

# Secure .env file permissions
chmod 600 .env
chown www-data:www-data .env

# Prevent web access to .env
# Add to .htaccess or nginx config:
# location ~ /\.env {
#     deny all;
# }

Rate Limiting #

API Rate Limiting:

// Implement rate limiting for API endpoints
Route::middleware(['throttle:60,1'])->group(function () {
    Route::get('/api/servermonitor/check/{type}/{api_key}', function ($type, $api_key) {
        // API endpoint logic
    });
});

Nginx Rate Limiting:

# Limit API requests
location /api/servermonitor/ {
    limit_req zone=api burst=10 nodelay;
    limit_req_status 429;

    # Continue to PHP processing
    try_files $uri $uri/ /index.php?$query_string;
}

# Define rate limit zone
http {
    limit_req_zone $binary_remote_addr zone=api:10m rate=30r/m;
}

IP Whitelisting #

Restrict API Access:

# Allow only specific IPs for API access
location /api/servermonitor/ {
    allow 192.168.1.0/24;    # Internal network
    allow 10.0.0.0/8;        # Private networks
    allow 203.0.113.0/24;    # Your office network
    deny all;

    try_files $uri $uri/ /index.php?$query_string;
}

Environment-Based Restrictions:

// IP whitelist in environment
$allowedIps = explode(',', env('API_ALLOWED_IPS', ''));
$clientIp = request()->ip();

if (!empty($allowedIps) && !in_array($clientIp, $allowedIps)) {
    return response()->json(['error' => 'IP not allowed'], 403);
}

Input Validation and Sanitization #

Server Endpoint Validation #

URL Validation:

// Strict URL validation for server endpoints
public $rules = [
    'title' => 'required|string|max:255',
    'endpoint' => 'required|url|regex:/^https?:\/\//'
];

// Additional security validation
public function beforeSave()
{
    // Prevent monitoring internal/private networks
    $url = parse_url($this->endpoint);
    $host = $url['host'];

    // Block private networks
    if (filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) {
        throw new ValidationException(['endpoint' => 'Cannot monitor private or reserved IP addresses']);
    }

    // Block common internal hostnames
    $blockedHosts = ['localhost', '127.0.0.1', '0.0.0.0', 'metadata.google.internal'];
    if (in_array(strtolower($host), $blockedHosts)) {
        throw new ValidationException(['endpoint' => 'Cannot monitor internal hostnames']);
    }
}

Communication Data Sanitization #

Email Content Sanitization:

// Sanitize notification content
$content = strip_tags($server->title . ': ' . $log->note);
$content = substr($content, 0, 160); // SMS length limit

// Validate email addresses
if (!filter_var($admin->email, FILTER_VALIDATE_EMAIL)) {
    Log::warning("Invalid email address for user {$admin->id}: {$admin->email}");
    continue;
}

Phone Number Validation:

// Validate and normalize phone numbers
$phoneNumber = preg_replace('/[^0-9]/', '', $admin->phone_number);
if (!preg_match('/^1?[0-9]{10}$/', $phoneNumber)) {
    Log::warning("Invalid phone number for user {$admin->id}");
    continue;
}

Infrastructure Security #

Server Hardening #

Operating System Security:

# Update system packages
sudo apt update && sudo apt upgrade -y

# Configure firewall
sudo ufw enable
sudo ufw allow 22/tcp    # SSH
sudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS
sudo ufw deny 3306/tcp   # Block direct database access

# Disable unnecessary services
sudo systemctl disable apache2  # If using nginx
sudo systemctl disable sendmail # If using different mailer

Web Server Security:

# Nginx security headers
server {
    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval'" always;

    # Hide server version
    server_tokens off;

    # Prevent access to sensitive files
    location ~ /\.(env|git|svn) {
        deny all;
        return 404;
    }

    location ~ /(config|storage|bootstrap|vendor) {
        deny all;
        return 404;
    }
}

Database Security #

Database Hardening:

-- Create dedicated database user
CREATE USER 'servermonitor'@'localhost' IDENTIFIED BY 'strong_random_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON servermonitor.* TO 'servermonitor'@'localhost';
FLUSH PRIVILEGES;

-- Remove default users
DROP USER ''@'localhost';
DROP USER ''@'hostname';
DROP USER 'root'@'hostname';

-- Secure root account
UPDATE mysql.user SET Password=PASSWORD('very_strong_root_password') WHERE User='root';
FLUSH PRIVILEGES;

Connection Security:

# Use SSL for database connections
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=servermonitor
DB_USERNAME=servermonitor
DB_PASSWORD=strong_random_password
DB_SSL_MODE=required

Monitoring and Logging #

Security Event Logging #

Authentication Events:

// Log authentication attempts
Event::listen('auth.login', function ($user) {
    Log::info("User login: {$user->email} from " . request()->ip());
});

Event::listen('auth.failed', function ($credentials) {
    Log::warning("Failed login attempt: {$credentials['email']} from " . request()->ip());
});

API Access Logging:

// Log all API access attempts
Route::middleware('log.api')->group(function () {
    // API routes
});

// Middleware implementation
class LogApiAccess
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        Log::info('API Access', [
            'endpoint' => $request->path(),
            'ip' => $request->ip(),
            'user_agent' => $request->userAgent(),
            'status' => $response->status(),
        ]);

        return $response;
    }
}

Intrusion Detection #

Suspicious Activity Detection:

#!/bin/bash
# security-monitor.sh - Run every 5 minutes

# Check for repeated failed logins
FAILED_LOGINS=$(grep "Failed login attempt" storage/logs/laravel.log | grep "$(date '+%Y-%m-%d %H:%M')" | wc -l)
if [ $FAILED_LOGINS -gt 10 ]; then
    echo "ALERT: $FAILED_LOGINS failed login attempts in last minute" | mail -s "Security Alert" security@yourcompany.com
fi

# Check for API abuse
API_ERRORS=$(grep "Invalid API key" storage/logs/laravel.log | grep "$(date '+%Y-%m-%d %H:%M')" | wc -l)
if [ $API_ERRORS -gt 5 ]; then
    echo "ALERT: $API_ERRORS invalid API key attempts in last minute" | mail -s "API Security Alert" security@yourcompany.com
fi

Log Analysis:

# Daily security log analysis
#!/bin/bash
# analyze-security-logs.sh

echo "Security Log Analysis for $(date)"
echo "================================="

# Failed authentication attempts
echo "Failed Login Attempts:"
grep "Failed login attempt" storage/logs/laravel.log | tail -10

# API key violations
echo -e "\nAPI Key Violations:"
grep "Invalid API key" storage/logs/laravel.log | tail -10

# Suspicious endpoints
echo -e "\nSuspicious Endpoint Access:"
grep -E "(\.env|config|admin|phpmyadmin)" /var/log/nginx/access.log | tail -10

Incident Response #

Security Incident Procedures #

Immediate Response:

  1. Isolate - Block suspicious IP addresses
  2. Assess - Determine scope of potential breach
  3. Contain - Disable compromised accounts/API keys
  4. Investigate - Review logs and system integrity
  5. Notify - Alert relevant stakeholders
  6. Recover - Restore services with enhanced security

API Key Compromise Response:

#!/bin/bash
# emergency-api-rotation.sh

echo "EMERGENCY: Rotating all API keys"

# Generate new API key
NEW_KEY=$(openssl rand -base64 32)

# Update environment
cp .env .env.backup.$(date +%Y%m%d_%H%M%S)
sed -i "s/SERVER_MONITOR_API_KEY=.*/SERVER_MONITOR_API_KEY=$NEW_KEY/" .env

# Clear application cache
php artisan config:clear

# Restart services
supervisorctl restart servermonitor-*:*

# Update monitoring systems with new key
echo "NEW API KEY: $NEW_KEY"
echo "UPDATE ALL MONITORING SYSTEMS IMMEDIATELY"

# Log incident
echo "$(date): Emergency API key rotation - Key compromised" >> security-incidents.log

Data Breach Response #

Assessment Checklist:

  • [ ] Identify compromised data types
  • [ ] Determine number of affected organizations
  • [ ] Check for cross-organization data exposure
  • [ ] Verify integrity of monitoring data
  • [ ] Assess notification system compromise

Communication Template:

Subject: Security Incident Notification

We are writing to inform you of a security incident that may have affected your monitoring data.

INCIDENT DETAILS:
- Date/Time: [TIMESTAMP]
- Nature: [BRIEF DESCRIPTION]
- Data Affected: [SPECIFIC DATA TYPES]
- Organizations Affected: [NUMBER]

IMMEDIATE ACTIONS TAKEN:
- [LIST CONTAINMENT MEASURES]
- [LIST SECURITY ENHANCEMENTS]

RECOMMENDED USER ACTIONS:
- Review monitoring configurations
- Update passwords if applicable
- Monitor for suspicious activity

We take security seriously and are committed to protecting your data.

Contact: security@yourcompany.com

Compliance and Auditing #

Audit Trail #

Database Auditing:

-- Create audit trail for sensitive operations
CREATE TABLE audit_log (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT,
    action VARCHAR(100),
    table_name VARCHAR(100),
    record_id INT,
    old_values JSON,
    new_values JSON,
    ip_address VARCHAR(45),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Application Auditing:

// Audit critical operations
class AuditLogger
{
    public static function log($action, $model, $oldValues = null, $newValues = null)
    {
        DB::table('audit_log')->insert([
            'user_id' => BackendAuth::getUser()->id ?? null,
            'action' => $action,
            'table_name' => $model->getTable(),
            'record_id' => $model->id,
            'old_values' => json_encode($oldValues),
            'new_values' => json_encode($newValues),
            'ip_address' => request()->ip(),
            'created_at' => now(),
        ]);
    }
}

// Usage in models
public function afterUpdate()
{
    AuditLogger::log('update', $this, $this->original, $this->attributes);
}

Compliance Frameworks #

SOC 2 Considerations:

  • Implement access controls and authentication
  • Maintain audit logs for all data access
  • Encrypt data in transit and at rest
  • Regular vulnerability assessments
  • Incident response procedures

GDPR Compliance:

  • Data minimization practices
  • Right to erasure implementation
  • Consent management for communications
  • Data processing agreements with subprocessors
  • Privacy by design principles

HIPAA Considerations (if monitoring healthcare systems):

  • Enhanced access controls
  • Additional encryption requirements
  • Business associate agreements
  • Audit log retention requirements

Security Testing #

Penetration Testing #

Regular Security Assessments:

# Automated security scanning
#!/bin/bash
# security-scan.sh

# SQL injection testing
sqlmap -u "https://yoursite.com/api/servermonitor/check/premium/test" --batch --level=1

# XSS testing
xsshunter --url "https://yoursite.com"

# SSL/TLS testing
sslscan yoursite.com

# Port scanning
nmap -sS -O yoursite.com

Code Security Review:

# PHP security analysis
./vendor/bin/psalm --security-analysis

# Dependency vulnerability scanning
composer audit

# OWASP dependency checking
dependency-check.sh --project servermonitor --scan ./

Regular Security Maintenance #

Monthly Security Tasks:

  • [ ] Rotate API keys
  • [ ] Review user access permissions
  • [ ] Update system packages
  • [ ] Scan for vulnerabilities
  • [ ] Review security logs
  • [ ] Test backup/restore procedures

Quarterly Security Tasks:

  • [ ] Penetration testing
  • [ ] Security policy review
  • [ ] Incident response plan testing
  • [ ] Security awareness training
  • [ ] Third-party security assessment

Previous: ← SaasBase Integration | Next: Legal Pages →