Security Checklist
Essential security measures for Multi Host deployments covering file upload validation, access control, server hardening, and ongoing security practices.
File hosting services face significant security challenges. This checklist covers essential protections for production deployments, organised from critical basics through defence-in-depth measures.
Critical: File Upload Security
File uploads represent the primary attack vector for hosting services. Attackers attempt to upload executable content, malformed files that exploit processing libraries, and content that violates legal or policy requirements.
Validate File Types Rigorously
Never trust user-provided file extensions or Content-Type headers:
$config['allowed_extensions'] = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
$config['allowed_mimetypes'] = [
'image/jpeg',
'image/png',
'image/gif',
'image/webp'
];
$config['validate_file_content'] = true;
Content validation examines actual file bytes, not just metadata. The fileinfo PHP extension provides reliable MIME detection. For images, verify files parse correctly with image libraries before accepting them.
Store Uploads Safely
Prevent uploaded files from executing as code:
- Store outside document root when possible
- Use non-executable file extensions in storage
- Configure web server to serve uploads as static content only
- Remove execution permissions from upload directories
Apache configuration:
<Directory /var/www/storage>
Options -Indexes -ExecCGI
AllowOverride None
# Force downloads or specify content types
<FilesMatch "\.ph(p|tml|ar)$">
Require all denied
</FilesMatch>
# Disable PHP execution
php_flag engine off
</Directory>
Nginx configuration:
location /storage {
location ~ \.php$ {
deny all;
}
}
Sanitise Filenames
User-provided filenames can contain path traversal attempts, special characters, or excessive length:
$config['filename_strategy'] = 'random'; // Safest option
$config['filename_length'] = 12;
$config['filename_charset'] = 'alphanumeric';
Random filenames eliminate filename-based attacks entirely. If preserving original names, sanitise aggressively:
- Remove path separators (
/,\) - Replace or remove special characters
- Limit length to prevent filesystem issues
- Convert to consistent case
Process Images Carefully
Image processing libraries have vulnerabilities. Protect against exploitation:
$config['reprocess_images'] = true; // Re-encode all uploads
$config['strip_metadata'] = true; // Remove EXIF, IPTC, etc.
$config['max_image_dimensions'] = 10000; // Prevent decompression bombs
Re-encoding forces images through your processing library, stripping potential payloads embedded in image data. This adds processing overhead but significantly reduces risk.
Metadata stripping removes location data, camera information, and embedded thumbnails that could contain malicious content or expose user privacy.
Critical: Access Control
Protect Administrative Functions
Administrative interfaces require strong protection:
$config['admin_path'] = '/manage-xyz123/'; // Non-obvious path
$config['admin_ip_whitelist'] = ['192.168.1.0/24']; // Restrict by IP
$config['admin_2fa_required'] = true;
Consider separate domains or subdomains for administrative access, making it harder for attackers to discover admin endpoints.
Implement Session Security
$config['session_lifetime'] = 3600; // 1 hour
$config['session_regenerate'] = true; // Regenerate ID on auth
PHP session configuration:
ini_set('session.cookie_secure', '1'); // HTTPS only
ini_set('session.cookie_httponly', '1'); // No JavaScript access
ini_set('session.cookie_samesite', 'Strict');
ini_set('session.use_strict_mode', '1');
Enforce Authentication Properly
Protect authentication endpoints from abuse:
$config['login_attempts'] = 5;
$config['lockout_duration'] = 900; // 15 minutes
$config['password_min_length'] = 10;
$config['password_require_complexity'] = true;
Log authentication failures for security monitoring. Implement account lockout carefully to prevent denial-of-service through intentional lockouts.
Essential: Server Hardening
Enable HTTPS Everywhere
$config['force_https'] = true;
HTTPS protects data in transit and enables security headers. Obtain certificates through Let's Encrypt or your hosting provider.
Configure HTTP Strict Transport Security (HSTS):
Strict-Transport-Security: max-age=31536000; includeSubDomains
Configure Security Headers
Add protective headers to all responses. Content Security Policy (CSP) prevents cross-site scripting and injection attacks:
Content-Security-Policy: default-src 'self'; img-src 'self' data: https:; script-src 'self'; style-src 'self' 'unsafe-inline'
Additional headers:
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()
Minimise Information Exposure
$config['debug'] = false;
$config['display_errors'] = false;
PHP configuration:
expose_php = Off
display_errors = Off
log_errors = On
Remove version information from server headers. Error messages should be generic to users while detailed logging captures information for administrators.
Defence in Depth
Implement Rate Limiting
Protect against abuse and denial-of-service:
$config['rate_limit_enabled'] = true;
$config['rate_limit_uploads'] = 10; // per minute
$config['rate_limit_api'] = 60;
$config['rate_limit_login'] = 5;
Apply limits per user and per IP address. Consider geographic and network-based limits for additional protection.
The Rate Limiting and Abuse Control guide covers implementation details.
Enable Comprehensive Logging
$config['log_uploads'] = true;
$config['log_authentication'] = true;
$config['log_admin_actions'] = true;
$config['log_retention'] = 90; // days
Logs enable incident investigation and pattern detection. Store logs securely and review regularly for anomalies.
Monitor for Anomalies
Watch for indicators of attack or abuse:
- Spike in failed authentications
- Unusual upload patterns (size, frequency, types)
- Access from unexpected geographic locations
- Requests for non-existent files (enumeration attempts)
Automated alerting helps catch problems before they escalate.
Plan for Incidents
Prepare incident response procedures:
- Detection: How will you know something is wrong?
- Containment: How do you limit damage quickly?
- Investigation: What information do you need?
- Recovery: How do you restore normal operation?
- Lessons: How do you prevent recurrence?
Document procedures and practice them before incidents occur.
Ongoing Security Practices
Keep Software Updated
- Update PHP to current stable versions
- Apply CMS/application patches promptly
- Monitor for vulnerabilities in dependencies
- Test updates in staging before production
Review Access Regularly
- Audit administrator accounts periodically
- Remove access for departed team members
- Review API keys and integration credentials
- Check for unused or overprivileged accounts
Backup Securely
- Encrypt backup storage
- Store backups separately from production
- Test restoration procedures
- Retain backups according to policy
Security Testing
- Run vulnerability scanners periodically
- Test upload validation with malformed files
- Verify access controls function correctly
- Consider professional penetration testing
Frequently Asked Questions
File upload validation prevents the most dangerous attacks. Ensure uploads are validated at multiple levels: extension, MIME type, file content, and image parsing. Store uploads where they cannot execute.