laminblur / filament-pdf-sanitizer
A Filament plugin that automatically sanitizes PDF files by removing JavaScript, forms, and annotations before upload to prevent WAF blocking
Installs: 10
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Language:JavaScript
pkg:composer/laminblur/filament-pdf-sanitizer
Requires
- php: ^8.2
- filament/filament: ^3.0
- illuminate/support: ^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^9.0|^10.0
README
A Filament plugin that automatically sanitizes PDF files by removing JavaScript, forms, annotations, and embedded scripts before upload. This prevents AWS WAF and other security systems from blocking PDF uploads that contain executable content.
๐ฏ Problem Solved
When uploading PDFs through Filament's FileUpload component, files containing embedded JavaScript or interactive elements can be blocked by security systems like AWS WAF (Web Application Firewall). This plugin automatically sanitizes PDFs client-side before upload, ensuring they pass security checks while preserving all visual content.
โจ Features
- ๐ Automatic PDF Sanitization - Removes JavaScript, forms, and annotations from PDFs before upload
- ๐ Zero Configuration - Works out of the box with Filament FileUpload components
- โก Lazy Loading - Only loads PDF libraries when file inputs are detected (reduces initial bundle size)
- ๐ฏ Transparent - Works seamlessly with Livewire file uploads without user intervention
- ๐ฆ Lightweight - Optimized bundle size with code splitting and dynamic imports
- ๐ Smart Caching - Caches sanitized files to prevent re-processing on retry
- ๐ก๏ธ WAF Compatible - Prevents AWS WAF and other security systems from blocking uploads
- ๐ Progress Indicators - Visual feedback during PDF sanitization
- โ๏ธ Configurable - Customize quality, scale, file size limits, and more
- ๐งน Memory Efficient - Automatic cleanup of canvas elements and memory management
- ๐จ Error Handling - Graceful error handling with console logging
- ๐ File Size Limits - Configurable maximum file size and page count limits
๐ Requirements
- PHP 8.2 or higher
- Laravel 11 or 12
- Filament 3.x
- Node.js dependencies:
jspdfandpdfjs-dist
๐ฆ Installation
Step 1: Install via Composer
Install the package directly from Packagist:
composer require laminblur/filament-pdf-sanitizer
Step 2: Install NPM Dependencies
npm install jspdf pdfjs-dist
Step 3: Publish Assets
php artisan vendor:publish --tag=filament-pdf-sanitizer-assets php artisan vendor:publish --tag=filament-pdf-sanitizer-config
Note: The PDF worker file is automatically copied to
public/vendor/filament-pdf-sanitizer/when the package is installed. If you need to update it, run the publish command again with the--forceflag.
Step 4: Update Vite Config (Optional)
If you want to explicitly include the package assets in your build, add to vite.config.js:
import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; export default defineConfig({ plugins: [ laravel({ input: [ 'resources/css/app.css', 'resources/js/app.js', 'resources/css/filament/admin/theme.css', 'resources/js/vendor/filament-pdf-sanitizer/init.js', // Add this ], refresh: true, }), ], });
Step 5: Rebuild Assets
npm run build
๐ Usage
Basic Usage
Add the plugin to your Filament panel provider:
<?php namespace App\Providers\Filament; use Filament\Panel; use Filament\PanelProvider; use Laminblur\FilamentPdfSanitizer\FilamentPdfSanitizerPlugin; class AdminPanelProvider extends PanelProvider { public function panel(Panel $panel): Panel { return $panel ->plugins([ FilamentPdfSanitizerPlugin::make(), // ... other plugins ]); } }
That's it! The plugin will automatically sanitize all PDF uploads in your Filament panels.
Configuration Options
You can configure the plugin in two ways:
Method 1: Plugin Methods (Per Panel)
FilamentPdfSanitizerPlugin::make() ->workerPath('/custom/path/to/pdf.worker.min.js') ->scale(2.0) // Higher quality (default: 1.5) ->quality(0.95) // JPEG quality 0.0-1.0 (default: 0.85) ->maxFileSizeMb(100) // Max file size in MB (default: 50) ->maxPages(100) // Max pages to process (default: null = unlimited) ->showProgress(true) // Show progress indicator (default: true) ->logErrors(true) // Log errors to console (default: true)
Method 2: Config File (Global)
Publish and edit the config file:
php artisan vendor:publish --tag=filament-pdf-sanitizer-config
Edit config/pdf-sanitizer.php:
return [ /* |-------------------------------------------------------------------------- | PDF Worker Path |-------------------------------------------------------------------------- | | The path to the PDF.js worker file. This file is required for PDF | parsing and rendering. | */ 'worker_path' => '/vendor/filament-pdf-sanitizer/pdf.worker.min.js', /* |-------------------------------------------------------------------------- | Enable PDF Sanitization |-------------------------------------------------------------------------- | | Set to false to disable PDF sanitization globally. | */ 'enabled' => true, /* |-------------------------------------------------------------------------- | PDF Rendering Scale |-------------------------------------------------------------------------- | | The scale factor for rendering PDF pages. Higher values produce better | quality but larger file sizes. Recommended range: 1.0 - 3.0 | */ 'scale' => 1.5, /* |-------------------------------------------------------------------------- | JPEG Quality |-------------------------------------------------------------------------- | | The JPEG quality for rendered pages (0.0 - 1.0). Higher values produce | better quality but larger file sizes. Recommended range: 0.7 - 0.95 | */ 'quality' => 0.85, /* |-------------------------------------------------------------------------- | Maximum File Size (MB) |-------------------------------------------------------------------------- | | Maximum PDF file size to sanitize. Files larger than this will be | skipped. Set to null to disable size checking. | */ 'max_file_size_mb' => 50, /* |-------------------------------------------------------------------------- | Maximum Pages |-------------------------------------------------------------------------- | | Maximum number of pages to process. PDFs with more pages will be | skipped. Set to null to disable page limit. | */ 'max_pages' => null, /* |-------------------------------------------------------------------------- | Show Progress Indicator |-------------------------------------------------------------------------- | | Whether to show a visual progress indicator during sanitization. | */ 'show_progress' => true, /* |-------------------------------------------------------------------------- | Log Errors |-------------------------------------------------------------------------- | | Whether to log sanitization errors to the browser console. | */ 'log_errors' => true, ];
๐ง How It Works
- Detection: The plugin detects when a PDF file is selected in a file input
- Validation: Checks file size and page count limits (if configured)
- Sanitization: Each PDF page is rendered to a canvas, converted to a JPEG image, and rebuilt as a clean PDF
- Progress: Shows visual progress indicator during sanitization (if enabled)
- Interception: The sanitized PDF replaces the original file before the upload request is sent
- Caching: Sanitized files are cached using WeakMap to prevent re-processing on retry
- Cleanup: Canvas elements and memory are automatically cleaned up after processing
What Gets Removed โ
- JavaScript actions and event handlers
- PDF forms and interactive elements
- Annotations and comments
- Embedded objects and widgets
- Metadata scripts
- JavaScript-based links
What Gets Preserved โ
- Visual content (text, images, graphics)
- Page layout and formatting
- Vector graphics and drawings
- File structure and organization
๐ Browser Support
- โ Chrome/Edge (latest)
- โ Firefox (latest)
- โ Safari (latest)
๐ Troubleshooting
PDF Worker Not Found
If you see errors about the PDF worker file:
-
The worker file should be automatically copied when the package is installed. If it's missing, publish assets:
php artisan vendor:publish --tag=filament-pdf-sanitizer-assets --force
-
Verify the file exists at:
public/vendor/filament-pdf-sanitizer/pdf.worker.min.js -
Verify the file is accessible via URL:
/vendor/filament-pdf-sanitizer/pdf.worker.min.js -
If the file still doesn't exist, ensure the
publicdirectory is writable and try clearing the application cache:php artisan cache:clear php artisan config:clear
Upload Still Blocked
If uploads are still being blocked:
- โ Check that the plugin is registered in your panel provider
- โ Verify the PDF worker file is accessible at the configured path
- โ Check browser console for JavaScript errors
- โ
Ensure npm dependencies are installed:
npm install jspdf pdfjs-dist - โ
Rebuild assets:
npm run build
Build Errors
If you encounter Vite build errors:
- Ensure JavaScript files are published to
resources/js/vendor/filament-pdf-sanitizer/ - Check your
vite.config.jsincludes the package assets (optional) - Run
npm run buildto rebuild assets - Clear Vite cache:
rm -rf node_modules/.vite(Linux/Mac) orRemove-Item -Recurse -Force node_modules\.vite(Windows)
File Upload Not Working
If file uploads stop working:
- Check browser console for errors
- Verify Livewire is properly initialized
- Ensure the plugin is only registered once (check for duplicate plugin registrations)
- Try clearing browser cache and rebuilding assets
๐ Performance
- Initial Bundle Impact: ~0KB (lazy loaded)
- When Active: ~800KB (pdfjs-dist + jspdf, loaded only when PDF is detected)
- Sanitization Time: ~1-3 seconds per PDF (depends on page count and complexity)
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
๐ License
This project is open-sourced software licensed under the MIT license.
๐ Acknowledgments
- Built for Filament PHP
- Uses PDF.js for PDF parsing
- Uses jsPDF for PDF generation
๐ Support
For issues and questions, please open an issue on GitHub.
๐ Links
Made with โค๏ธ for the Filament community