Initial commit
This commit is contained in:
226
references/DEPLOYMENT_HTMLPURIFIER_FIX.md
Normal file
226
references/DEPLOYMENT_HTMLPURIFIER_FIX.md
Normal 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/`
|
||||
Reference in New Issue
Block a user