mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 08:09:18 +02:00
5.3 KiB
5.3 KiB
De-librairisation Plan
Why
XAMXAM currently contains ~3,300 lines of custom code implementing common infrastructural concerns that well-maintained ecosystem libraries have already solved — correctly, securely, and with years of security audits and edge-case hardening behind them. By replacing these bespoke implementations with off-the-shelf packages we:
- Eliminate attack surface — we stop maintaining our own SMTP client, HTTP client, and Markdown parser.
- Reduce maintenance burden — each line of infrastructure code we own is a line we must understand, debug, and keep secure. Off-the-shelf libs shift that to dedicated maintenance teams.
- Gain features for free — DKIM signing, TLS 1.3, connection pooling, async I/O, proper content security — all things we would never build ourselves.
- Make the codebase smaller and more readable — the remaining code is actual application logic, not protocol plumbing.
What we replace
| # | Component | Current size | Replaced by | Why |
|---|---|---|---|---|
| 1 | Markdown parser | ~1770 lines | league/commonmark 2.x |
Parsedown 1.8.0 is unmaintained since 2019. It has known XSS vulnerabilities fixed in later versions that never shipped. league/commonmark is the de-facto standard, actively maintained, security-audited, and supports GFM extensions (tables, strikethrough, autolinks). |
| 2 | SMTP client | ~680 lines | phpmailer/phpmailer 6.x |
Raw socket SMTP with manual STARTTLS negotiation is one of the hardest things to get right in application code. PHPMailer handles TLS 1.3, DKIM, MIME encoding, character sets, connection pooling — all things our custom code does not. |
| 3 | HTTP client | ~200 lines | guzzlehttp/guzzle 7.x |
PeerTubeService::httpRequest() uses file_get_contents() with stream_context_create(). Manual JSON parsing, no retry logic, no connection reuse, fragile error handling. Guzzle is the PHP HTTP standard. |
| 4 | Encryption | ~86 lines | defuse/php-encryption 2.x |
Our AES-256-GCM implementation is actually correct, but home-rolled crypto is never recommended. defuse/php-encryption is the recommended library by the PHP security community. Requires migration of existing encrypted data. |
What we keep (and why)
| Component | Why keep |
|---|---|
password_hash() / password_verify() |
Already the correct approach — PHP's built-in bcrypt. No library needed. |
CSRF (App.php) |
Implementation is correct: 256-bit random token, hash_equals() verification, rotated after mutations. A Symfony CSRF component would be an upgrade but not urgent. |
Rate limiter (RateLimit.php) |
Adequate for current scale. A concurrent-safe Symfony rate-limiter would be better but the file race condition is low-risk at our traffic levels. |
| PHP templates | Plain PHP include with extract() is fast, simple, and well-understood. Auto-escaping (Twig) would be a security upgrade but the migration cost is high and content is mostly admin-controlled. |
| Logging | error_log() with JSON-lines is sufficient. Monolog would be cleaner but adds no security benefit. |
Composer setup
The project currently has no composer.json. PHP CS Fixer and PHPStan
were installed manually into vendor/bin/. We will:
- Create
composer.jsonwith the four packages above. - Run
composer installto populatevendor/. - Keep existing PHP CS Fixer and PHPStan configs — they already work.
Migration order (by risk)
Phase 1: Markdown parser (low risk, high payoff)
- Surface: 4 files import Parsedown
- API similarity:
$pd->text($input)→$converter->convert($input) - SafeMode equivalent:
league/commonmarkis safe by default (no raw HTML in safe mode) - No data migration needed: input is Markdown strings, output is HTML — both are ephemeral and regenerated on each page load
- Files to change:
app/src/Controllers/AboutController.phpapp/src/Controllers/LicenceController.phpapp/templates/partials/form/form-help-block.phpapp/public/admin/form-help-inline-fragment.php
Phase 2: HTTP client (low risk, PeerTube-specific)
- Surface:
app/src/PeerTubeService.phponly - No data migration needed: purely a transport layer replacement
- Can be done independently of Phase 1
Phase 3: SMTP client (medium risk, needs testing)
- Surface:
app/src/SmtpRelay.php - API change:
SmtpRelay::send($db, $to, $subject, $htmlBody)signature stays, but internals replaced with PHPMailer - No data migration needed: SMTP settings in DB are read identically
- Must test: actual email sending to a real SMTP server before deploying
Phase 4: Encryption (highest risk, requires migration)
- Surface:
app/src/Crypto.php,app/src/ShareLink.php,app/src/AdminAuth.php - Affects: encrypted passwords in
share_links.encrypted_password, SMTP password insite_settings - Migration required: decrypt all values with old Crypto, re-encrypt with defuse/php-encryption, write migration script
- Do last, and only if the risk/reward is worth it (our current implementation is actually correct)
Target state
After all phases, the codebase loses ~2,700 lines of infrastructure code and gains four well-maintained dependencies with known security postures and upgrade paths.