A comprehensive guide to secure your Laravel application against common attacks and vulnerabilities.
- Nginx Configuration
- File Permissions
- Laravel Security Settings
- Server Hardening
- Monitoring & Maintenance
- Security Checklist
Edit /etc/nginx/nginx.conf
:
http {
# ... existing settings ...
# Rate limiting
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;
# Security settings
server_tokens off;
client_max_body_size 10M;
client_body_buffer_size 128k;
# ... rest of settings ...
}
Test and reload Nginx to apply the changes:
# test the configuration first
sudo nginx -t
# Reload nginx
sudo systemctl reload nginx
- Site Configuration
Create
/etc/nginx/sites-available/your-site.conf
:
server {
listen 443 ssl http2;
server_name your-domain.com;
root /var/www/your-domain.com/public;
index index.php index.html;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Please make sure that the following rules are not duplicated
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
# 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' http: https: data: blob: 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Logs
access_log /var/log/nginx/your-domain.com-access.log;
error_log /var/log/nginx/your-domain.com-error.log;
# Rate Limiting
location / {
limit_req zone=mylimit burst=10 nodelay;
try_files $uri $uri/ /index.php?$query_string;
}
# Block Sensitive Files
location ~ /\. { deny all; }
location ~ ^/(app|bootstrap|config|database|resources|routes|storage|tests|vendor)/ { deny all; }
location ~ \.(env|log|lock|json|yml|yaml|config|bak|git|svn|txt|md|sql)$ { deny all; }
# Protect Upload Directories
location ~ ^/uploads/.*\.php$ { deny all; }
# PHP-FPM Configuration
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_intercept_errors on;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
}
# Static Files Cache
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
}
# HTTP to HTTPS Redirect
server {
listen 80;
server_name your-domain.com www.your-domain.com;
return 301 https://$server_name$request_uri;
}
File Permissions
- Set Ownership
# Set proper ownership
sudo chown -R www-data:www-data /var/www/your-domain.com
# Set proper permissions
find /var/www/your-domain.com -type f -exec chmod 644 {} \;
find /var/www/your-domain.com -type d -exec chmod 755 {} \;
# Set specific permissions for sensitive directories
chmod 750 storage
chmod -R 750 storage/framework
chmod -R 750 storage/logs
chmod -R 750 bootstrap/cache
Laravel Security Settings
- Environment File
APP_ENV=production
APP_DEBUG=false
APP_URL=https://your-domain.com
SESSION_SECURE_COOKIE=true
SESSION_COOKIE_HTTPONLY=true
SESSION_DOMAIN=your-domain.com
SANCTUM_STATEFUL_DOMAINS=your-domain.com
- Security Middleware Add to app/Http/Kernel.php:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\VerifyCsrfToken::class,
\App\Http\Middleware\EncryptCookies::class,
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
],
];
- Config Updates
// config/session.php
'secure' => true,
'http_only' => true,
'same_site' => 'lax',
// config/hashing.php
'driver' => 'bcrypt',
'rounds' => 12,
Server Hardening
- Install Security Tools
# Install security packages
sudo apt update
sudo apt install fail2ban ufw mod-security
# Configure UFW
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 'Nginx Full'
sudo ufw enable
- Create Security Scan Script
#!/bin/bash
# /root/security_scan.sh
# Scan for recently modified files
find /var/www/your-domain.com -type f -mtime -1 -ls > /root/modified_files.log
# Check for files with wrong permissions
find /var/www/your-domain.com -type f -perm /o+w -ls > /root/wrong_permissions.log
# Check for PHP files in upload directories
find /var/www/your-domain.com/public/uploads -name "*.php" -ls > /root/suspicious_uploads.log
# Check for large files that might indicate malware
find /var/www/your-domain.com -type f -size +10M -ls > /root/large_files.log
Add to crontab:
# Make it executable and add to crontab:
chmod +x /root/security_scan.sh
(crontab -l 2>/dev/null; echo "0 */6 * * * /root/security_scan.sh") | crontab -
Monitoring & Maintenance
- Regular Updates
# Update system packages
sudo apt update
sudo apt upgrade
# Update Composer dependencies
composer update --no-dev
- Log Monitoring
# Monitor Laravel logs
tail -f storage/logs/laravel.log
# Monitor Nginx access logs
tail -f /var/log/nginx/access.log
# Monitor Nginx error logs
tail -f /var/log/nginx/error.log
Create cleanup script
#!/bin/bash
echo "Starting security cleanup..."
# Directory containing suspicious files
PROJECT_ROOT="/var/www/yourdomain.com"
cd $PROJECT_ROOT
# 1. Remove suspicious PHP files in various locations
echo "Removing suspicious PHP files..."
suspicious_files=(
"public/.well-known/pki-validation/_manager/Support/ChunkInterface.php"
"public/.well-known/pki-validation/_manager/Support/SOURCE/-/php.ini"
"public/.well-known/pki-validation/_manager/Support/SOURCE/-/source.php"
"public/admin-bar.php"
"public/apply/assets/cc.php"
"public/assets/global/excel/gecko.php"
"public/assets/site/images/en.jpg.php"
"public/php.ini"
"public/storage/index.php"
"public/storage/sitme.xml"
"public/vendor/datatables/ALFA_DATA"
"public/vendor/datatables/server_data.php"
"public/vendor/datatables/style.php"
"public/video/index.php"
"public/video/sitme.xml"
"public/video/wgjc.txt"
"public/workshops/assets/.DS.Prokon.php"
"public/workshops/assets/images/ALFA_DATA"
"public/workshops/assets/images/base.php"
"public/workshops/assets/images/rigen.php"
"public/workshops/assets/vendor/bootstrap/Backup_fil.php"
"bootstrap/app.php.bk"
)
for file in "${suspicious_files[@]}"; do
if [ -e "$file" ]; then
rm -rf "$file"
echo "Removed: $file"
fi
done
# 2. Remove ALFA shell backdoors (common malware)
echo "Removing ALFA shell backdoors..."
find . -type f -name "*.alfa" -delete
find . -type f -name "bash.alfa" -delete
find . -type f -name "perl.alfa" -delete
find . -type f -name "py.alfa" -delete
# 3. Clean uploads directory of PHP files
echo "Cleaning uploads directory..."
find ./public/assets/uploads -type f -name "*.php" -delete
# 4. Remove any hidden PHP files
echo "Removing hidden PHP files..."
find . -type f -name ".*.php" -delete
# 5. Verify and fix permissions
echo "Fixing permissions..."
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
chmod -R 750 storage
chmod -R 750 bootstrap/cache
# 6. Clean git cache
echo "Cleaning git cache..."
git rm -r --cached .
git add .
git commit -m "security: remove malicious files and fix permissions"
echo "Cleanup complete. Please review the following security measures:"
# Output security recommendations
echo "
IMPORTANT NEXT STEPS:
1. Change all passwords immediately
2. Review all database tables for unauthorized changes
3. Check for unauthorized users/admin accounts
4. Update all dependencies
5. Run: composer update --no-dev
6. Check for unauthorized cron jobs: crontab -l
7. Monitor access logs for suspicious activity
8. Consider fresh installation of core files
9. Update Laravel framework
10. Enable file integrity monitoring
"
# Scan for remaining PHP files in suspicious locations
echo "Scanning for remaining suspicious files..."
find ./public -type f -name "*.php" ! -path "./public/index.php" -ls
echo "Please review any remaining PHP files listed above."
Save this as cleanup.sh and run it:
sudo chmod +x cleanup.sh
sudo ./cleanup.sh
After running the cleanup script:
- Change all passwords:
- Database passwords
- Admin user passwords
- API keys
- SSH keys
- Add these rules to your nginx configuration to prevent future uploads:
# Add inside your server block
location ~ /\.well-known/.*\.php$ {
deny all;
}
location ~ /vendor/.*\.php$ {
deny all;
}
location ~ /workshops/.*\.php$ {
deny all;
}
- Monitor your files:
First, create the monitoring script:
sudo nano /root/monitor_files.sh
Add this content:
#!/bin/bash
/usr/bin/inotifywait -m -r /var/www/freeziana.com -e create,modify,delete,move |
while read path action file; do
echo "$(date): $path$file $action" >> /var/log/file_changes.log
if [[ "$file" =~ .*\.php$ ]]; then
echo "PHP file $action: $path$file" | mail -s "Security Alert: PHP File Change" [email protected]
fi
done
Make it executable:
sudo chmod +x /root/monitor_files.sh
Add it to crontab properly:
# Open crontab editor
sudo crontab -e
Add this line to the crontab:
@reboot /root/monitor_files.sh
For immediate monitoring (without waiting for reboot), you can start it as a service:
sudo nano /etc/systemd/system/file-monitor.service
Add this content:
[Unit]
Description=File Monitoring Service
After=network.target
[Service]
Type=simple
ExecStart=/root/monitor_files.sh
Restart=always
[Install]
WantedBy=multi-user.target
Start and enable the service:
sudo systemctl daemon-reload
sudo systemctl enable file-monitor
sudo systemctl start file-monitor
Check the service status:
sudo systemctl status file-monitor
This setup will:
- Monitor your files continuously
- Log changes to /var/log/file_changes.log
- Send email alerts for PHP file changes
- Start automatically on reboot
- Restart if it crashes
Security Checklist:
- ✅ SSL certificate installed and renewed automatically
- ✅ Rate limiting configured in Nginx
- ✅ File permissions properly set
- ✅ Security headers configured
- ✅ Upload directory protected
- ✅ Sensitive files blocked
- ✅ Debug mode disabled
- ✅ Security scan script installed
- ✅ Fail2ban configured
- ✅ UFW firewall enabled
- ✅ Regular updates scheduled
- ✅ Log monitoring in place
- ✅ CSRF protection enabled
- ✅ Session security configured
- ✅ Database credentials secured
- ✅ API endpoints protected
- ✅ Input validation implemented
- ✅ XSS protection enabled
- ✅ SQL injection prevention configured
- ✅ File upload validation implemented
Additional Recommendations
- Use Laravel Sanctum for API authentication
- Implement two-factor authentication
- Use prepared statements for all database queries
- Implement rate limiting on API routes
- Regular security audits
- Keep backups in secure, off-site location
- Use Laravel's built-in XSS protection
- Implement proper password hashing
- Use HTTPS for all requests
- Regular penetration testing
- Emergency Response
- If your site is compromised:
Take the site offline
- Backup all files and logs
- Check file modification timestamps
- Review all PHP files for malicious code
- Check database for unauthorized changes
- Reset all passwords and API keys
- Update all software and dependencies
- Review and strengthen security measures
- Report the incident if required by regulations
- Document the incident and improve security