fix(scanner): avoid SVG/XML false positives; add allowlist and .gitignore
Relax payload scanner for XML/SVG by passing content-type into checks Skip JS-style eval() detection when content-type is XML/SVG Pass request Content-Type through sniff_file_for_php_payload() and raw-body checks Add common XML/SVG content-types to allowlist.json Add repository .gitignore (ignore logs, quarantine/, state/, env, vendor, IDE files)
This commit is contained in:
33
.gitignore
vendored
Normal file
33
.gitignore
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Upload Logger repository .gitignore
|
||||||
|
|
||||||
|
# Runtime logs and quarantine/state directories (do not commit)
|
||||||
|
/logs/
|
||||||
|
/quarantine/
|
||||||
|
/state/
|
||||||
|
*.log
|
||||||
|
uploads.log
|
||||||
|
|
||||||
|
# Peek allow marker (local only)
|
||||||
|
/.upload_logger_allow_peek
|
||||||
|
|
||||||
|
# Local environment files
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
|
||||||
|
# Composer / vendor
|
||||||
|
/vendor/
|
||||||
|
/composer.lock
|
||||||
|
|
||||||
|
# Node
|
||||||
|
/node_modules/
|
||||||
|
|
||||||
|
# IDEs and OS files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Temp/cache
|
||||||
|
*.cache
|
||||||
|
*.tmp
|
||||||
472
INTEGRATION.md
Normal file
472
INTEGRATION.md
Normal file
@@ -0,0 +1,472 @@
|
|||||||
|
# 🔐 Per-Site PHP Upload Guard Integration Guide
|
||||||
|
|
||||||
|
This guide explains how to integrate a global PHP upload monitoring script
|
||||||
|
using `auto_prepend_file`, on a **per-site basis**, with isolated security
|
||||||
|
folders.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 1. Recommended Folder Structure
|
||||||
|
|
||||||
|
Each website should contain its own hidden security directory:
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
/var/www/sites/example-site/
|
||||||
|
├── public/
|
||||||
|
├── app/
|
||||||
|
├── uploads/
|
||||||
|
├── .security/
|
||||||
|
│ ├── upload_guard.php
|
||||||
|
│ └── logs/
|
||||||
|
│ └── uploads.log
|
||||||
|
|
||||||
|
````
|
||||||
|
|
||||||
|
Benefits:
|
||||||
|
|
||||||
|
- Per-site isolation
|
||||||
|
- Easier debugging
|
||||||
|
- Independent log files
|
||||||
|
- Reduced attack surface
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 2. Create the Security Directory
|
||||||
|
|
||||||
|
From the site root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /var/www/sites/example-site
|
||||||
|
|
||||||
|
mkdir .security
|
||||||
|
mkdir .security/logs
|
||||||
|
````
|
||||||
|
|
||||||
|
Set secure permissions:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chown -R root:www-data .security
|
||||||
|
chmod 750 .security
|
||||||
|
chmod 750 .security/logs
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 3. Install the Upload Guard Script
|
||||||
|
|
||||||
|
Create the script file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano .security/upload_guard.php
|
||||||
|
```
|
||||||
|
|
||||||
|
Paste your hardened upload monitoring script.
|
||||||
|
|
||||||
|
Inside the script, configure logging:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$logFile = __DIR__ . '/logs/uploads.log';
|
||||||
|
```
|
||||||
|
|
||||||
|
Lock the script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chown root:root .security/upload_guard.php
|
||||||
|
chmod 644 .security/upload_guard.php
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ 4. Enable auto_prepend_file (Per Site)
|
||||||
|
|
||||||
|
### Option A — PHP-FPM Pool (Recommended)
|
||||||
|
|
||||||
|
Edit the site’s PHP-FPM pool configuration:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano /etc/php/8.x/fpm/pool.d/example-site.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Add:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
php_admin_value[auto_prepend_file] = /var/www/sites/example-site/.security/upload_guard.php
|
||||||
|
```
|
||||||
|
|
||||||
|
Reload PHP-FPM:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl reload php8.x-fpm
|
||||||
|
```
|
||||||
|
|
||||||
|
# 🔐 Per-Site PHP Upload Guard Integration Guide
|
||||||
|
|
||||||
|
This guide explains how to integrate a global PHP upload monitoring script
|
||||||
|
using `auto_prepend_file`, on a **per-site basis**, with isolated security
|
||||||
|
folders.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 1. Recommended Folder Structure
|
||||||
|
|
||||||
|
Each website should contain its own hidden security directory:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/var/www/sites/example-site/
|
||||||
|
├── public/
|
||||||
|
├── app/
|
||||||
|
├── uploads/
|
||||||
|
├── .security/
|
||||||
|
│ ├── upload-logger.php
|
||||||
|
│ └── logs/
|
||||||
|
│ └── uploads.log
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Benefits:
|
||||||
|
|
||||||
|
- Per-site isolation
|
||||||
|
- Easier debugging
|
||||||
|
- Independent log files
|
||||||
|
- Reduced attack surface
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 2. Create the Security Directory
|
||||||
|
|
||||||
|
From the site root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /var/www/sites/example-site
|
||||||
|
|
||||||
|
mkdir .security
|
||||||
|
mkdir .security/logs
|
||||||
|
```
|
||||||
|
|
||||||
|
Set secure permissions:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chown -R root:www-data .security
|
||||||
|
chmod 750 .security
|
||||||
|
chmod 750 .security/logs
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 3. Install the Upload Guard Script
|
||||||
|
|
||||||
|
Create the script file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano .security/upload-logger.php
|
||||||
|
```
|
||||||
|
|
||||||
|
Paste your hardened upload monitoring script.
|
||||||
|
|
||||||
|
Inside the script, configure logging:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$logFile = __DIR__ . '/logs/uploads.log';
|
||||||
|
```
|
||||||
|
|
||||||
|
Lock the script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chown root:root .security/upload-logger.php
|
||||||
|
chmod 644 .security/upload-logger.php
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ 4. Enable auto_prepend_file (Per Site)
|
||||||
|
|
||||||
|
### Option A — PHP-FPM Pool (Recommended)
|
||||||
|
|
||||||
|
Edit the site’s PHP-FPM pool configuration:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano /etc/php/8.x/fpm/pool.d/example-site.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Add:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
php_admin_value[auto_prepend_file] = /var/www/sites/example-site/.security/upload-logger.php
|
||||||
|
```
|
||||||
|
|
||||||
|
Reload PHP-FPM (adjust service name to match your PHP version):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl reload php8.x-fpm
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Option B — Apache Virtual Host
|
||||||
|
|
||||||
|
If using a shared PHP-FPM pool, configure in the vHost:
|
||||||
|
|
||||||
|
```apache
|
||||||
|
<Directory /var/www/sites/example-site>
|
||||||
|
php_admin_value auto_prepend_file /var/www/sites/example-site/.security/upload-logger.php
|
||||||
|
</Directory>
|
||||||
|
```
|
||||||
|
|
||||||
|
Reload Apache:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl reload apache2
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚫 5. Block Web Access to `.security`
|
||||||
|
|
||||||
|
Prevent direct HTTP access to the security folder.
|
||||||
|
|
||||||
|
In the vHost:
|
||||||
|
|
||||||
|
```apache
|
||||||
|
<Directory /var/www/sites/example-site/.security>
|
||||||
|
Require all denied
|
||||||
|
</Directory>
|
||||||
|
```
|
||||||
|
|
||||||
|
Or in `.htaccess` (if allowed):
|
||||||
|
|
||||||
|
```apache
|
||||||
|
Require all denied
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ 6. Verify Installation
|
||||||
|
|
||||||
|
Create a temporary file:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php phpinfo();
|
||||||
|
```
|
||||||
|
|
||||||
|
Open it in browser and search for:
|
||||||
|
|
||||||
|
```text
|
||||||
|
auto_prepend_file
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected output:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/var/www/sites/example-site/.security/upload_guard.php
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove the test file after verification.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 7. Test Upload Logging
|
||||||
|
|
||||||
|
Create a simple upload test:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<form method="post" enctype="multipart/form-data">
|
||||||
|
<input type="file" name="testfile">
|
||||||
|
<button>Upload</button>
|
||||||
|
</form>
|
||||||
|
```
|
||||||
|
|
||||||
|
Upload any file and check logs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat .security/logs/uploads.log
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see a new entry.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔒 8. Disable PHP Execution in Uploads
|
||||||
|
|
||||||
|
Always block PHP execution in upload directories.
|
||||||
|
|
||||||
|
Example (Apache):
|
||||||
|
|
||||||
|
```apache
|
||||||
|
<Directory /var/www/sites/example-site/uploads>
|
||||||
|
php_admin_flag engine off
|
||||||
|
AllowOverride None
|
||||||
|
</Directory>
|
||||||
|
```
|
||||||
|
|
||||||
|
Reload Apache after changes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛡️ 9. Enable Blocking Mode (Optional)
|
||||||
|
|
||||||
|
After monitoring for some time, enable blocking.
|
||||||
|
|
||||||
|
Edit:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$BLOCK_SUSPICIOUS = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
Then reload PHP-FPM.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 10. (Optional) Fail2Ban Integration (JSON logs)
|
||||||
|
|
||||||
|
Create a JSON-aware filter that matches `event: "suspicious"` and extracts the IP address.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano /etc/fail2ban/filter.d/php-upload.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Definition]
|
||||||
|
# Match JSON lines where event == "suspicious" and capture the IPv4 address as <HOST>
|
||||||
|
failregex = ^.*"event"\s*:\s*"suspicious".*"ip"\s*:\s*"(?P<host>\d{1,3}(?:\.\d{1,3}){3})".*$
|
||||||
|
ignoreregex =
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a jail that points to the per-site logs (or a central aggregated log):
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[php-upload]
|
||||||
|
enabled = true
|
||||||
|
filter = php-upload
|
||||||
|
logpath = /var/www/sites/*/.security/logs/uploads.log
|
||||||
|
maxretry = 3
|
||||||
|
findtime = 600
|
||||||
|
bantime = 86400
|
||||||
|
action = iptables-multiport[name=php-upload, port="http,https", protocol=tcp]
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart Fail2Ban:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl restart fail2ban
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fail2Ban action: nftables example
|
||||||
|
|
||||||
|
If your host uses nftables, prefer the `nftables` action so bans use the system firewall:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[php-upload]
|
||||||
|
enabled = true
|
||||||
|
filter = php-upload
|
||||||
|
logpath = /var/www/sites/*/.security/logs/uploads.log
|
||||||
|
maxretry = 3
|
||||||
|
findtime = 600
|
||||||
|
bantime = 86400
|
||||||
|
action = nftables[name=php-upload, port="http,https", protocol=tcp]
|
||||||
|
```
|
||||||
|
|
||||||
|
This uses Fail2Ban's `nftables` action (available on modern distributions). Adjust `port`/`protocol` to match your services.
|
||||||
|
|
||||||
|
### Central log aggregation (Filebeat / rsyslog)
|
||||||
|
|
||||||
|
Forwarding per-site JSON logs to a central collector simplifies alerts and Fail2Ban at scale. Two lightweight options:
|
||||||
|
|
||||||
|
- Filebeat prospector (send to Logstash/Elasticsearch):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
filebeat.inputs:
|
||||||
|
- type: log
|
||||||
|
paths:
|
||||||
|
- /var/www/sites/*/.security/logs/uploads.log
|
||||||
|
json.keys_under_root: true
|
||||||
|
json.add_error_key: true
|
||||||
|
fields:
|
||||||
|
source: php-upload-logger
|
||||||
|
output.logstash:
|
||||||
|
hosts: ["logserver:5044"]
|
||||||
|
```
|
||||||
|
|
||||||
|
- rsyslog `imfile` forwarding to remote syslog (central rsyslog/logstash):
|
||||||
|
|
||||||
|
Add to `/etc/rsyslog.d/10-upload-logger.conf`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
module(load="imfile" PollingInterval="10")
|
||||||
|
input(type="imfile" File="/var/www/sites/*/.security/logs/uploads.log" Tag="uploadlogger" Severity="info" Facility="local7")
|
||||||
|
*.* @@logserver:514
|
||||||
|
```
|
||||||
|
|
||||||
|
Both options keep JSON intact for downstream parsing and reduce per-host Fail2Ban complexity.
|
||||||
|
|
||||||
|
### Testing your Fail2Ban filter
|
||||||
|
|
||||||
|
Create a temporary file containing a representative JSON log line emitted by `upload-logger.php` and run `fail2ban-regex` against your filter to validate detection.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# create test file with a suspicious event
|
||||||
|
cat > /tmp/test_upload.log <<'JSON'
|
||||||
|
{"ts":"$(date -u +%Y-%m-%dT%H:%M:%SZ)","event":"suspicious","ip":"1.2.3.4","user":"guest","name":"evil.php.jpg","real_mime":"application/x-php","reasons":["bad_name","php_payload"]}
|
||||||
|
JSON
|
||||||
|
|
||||||
|
# test the filter (adjust path to filter if different)
|
||||||
|
fail2ban-regex /tmp/test_upload.log /etc/fail2ban/filter.d/php-upload.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
`fail2ban-regex` will report how many matches were found and display sample matched groups (including the captured `<HOST>`). Use this to iterate on the `failregex` if it doesn't extract the IP as expected.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏁 Final Architecture
|
||||||
|
|
||||||
|
```text
|
||||||
|
Client → Web Server → PHP (auto_prepend) → Application → Disk
|
||||||
|
↓
|
||||||
|
Log / Alert / Ban
|
||||||
|
```
|
||||||
|
|
||||||
|
This provides multi-layer upload monitoring and protection.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🗂️ Log rotation & SELinux/AppArmor notes
|
||||||
|
|
||||||
|
- Example `logrotate` snippet to rotate per-site logs weekly and keep 8 rotations:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/var/www/sites/*/.security/logs/uploads.log {
|
||||||
|
weekly
|
||||||
|
rotate 8
|
||||||
|
compress
|
||||||
|
missingok
|
||||||
|
notifempty
|
||||||
|
create 0640 root adm
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- If your host enforces SELinux or AppArmor, ensure the `.security` directory and log files have the correct context so PHP-FPM can read the script and write logs. For SELinux (RHEL/CentOS) you may need:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chcon -R -t httpd_sys_rw_content_t /var/www/sites/example-site/.security/logs
|
||||||
|
restorecon -R /var/www/sites/example-site/.security
|
||||||
|
```
|
||||||
|
|
||||||
|
Adjust commands to match your platform and policy. AppArmor profiles may require adding paths to the PHP-FPM profile.
|
||||||
|
|
||||||
|
## ⚠️ Security Notes
|
||||||
|
|
||||||
|
- Never use `777` permissions
|
||||||
|
- Keep `.security` owned by `root`
|
||||||
|
- Regularly review logs
|
||||||
|
- Update PHP and extensions
|
||||||
|
- Combine with OS-level auditing for best results
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📌 Recommended Maintenance
|
||||||
|
|
||||||
|
Weekly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
grep ALERT .security/logs/uploads.log
|
||||||
|
```
|
||||||
58
README.md
Normal file
58
README.md
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# Upload Logger (Hardened v3)
|
||||||
|
|
||||||
|
This repository contains the v3 upload-logging helper: a hardened single-file monitor that logs uploads, detects common evasion techniques, and optionally blocks suspicious uploads.
|
||||||
|
|
||||||
|
Primary file: [upload-logger.php](upload-logger.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_file` in a per-site PHP-FPM pool for broad coverage.
|
||||||
|
|
||||||
|
Key configuration (top of `upload-logger.php`)
|
||||||
|
- `$logFile` — path to the log file (default: `__DIR__ . '/logs/uploads.log'`).
|
||||||
|
- `$BLOCK_SUSPICIOUS` — if `true` the script returns `403` and exits when suspicious uploads are detected.
|
||||||
|
- `$MAX_SIZE` — threshold for `WARN big_upload` (default 50 MB).
|
||||||
|
- `$RAW_BODY_MIN` — minimum raw request body size considered suspicious when `$_FILES` is 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` — include `User-Agent` in logs when true.
|
||||||
|
|
||||||
|
What it detects
|
||||||
|
- Dangerous filenames (path-traversal, double extensions, hidden php-like dotfiles).
|
||||||
|
- Fake images: file extension indicates an image but `finfo` returns 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-stream` or streamed uploads) when `$_FILES` is 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 `UPLOAD` line with fields: `ip`, `user`, `name`, `size`, `type`, `real` (detected MIME), `tmp`, `uri`, and optional `ua`.
|
||||||
|
- Suspicious uploads generate `ALERT suspicious` entries with `reasons=` listing detected flags (e.g., `bad_name,fake_image,php_payload`).
|
||||||
|
- Other notes: `WARN big_upload`, `NOTE archive_upload`, `MULTIPART_NO_FILES`, and `RAW_BODY` are 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 of `upload-logger.php` so 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()`/`finfo` where available; ensure the PHP `fileinfo` extension is enabled for best MIME detection.
|
||||||
|
|
||||||
|
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`, group `www-data`, `chmod 750` on `.security` and `chmod 640` for logs) and confirm PHP-FPM's user/group membership.
|
||||||
|
- Rotate logs with `logrotate` (see `INTEGRATION.md` for 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_BYTES` and `$SNIFF_MAX_FILESIZE` to balance coverage and performance.
|
||||||
|
|
||||||
|
Quick start
|
||||||
|
1. Place `upload-logger.php` in a per-site secure folder (see `INTEGRATION.md`).
|
||||||
|
2. Ensure the `logs/` directory exists and is writable by PHP-FPM.
|
||||||
|
3. Enable as an `auto_prepend_file` in the site pool and reload PHP-FPM.
|
||||||
|
4. Monitor `logs/uploads.log` and adjust configuration options at the top of the script.
|
||||||
|
|
||||||
|
Support & changes
|
||||||
|
- For changes, edit configuration variables at the top of `upload-logger.php` or adapt detection helpers as needed.
|
||||||
|
|
||||||
|
---
|
||||||
|
Generated for upload-logger.php (v3).
|
||||||
22
allowlist.json
Normal file
22
allowlist.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"uris": [
|
||||||
|
"/api/uploads/avatars",
|
||||||
|
"/api/v1/avatars",
|
||||||
|
"/user/avatar",
|
||||||
|
"/media/upload",
|
||||||
|
"/api/media",
|
||||||
|
"/api/uploads",
|
||||||
|
"/api/v1/uploads",
|
||||||
|
"/attachments/upload",
|
||||||
|
"/upload",
|
||||||
|
"#^/internal/webhook#",
|
||||||
|
"#/hooks/(github|gitlab|stripe|slack)#",
|
||||||
|
"/services/avatars",
|
||||||
|
"/api/profile/photo"
|
||||||
|
],
|
||||||
|
"ctypes": [
|
||||||
|
"image/svg+xml",
|
||||||
|
"application/xml",
|
||||||
|
"text/xml"
|
||||||
|
]
|
||||||
|
}
|
||||||
1000
upload-logger.php
Normal file
1000
upload-logger.php
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user