Initial commit

This commit is contained in:
Ronald Huynen
2026-03-23 21:37:59 +01:00
commit 2547717edb
2193 changed files with 972171 additions and 0 deletions

View File

@@ -0,0 +1,226 @@
# HTMLPurifier Cache Directory Fix
## Problem
When deploying to a server, you may encounter this error:
```
Directory /var/www/timebank_cc_dev/vendor/ezyang/htmlpurifier/library/HTMLPurifier/DefinitionCache/Serializer not writable.
```
This occurs because HTMLPurifier tries to write cache files to its vendor directory, which:
1. Should NOT be writable for security reasons
2. May not have correct permissions on production servers
3. Can be overwritten during `composer install`
## Solution
We've reconfigured HTMLPurifier to use Laravel's cache directory instead.
### Changes Made
1. **Updated `app/Helpers/StringHelper.php`** (Lines 55-63)
- HTMLPurifier now uses `storage/framework/cache/htmlpurifier`
- Auto-creates directory if it doesn't exist
- Works across all environments without manual configuration
2. **Created `deployment-htmlpurifier-fix.sh`**
- Standalone script to set up HTMLPurifier cache directory
- Auto-detects web server user or accepts it as argument
- Gracefully handles permission errors
- Always exits successfully (doesn't break deployment)
3. **Integrated into `deploy.sh`** (Lines 306-316)
- Automatically runs during deployment
- Uses same web user/group as rest of application
- Runs for both local and server environments
## How It Works
### Automatic (via deploy.sh)
When you run `./deploy.sh`, it will automatically:
1. Create `storage/framework/cache/htmlpurifier` directory
2. Set ownership to web server user (www-data, apache, nginx, etc.)
3. Set permissions to 755
4. Verify the directory is writable
### Manual (if needed)
If you need to run the setup separately:
```bash
# Let script auto-detect web server user
./deployment-htmlpurifier-fix.sh
# Or specify web server user
./deployment-htmlpurifier-fix.sh www-data
# Or specify both user and group
./deployment-htmlpurifier-fix.sh www-data www-data
```
### Code-Level (automatic)
The `StringHelper::sanitizeHtml()` method automatically creates the cache directory if it doesn't exist (lines 58-61):
```php
$cacheDir = storage_path('framework/cache/htmlpurifier');
if (!is_dir($cacheDir)) {
mkdir($cacheDir, 0755, true);
}
```
## Deployment Instructions
### First Time Setup (New Servers)
Just run your normal deployment:
```bash
./deploy.sh
```
The HTMLPurifier cache directory will be set up automatically.
### Existing Deployments (Already Running)
If you're updating an existing server that already has the old code deployed:
1. **Pull and deploy the latest code:**
```bash
./deploy.sh
```
2. **The script will automatically:**
- Update code to use new cache location
- Create and configure the cache directory
- Set correct permissions
3. **Verify (optional):**
```bash
ls -la storage/framework/cache/htmlpurifier
```
You should see the directory with correct ownership and permissions.
### If You Still Get Errors
If you encounter permission errors after deployment:
1. **Manually run the fix script:**
```bash
cd /var/www/timebank_cc_dev
./deployment-htmlpurifier-fix.sh www-data www-data
```
2. **Check storage directory permissions:**
```bash
sudo chown -R www-data:www-data storage/
sudo chmod -R 775 storage/
```
3. **Check SELinux (if applicable):**
```bash
sudo chcon -R -t httpd_sys_rw_content_t storage/
```
4. **Clear all caches:**
```bash
php artisan cache:clear
php artisan view:clear
php artisan config:clear
```
## Benefits
1. **Security:** Vendor directory remains read-only
2. **Reliability:** Cache survives `composer install` updates
3. **Laravel Standard:** Uses Laravel's cache directory structure
4. **Cross-Environment:** Works on local, dev, and production without changes
5. **Auto-Recovery:** Code creates directory if missing
6. **Deployment Safe:** Script always continues even if errors occur
## Technical Details
### Cache Location
- **Old (problematic):** `vendor/ezyang/htmlpurifier/library/HTMLPurifier/DefinitionCache/Serializer`
- **New (fixed):** `storage/framework/cache/htmlpurifier`
### Permissions
- **Directory:** 0755 (owner: rwx, group: r-x, others: r-x)
- **Owner:** Web server user (www-data, apache, nginx)
- **Group:** Web server group (same as owner)
### Files Created
When HTMLPurifier runs, it creates definition cache files:
- `HTML/4.01_XHTML1.0_Transitional.ser`
- `HTML/4.01_XHTML1.0_Transitional-Attr.AllowedFrameTargets.ser`
- And others based on configuration
These are automatically managed by HTMLPurifier and Laravel's cache clearing commands.
## Troubleshooting
### Error: "Directory not writable"
**Cause:** Web server user can't write to cache directory
**Fix:**
```bash
sudo chown -R www-data:www-data storage/framework/cache/htmlpurifier
sudo chmod -R 755 storage/framework/cache/htmlpurifier
```
### Error: "Failed to create directory"
**Cause:** Parent directory (`storage/framework/cache/`) doesn't have write permissions
**Fix:**
```bash
sudo chown -R www-data:www-data storage/framework/cache/
sudo chmod -R 775 storage/framework/cache/
```
### Error: SELinux blocking writes
**Cause:** SELinux security context preventing writes
**Fix:**
```bash
sudo chcon -R -t httpd_sys_rw_content_t storage/framework/cache/
```
## Testing
After deployment, verify HTMLPurifier works:
1. **View a post with HTML content:**
- Visit any page that displays post content
- No errors should appear
2. **Check cache directory:**
```bash
ls -la storage/framework/cache/htmlpurifier/
```
You should see definition cache files created by HTMLPurifier
3. **Run tests:**
```bash
php artisan test --filter PostContentXssProtectionTest
```
All 16 tests should pass
## Related Files
- `app/Helpers/StringHelper.php` - Sanitization method with cache configuration
- `deployment-htmlpurifier-fix.sh` - Standalone setup script
- `deploy.sh` - Main deployment script (includes HTMLPurifier setup)
- `SECURITY_AUDIT_XSS.md` - Complete XSS vulnerability audit report
## Support
If you encounter issues not covered here:
1. Check Laravel logs: `storage/logs/laravel.log`
2. Check web server error logs: `/var/log/apache2/error.log` or `/var/log/nginx/error.log`
3. Verify web server user: `ps aux | grep -E 'apache|nginx|httpd' | grep -v grep`
4. Check storage permissions: `ls -la storage/`