Some checks failed
CI / build (8.0) (push) Has been cancelled
CI / build (8.1) (push) Has been cancelled
CI / build (8.2) (push) Has been cancelled
CI / build (8.3) (push) Has been cancelled
CI / build (8.4) (push) Has been cancelled
CI / PHP Lint & Basic Checks (matrix) (8.0) (push) Has been cancelled
CI / PHP Lint & Basic Checks (matrix) (8.1) (push) Has been cancelled
CI / PHP Lint & Basic Checks (matrix) (8.2) (push) Has been cancelled
UploadShield (Hardened v3)
This repository contains UploadShield (formerly "Upload Logger"): a hardened PHP upload protection helper. It provides a single-file monitor that logs uploads, detects common evasion techniques, quarantines suspicious files, and can optionally block malicious uploads.
Primary file: uploadshield.php
Summary
- Purpose: Log normal uploads and raw-body uploads, detect double-extension tricks, fake images, PHP payloads embedded in files, and provide flood detection.
- Runs only for HTTP requests; recommended to enable via
auto_prepend_filein a per-site PHP-FPM pool for broad coverage.
Key configuration (top of uploadshield.php)
$logFile— path to the log file (default:__DIR__ . '/logs/uploads.log').$BLOCK_SUSPICIOUS— iftruethe script returns403and exits when suspicious uploads are detected.$MAX_SIZE— threshold forWARN big_upload(default 50 MB).$RAW_BODY_MIN— minimum raw request body size considered suspicious when$_FILESis empty (default 500 KB).$FLOOD_WINDOW_SEC,$FLOOD_MAX_UPLOADS— lightweight per-IP flood detection window and max uploads before alerting.$SNIFF_MAX_BYTES,$SNIFF_MAX_FILESIZE— parameters controlling fast content sniffing for PHP/webshell markers.$LOG_USER_AGENT— includeUser-Agentin logs when true.
What it detects
- Dangerous filenames (path-traversal, double extensions, hidden php-like dotfiles).
- Fake images: file extension indicates an image but
finforeturns a non-image MIME. - PHP/webshell markers inside file content (fast head-scan up to configured limits).
- Archive uploads (
.zip,.tar, etc.) flagged for attention. - Raw request bodies (e.g.,
application/octet-streamor streamed uploads) when$_FILESis empty and body size exceeds$RAW_BODY_MIN. - Flooding by counting uploads per-IP in a rolling window.
Logging and alerts
- Each accepted upload generates an
UPLOADline with fields:ip,user,name,size,type,real(detected MIME),tmp,uri, and optionalua. - Suspicious uploads generate
ALERT suspiciousentries withreasons=listing detected flags (e.g.,bad_name,fake_image,php_payload). - Other notes:
WARN big_upload,NOTE archive_upload,MULTIPART_NO_FILES, andRAW_BODYare emitted when appropriate.
Integration notes
- Preferred deployment: set
php_admin_value[auto_prepend_file]in the site-specific PHP-FPM pool to the absolute path ofuploadshield.phpso it runs before application code. - If using sessions for user identification, the script safely reads
$_SESSION['user_id']only when a session is active; do not rely on it being present unless your app starts sessions earlier. - The script uses
is_uploaded_file()/finfowhere available; ensure the PHPfileinfoextension is enabled for best MIME detection. - The script uses
is_uploaded_file()/finfowhere available; ensure the PHPfileinfoextension is enabled for best MIME detection.
Content detector & tuning
ContentDetectoris now included and performs a fast head-scan of uploaded files to detect PHP open-tags and common webshell indicators (e.g.,passthru(),system(),exec(),shell_exec(),proc_open(),popen(),base64_decode(),eval(),assert()).- The detector only scans the first N bytes of a file to limit CPU/io work; tune these limits in
uploadshield.json:limits.sniff_max_bytes— number of bytes to scan from file head (default8192).limits.sniff_max_filesize— only scan files up to this size in bytes (default2097152/ 2MB).
- Behavior note:
eval()and similar tokens commonly appear inside SVG/JS contexts. The detector uses the detected MIME to be more permissive for XML/SVG-like content, but you should test and tune for your application's upload patterns to avoid false positives (seeINTEGRATION.md). If your application legitimately accepts encoded or templated payloads, add application-specific allowlist rules (URI or content-type) inallowlist.jsonor extenduploadshield.jsonwith detector-specific tuning before enabling blocking mode. Further integration - Read the
INTEGRATION.mdfor detector tuning, allowlists, and examples for log forwarding and Fail2Ban. - See
docs/INSTALLATION.mdfor a step-by-step per-site install andauto_prepend_fileexamples. - Provision the required directories (
quarantine,state) and set ownership/SELinux via the included provisioning script:scripts/provision_dirs.sh. - Example automation:
scripts/ansible/uploadshield-provision.ymlandscripts/systemd/uploadshield-provision.serviceare included as examples to run provisioning at deploy-time or boot.
Operational recommendations
- Place the
logs/directory outside the webroot or deny web access to it. - Ensure correct owner/group and permissions (e.g., owner
root, groupwww-data,chmod 750on.securityandchmod 640for logs) and confirm PHP-FPM's user/group membership. - Rotate logs with
logrotate(seeINTEGRATION.mdfor an example snippet). - If your host uses SELinux/AppArmor, set correct contexts or adjust profiles so PHP-FPM can read the script and write logs.
Limitations & safety
- This script improves visibility and blocks common upload tricks but cannot guarantee interception of every file-write vector (e.g., direct application writes, ZipArchive extraction, custom file APIs). Use it as part of a layered defense.
- Content sniffing is limited to a head-scan to reduce CPU and false positives; tune
$SNIFF_MAX_BYTESand$SNIFF_MAX_FILESIZEto balance coverage and performance.
Quick start
- Place
uploadshield.phpin a per-site secure folder (seeINTEGRATION.md). - Ensure the
logs/directory exists and is writable by PHP-FPM. - Enable as an
auto_prepend_filein the site pool and reload PHP-FPM. - Monitor
logs/uploads.logand adjust configuration options at the top of the script.
Support & changes
- For changes, edit configuration variables at the top of
uploadshield.phpor adapt detection helpers as needed.
Generated for uploadshield.php (UploadShield v3).
Additional documentation
- Auto-merge & Dependabot: docs/auto-merge.md
Description
Languages
PHP
89%
Shell
10.7%
PowerShell
0.3%