Commit Graph

38 Commits

Author SHA1 Message Date
Username
3a76453828 security: implement CRYPTO-001 and TIMING-001 remediations
CRYPTO-001: Certificate serial collision detection
- Add _generate_unique_serial() helper for database-backed PKI
- Add _generate_unique_serial() method for in-memory PKI class
- Check database for existing serial before certificate issuance
- Retry with new random serial if collision detected (max 5 attempts)

TIMING-001: Constant-time database lookups for sensitive queries
- Add dummy PBKDF2 verification when paste not found
- Prevents timing-based enumeration (attackers can't distinguish
  'not found' from 'wrong password' by measuring response time)
2025-12-24 23:28:16 +01:00
Username
c130020ab8 security: implement HASH-001 and ENUM-001 remediations
HASH-001: Add threading lock to content hash deduplication
- Prevents race condition between SELECT and UPDATE
- Ensures accurate dedup counting under concurrent load

ENUM-001: Add rate limiting to paste lookups
- Separate rate limiter for GET/HEAD on paste endpoints
- Default 60 requests/minute per IP (configurable)
- Prevents brute-force paste ID enumeration attacks
2025-12-24 23:12:28 +01:00
Username
da1beca893 security: implement quick win remediations (FLOOD-001, CLI-002, CLI-003, AUDIT-001)
FLOOD-001: Cap anti-flood request list at configurable max entries
- Add ANTIFLOOD_MAX_ENTRIES config (default 10000)
- Prune oldest entries when limit exceeded

CLI-002: Explicitly set SSL hostname verification
- Add ctx.check_hostname = True and ctx.verify_mode = CERT_REQUIRED
- Defense in depth (create_default_context sets these by default)

CLI-003: Warn on insecure config file permissions
- Check if config file is world-readable
- Print warning to stderr if permissions too open

AUDIT-001: Already implemented - query has LIMIT/OFFSET with 500 max
2025-12-24 23:02:55 +01:00
Username
1fbb69d7f9 security: implement pentest remediation (RATE-002, CLI-001)
RATE-002: Proactive rate limit cleanup when entries exceed threshold
- Add RATE_LIMIT_CLEANUP_THRESHOLD config (default 0.8)
- Trigger cleanup before hitting hard limit
- Prevents memory exhaustion under sustained load

CLI-001: Validate clipboard tool paths against trusted directories
- Add TRUSTED_CLIPBOARD_DIRS for Unix system paths
- Add TRUSTED_WINDOWS_PATTERNS for Windows validation
- Reject tools in user-writable locations (PATH hijack prevention)
- Use absolute paths in subprocess calls
2025-12-24 22:03:17 +01:00
Username
89eee3378a security: implement pentest remediation (PROXY-001, BURN-001, RATE-001)
PROXY-001: Add startup warning when TRUSTED_PROXY_SECRET empty in production
- validate_security_config() checks for missing proxy secret
- Additional warning when PKI enabled without proxy secret
- Tests for security configuration validation

BURN-001: HEAD requests now trigger burn-after-read deletion
- Prevents attacker from probing paste existence before retrieval
- Updated test to verify new behavior

RATE-001: Add RATE_LIMIT_MAX_ENTRIES to cap memory usage
- Default 10000 unique IPs tracked
- Prunes oldest entries when limit exceeded
- Protects against memory exhaustion DoS

Test count: 284 -> 291 (7 new security tests)
2025-12-24 21:42:15 +01:00
Username
cf458347ef add systemd service unit and rate limit headers
Systemd deployment:
- examples/flaskpaste.service with security hardening
- examples/flaskpaste.env with all config options
- README deployment section updated

Rate limit headers (X-RateLimit-*):
- Limit, Remaining, Reset on 201 and 429 responses
- Per-IP tracking with auth multiplier
- api.md documented
2025-12-24 17:51:14 +01:00
Username
045f73c998 feat: integrate unused observability features
- Add request duration metrics via before/after request hooks
- Add PKI audit logging: CERT_ISSUED, CERT_REVOKED, AUTH_FAILURE
- Wire up observe_request_duration() from metrics.py
- Log certificate operations (registration, CA gen, issue, revoke)
- Log auth failures for revoked/expired certificates
2025-12-24 16:41:31 +01:00
Username
7063f8718e feat: add observability and CLI enhancements
Audit logging:
- audit_log table with event tracking
- app/audit.py module with log_event(), query_audit_log()
- GET /audit endpoint (admin only)
- configurable retention and cleanup

Prometheus metrics:
- app/metrics.py with custom counters
- paste create/access/delete, rate limit, PoW, dedup metrics
- instrumentation in API routes

CLI clipboard integration:
- fpaste create -C/--clipboard (read from clipboard)
- fpaste create --copy-url (copy result URL)
- fpaste get -c/--copy (copy content)
- cross-platform: xclip, xsel, pbcopy, wl-copy

Shell completions:
- completions/ directory with bash/zsh/fish scripts
- fpaste completion --shell command
2025-12-23 22:39:50 +01:00
Username
ca9342e92d fix: add comprehensive type annotations for mypy
- database.py: add type hints for Path, Flask, Any, BaseException
- pki.py: add assertions to narrow Optional types after has_ca() checks
- routes.py: annotate config values to avoid Any return types
- api/__init__.py: use float for cleanup timestamps (time.time())
- __init__.py: remove unused return from setup_rate_limiting
2025-12-22 19:11:11 +01:00
Username
680b068c00 refactor: code consistency and best practices
- add type hints to error handlers in app/__init__.py
- add docstrings to nested callback functions
- remove deprecated X-XSS-Protection header (superseded by CSP)
- fix typo in cleanup log message (entr(ies) -> entries)
- standardize loop variable naming in fpaste CLI
- update test for intentional header removal
2025-12-22 00:25:18 +01:00
Username
e8a99d5bdd add tiered auto-expiry based on auth level 2025-12-21 21:55:30 +01:00
Username
40873434c3 pki: admin can list/delete any paste
Add is_admin() helper to check if current user is admin.
Update DELETE /<id> to allow admin to delete any paste.
Update GET /pastes to support ?all=1 for admin to list all pastes.
Admin view includes owner fingerprint in paste metadata.
2025-12-21 21:30:50 +01:00
Username
2acf640d91 pki: first registered user gets admin rights
Auto-detect first certificate issuance and grant admin flag.
Add is_admin column to issued_certificates table.
Add is_admin_certificate() helper function.
Include is_admin in /pki/issue response and X-Is-Admin header in registration.
2025-12-21 21:13:30 +01:00
Username
2ccbfcbfaa ci: update linting and security checks
- Fix bandit suppressions (use # nosec B608 for bandit)
- Add # noqa: S608 for ruff compatibility
- CI workflow: add coverage reporting (informational)
- CI workflow: track mypy error baseline
- CI workflow: improve documentation
2025-12-21 13:39:30 +01:00
Username
0c7bf6b587 improve index endpoint with comprehensive API info
- Add all endpoints including PUT, register, PKI
- Show authentication tiers (anonymous/client_cert/trusted)
- Display current limits (size, rate) for each tier
- Show PoW status and difficulty
- Add CLI install/usage hints
- Conditionally show PKI endpoints when enabled
2025-12-21 13:16:49 +01:00
Username
098789ff89 allow untrusted certs to manage own pastes
Split authentication into two functions:
- get_client_fingerprint(): Identity for ownership (any cert)
- get_client_id(): Elevated privileges (trusted certs only)

Behavior:
- Anonymous: Create only, strict limits
- Untrusted cert: Create + delete/update/list own pastes, strict limits
- Trusted cert: All operations, relaxed limits (50MB, 5x rate)

Updated tests to reflect new behavior where revoked certs
can still manage their own pastes.
2025-12-21 12:59:18 +01:00
Username
880bf631e3 fpaste: add register command for public certificate enrollment
- Add register command to obtain client cert from server
- Solve PoW challenge, receive PKCS#12 bundle
- Extract cert/key, optionally update config (--configure)
- Fix registration to work without PKI_ENABLED (only needs PKI_CA_PASSWORD)
- Add skip_enabled_check param to get_ca_info() for registration path
- Update docs: README examples, API header name fix (X-Fingerprint-SHA1)
2025-12-21 10:59:09 +01:00
Username
5849c7406f add /register endpoint for public certificate registration
Public endpoint allows anyone to obtain a client certificate for
authentication. Features:

- Higher PoW difficulty than paste creation (24 vs 20 bits)
- Auto-generates CA on first registration if not present
- Returns PKCS#12 bundle with cert, key, and CA
- Configurable via FLASKPASTE_REGISTER_POW

Endpoints:
- GET /register/challenge - Get registration PoW challenge
- POST /register - Register and receive PKCS#12 bundle
2025-12-21 10:34:02 +01:00
Username
45712ea93f add anti-flood: dynamic PoW difficulty under load
When paste creation rate exceeds threshold, PoW difficulty
increases to slow down attackers. Decays back to base when
abuse stops.

Config:
- ANTIFLOOD_THRESHOLD: requests/window before increase (30)
- ANTIFLOOD_STEP: difficulty bits per step (2)
- ANTIFLOOD_MAX: maximum difficulty cap (28)
- ANTIFLOOD_DECAY: seconds before reducing (30)
2025-12-20 20:45:58 +01:00
Username
a6812af027 remove /solver endpoint 2025-12-20 20:38:02 +01:00
Username
3fe3f6f160 add /solver endpoint for PoW solver script download 2025-12-20 20:32:39 +01:00
Username
bfc238b5cf add CLI enhancements and scheduled cleanup
CLI commands:
- list: show user's pastes with pagination
- search: filter by type (glob), after/before timestamps
- update: modify content, password, or extend expiry
- export: save pastes to directory with optional decryption

API changes:
- PUT /<id>: update paste content and metadata
- GET /pastes: add type, after, before query params

Scheduled tasks:
- Thread-safe cleanup with per-task intervals
- Activate cleanup_expired_hashes (15min)
- Activate cleanup_rate_limits (5min)

Tests: 205 passing
2025-12-20 20:13:00 +01:00
Username
a2c5a013ef docs: update for encrypt-by-default CLI
Update README.md, api.md, and error hints to reflect:
- encryption is now default (no -e flag needed)
- use -E/--no-encrypt to disable
- file path shortcut (fpaste file.txt)
2025-12-20 18:12:00 +01:00
Username
28ee2bae31 add minimum size and binary content enforcement 2025-12-20 17:46:49 +01:00
Username
4e38517faf pki: add minimal certificate authority
- CA generation with encrypted private key storage (AES-256-GCM)
- Client certificate issuance with configurable validity
- Certificate revocation with status tracking
- SHA1 fingerprint integration with existing mTLS auth
- API endpoints: /pki/status, /pki/ca, /pki/issue, /pki/revoke
- CLI commands: fpaste pki status/issue/revoke
- Comprehensive test coverage
2025-12-20 17:20:15 +01:00
Username
7deba711d4 entropy: exempt small content from check
Small data has unreliable entropy measurement due to sample size.
MIN_ENTROPY_SIZE (default 256 bytes) sets the threshold.
2025-12-20 08:48:13 +01:00
Username
8addf2d9e8 add entropy enforcement for optional encryption requirement
Shannon entropy check rejects low-entropy content when MIN_ENTROPY > 0.
Encrypted data ~7.5-8.0 bits/byte, plaintext ~4.0-5.0 bits/byte.
Configurable via FLASKPASTE_MIN_ENTROPY environment variable.
2025-12-20 06:57:50 +01:00
Username
964698428c routes: use detected base URL in usage examples 2025-12-20 05:27:10 +01:00
Username
677d3e5ba1 client: also update help text with detected URL 2025-12-20 05:23:00 +01:00
Username
d6fb2e92af client: auto-detect server URL from request headers 2025-12-20 05:21:55 +01:00
Username
2272b1ff12 add /client endpoint to download fpaste CLI 2025-12-20 05:19:20 +01:00
Username
274648e1f7 fix: return relative URLs in responses, prefix only for docs 2025-12-20 04:48:55 +01:00
Username
5770698847 add URL_PREFIX config for reverse proxy path support 2025-12-20 04:43:36 +01:00
Username
c76a158c18 bump version to 1.1.0, centralize VERSION constant 2025-12-20 04:21:06 +01:00
Username
8fdeeaed9c add proof-of-work spam prevention
Clients must solve a SHA256 hash puzzle before paste creation.
Configurable via FLASKPASTE_POW_DIFFICULTY (0 = disabled, 16 = default).
Challenge tokens expire after FLASKPASTE_POW_TTL seconds (default 300).
2025-12-20 04:03:59 +01:00
Username
4532b9b1d5 add HEAD method for paste endpoints 2025-12-20 03:47:20 +01:00
Username
202e927918 add content-hash dedup for abuse prevention
Throttle repeated submissions of identical content using SHA256 hash
tracking. Configurable via FLASKPASTE_DEDUP_WINDOW and FLASKPASTE_DEDUP_MAX.
2025-12-20 03:31:20 +01:00
Username
8f9868f0d9 flaskpaste: initial commit with security hardening
Features:
- REST API for text/binary pastes with MIME detection
- Client certificate auth via X-SSL-Client-SHA1 header
- SQLite with WAL mode for concurrent access
- Automatic paste expiry with LRU cleanup

Security:
- HSTS, CSP, X-Frame-Options, X-Content-Type-Options
- Cache-Control: no-store for sensitive responses
- X-Request-ID tracing for log correlation
- X-Proxy-Secret validation for defense-in-depth
- Parameterized queries, input validation
- Size limits (3 MiB anon, 50 MiB auth)

Includes /health endpoint, container support, and 70 tests.
2025-12-16 04:42:18 +01:00