Harden quarantine provisioning; enforce strict permissions and update Ansible and docs
This commit is contained in:
105
INTEGRATION.md
105
INTEGRATION.md
@@ -1,3 +1,99 @@
|
||||
## Integration
|
||||
|
||||
Example `upload-logger.json` (commented for easy copy/paste into your environment):
|
||||
|
||||
```json
|
||||
// {
|
||||
// "modules": {
|
||||
// "flood": true,
|
||||
// "filename": true,
|
||||
// "mime_sniff": true,
|
||||
// "hashing": true,
|
||||
// "base64_detection": true,
|
||||
// "raw_peek": false,
|
||||
// "archive_inspect": true,
|
||||
// "quarantine": true
|
||||
// },
|
||||
// "paths": {
|
||||
// "log_file": "logs/uploads.log",
|
||||
// "quarantine_dir": "quarantine",
|
||||
// "state_dir": "state",
|
||||
// "allowlist_file": "allowlist.json"
|
||||
// },
|
||||
// "limits": {
|
||||
// "max_size": 52428800,
|
||||
// "raw_body_min": 512000,
|
||||
// "sniff_max_bytes": 8192,
|
||||
// "sniff_max_filesize": 2097152,
|
||||
// "hash_max_filesize": 10485760,
|
||||
// "archive_max_inspect_size": 52428800,
|
||||
// "archive_max_entries": 200
|
||||
// },
|
||||
// "ops": {
|
||||
// "quarantine_owner": "root",
|
||||
// "quarantine_group": "www-data",
|
||||
// "quarantine_dir_perms": "0700",
|
||||
// "log_rotate": {
|
||||
// "enabled": true,
|
||||
// "size": 10485760,
|
||||
// "keep": 7
|
||||
// }
|
||||
// },
|
||||
// "allowlists": {
|
||||
// "base64_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"]
|
||||
// }
|
||||
// }
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Remove the leading `// ` when copying this into a real `upload-logger.json` file.
|
||||
- Adjust paths, owners, and limits to match your environment and PHP-FPM worker permissions.
|
||||
|
||||
ContentDetector tuning and false-positive guidance
|
||||
|
||||
- The repository includes a `ContentDetector` that performs a fast head-scan of uploaded files to detect PHP open-tags and common webshell indicators (for example `passthru()`, `system()`, `exec()`, `shell_exec()`, `proc_open()`, `popen()`, `base64_decode()`, `eval()`, `assert()`). It intentionally limits the scan to a small number of bytes to reduce CPU/IO overhead.
|
||||
|
||||
- Tuning options (place these in `upload-logger.json`):
|
||||
- `limits.sniff_max_bytes` (integer): number of bytes to read from the file head for scanning. Default: `8192`.
|
||||
- `limits.sniff_max_filesize` (integer): only perform head-scan on files with size <= this value. Default: `2097152` (2 MB).
|
||||
- `allowlists.ctypes` (array): content-types that should be considered trusted for base64/raw payloads (for example `image/svg+xml`, `application/xml`, `text/xml`) and may relax some detections.
|
||||
- `allowlists.base64_uris` (array): URI patterns that should be ignored for large base64 payloads (webhooks, avatar uploads, etc.).
|
||||
|
||||
- False positives: `eval(` and other tokens commonly appear in client-side JS inside SVG files or in benign templating contexts. If you observe false positives:
|
||||
- Add trusted URIs to `allowlists.base64_uris` for endpoints that legitimately accept encoded content.
|
||||
- Add trusted content-types to `allowlists.ctypes` to relax detection for XML/SVG uploads.
|
||||
- Tune `limits.sniff_max_bytes` and `limits.sniff_max_filesize` to increase or decrease sensitivity.
|
||||
|
||||
- Suggested (example) detector tuning block (commented):
|
||||
|
||||
```json
|
||||
// "detectors": {
|
||||
// "content": {
|
||||
// "enabled": true,
|
||||
// "sniff_max_bytes": 8192,
|
||||
// "sniff_max_filesize": 2097152,
|
||||
// "allow_xml_eval": false
|
||||
// }
|
||||
// }
|
||||
```
|
||||
|
||||
Remove the leading `// ` when copying these example snippets into a real `upload-logger.json` file.
|
||||
# 🔐 Per-Site PHP Upload Guard Integration Guide
|
||||
|
||||
This guide explains how to integrate a global PHP upload monitoring script
|
||||
@@ -44,6 +140,7 @@ mkdir .security/logs
|
||||
````
|
||||
|
||||
Set secure permissions:
|
||||
- Set secure permissions:
|
||||
|
||||
```bash
|
||||
chown -R root:www-data .security
|
||||
@@ -51,6 +148,14 @@ chmod 750 .security
|
||||
chmod 750 .security/logs
|
||||
```
|
||||
|
||||
Quarantine hardening (important):
|
||||
|
||||
- Ensure the quarantine directory is owner `root`, group `www-data`, and mode `0700` so quarantined files are not accessible to other system users. Example provisioning script `scripts/provision_dirs.sh` now enforces these permissions and tightens existing files to `0600`.
|
||||
|
||||
- If using Ansible, the playbook `scripts/ansible/upload-logger-provision.yml` includes a task that sets any existing files in the quarantine directory to `0600` and enforces owner/group.
|
||||
|
||||
- Verify SELinux/AppArmor contexts after provisioning; the script attempts to register fcontext entries and calls `restorecon` when available.
|
||||
|
||||
---
|
||||
|
||||
## 📄 3. Install the Upload Guard Script
|
||||
|
||||
Reference in New Issue
Block a user