diff --git a/ROADMAP.md b/ROADMAP.md index 4df5d56..ed3e9ca 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,11 +2,11 @@ ## Current State -FlaskPaste v1.5.0 is deployed with comprehensive security hardening and abuse prevention. +FlaskPaste v1.5.1 is deployed with comprehensive security hardening and abuse prevention. **Implemented:** - Full REST API (CRUD operations) -- Binary content support with magic-byte MIME detection +- Binary content support with text/binary MIME detection - Client certificate authentication - Minimal PKI (CA generation, certificate issuance, revocation) - Content-hash deduplication (abuse prevention) diff --git a/TODO.md b/TODO.md index ccaf56e..cfd1b25 100644 --- a/TODO.md +++ b/TODO.md @@ -12,7 +12,7 @@ Unstructured intake buffer for ideas, issues, and observations. Items here are r - Design: compress-then-encrypt only (not compress-only) - Compressed data has high entropy → bypasses entropy enforcement - Must enforce encryption when compression enabled (CLI-side) - - Server detects compression formats via magic bytes (REQUIRE_BINARY) + - Server rejects plaintext via REQUIRE_BINARY (UTF-8 detection) - ETag support for conditional requests - Neovim/Vim plugin for editor integration - Webhook notifications for paste events @@ -53,8 +53,8 @@ Unstructured intake buffer for ideas, issues, and observations. Items here are r ## External Dependencies -- Consider adding `python-magic` for better MIME detection (currently magic bytes only) - cryptography package required for PKI features (optional otherwise) +- For full MIME detection, consider `filetype` library (currently text/binary only) --- diff --git a/documentation/api.md b/documentation/api.md index 098cd4d..b97f066 100644 --- a/documentation/api.md +++ b/documentation/api.md @@ -707,17 +707,16 @@ export FLASKPASTE_MIN_ENTROPY_SIZE=256 # Only check content >= this size (defaul ### Binary Content Requirement -FlaskPaste can require unrecognizable binary content (MIME-based encryption enforcement). +FlaskPaste can require unrecognizable binary content (encryption enforcement). **How it works:** -- Content is checked for magic bytes (PNG, JPEG, PDF, ZIP, etc.) - Content is checked for valid UTF-8 text -- Recognized formats are rejected with 400 -- Only application/octet-stream (unrecognizable binary) is allowed +- Plaintext (valid UTF-8) is rejected with 400 +- Only binary content (invalid UTF-8) is allowed **Configuration:** ```bash -export FLASKPASTE_REQUIRE_BINARY=1 # Reject recognizable formats (0=disabled) +export FLASKPASTE_REQUIRE_BINARY=1 # Reject plaintext (0=disabled) ``` **Response (400 Bad Request):** @@ -729,16 +728,11 @@ export FLASKPASTE_REQUIRE_BINARY=1 # Reject recognizable formats (0=disabled) } ``` -**Detected formats:** -- `text/plain` (valid UTF-8 text) -- `image/png`, `image/jpeg`, `image/gif`, `image/webp` -- `application/pdf`, `application/zip`, `application/gzip` - **vs Entropy enforcement:** -| Method | Detects | False positives | -|--------|---------|-----------------| -| Entropy | Random-looking data | Compressed files pass | -| Binary | No magic bytes + invalid UTF-8 | Minimal | +| Method | Detects | Use case | +|--------|---------|----------| +| Entropy | Low-entropy data | Reject unencrypted content | +| Binary | Valid UTF-8 text | Reject plaintext | Use both together for maximum encryption enforcement: ```bash diff --git a/documentation/mime-security-assessment.md b/documentation/mime-security-assessment.md index bec48ea..eeac838 100644 --- a/documentation/mime-security-assessment.md +++ b/documentation/mime-security-assessment.md @@ -1,5 +1,10 @@ # MIME Detection Security Assessment +> **Note (v1.5.1):** Magic byte detection has been simplified to UTF-8 validation only. +> Content is now classified as `text/plain` (valid UTF-8) or `application/octet-stream` (binary). +> Security headers (nosniff, CSP) provide the primary defense against MIME confusion attacks. +> This document is retained for historical reference. + Penetration testing of FlaskPaste's magic byte-based MIME detection system. --- diff --git a/documentation/security-testing-status.md b/documentation/security-testing-status.md index fb1890b..0b3809e 100644 --- a/documentation/security-testing-status.md +++ b/documentation/security-testing-status.md @@ -328,14 +328,13 @@ DEDUP_MAX = 3 # Max duplicates allowed | X-Content-Type-Options | nosniff | Yes | | Content-Security-Policy | default-src 'none' | Yes | | X-Frame-Options | DENY | Yes | -| Magic byte detection | First 16 bytes, 45 signatures | Yes | +| MIME detection | UTF-8 validation (text/binary) | Yes | | Input sanitization | Werkzeug header handling | Yes | | SQL injection prevention | SQLAlchemy parameterized queries | Yes | | SSTI prevention | No user content in templates | Yes | | Path traversal prevention | ID validation regex | Yes | | Constant-time password check | PBKDF2 600k iterations | Yes | | Burn-after-read race condition | HEAD triggers deletion | Yes | -| RIFF container detection | Subtype check (WEBP/AVI/WAVE) | Yes | | Clipboard command injection | Trusted path validation | Yes | | Memory exhaustion prevention | Max entries on all dicts | Yes | | Race condition protection | Threading locks on counters | Yes | diff --git a/documentation/threat-model.md b/documentation/threat-model.md index 42beecf..377b96a 100644 --- a/documentation/threat-model.md +++ b/documentation/threat-model.md @@ -191,28 +191,27 @@ User Input Flow: ## MIME Detection Security -Content is detected by magic bytes, not user-supplied Content-Type: +Content is detected by UTF-8 validation (text vs binary): ``` -User uploads "image.png" with PHP payload +User uploads content | v -[Magic byte detection] --> Not PNG magic --> text/plain - | +[UTF-8 validation] --> Valid UTF-8 --> text/plain + | Invalid --> application/octet-stream + v [X-Content-Type-Options: nosniff] --> Browser won't sniff | [CSP: default-src 'none'] --> No script execution ``` -### Polyglot Attack Mitigations +### Security Headers (Primary Defense) -| Attack | Detection | Result | -|--------|-----------|--------| -| PNG + HTML | PNG magic detected | image/png | -| GIF + JS | GIF magic detected | image/gif | -| PDF + ZIP | PDF magic detected | application/pdf | -| SVG + script | No XML magic | text/plain | -| JPEG + PHP | JPEG magic detected | image/jpeg | +| Header | Value | Protection | +|--------|-------|------------| +| X-Content-Type-Options | nosniff | Prevents MIME sniffing | +| Content-Security-Policy | default-src 'none' | Blocks script execution | +| X-Frame-Options | DENY | Prevents framing | ---