Files
xamxam/docs/TODO.SECURITY.md
Théophile Gervreau-Mercier 8613f71112 security: add PHP session auth guard for admin panel (item #2, CRITICAL)
- lib/AdminAuth.php: new class with requireLogin(), login(), logout(),
  isAuthenticated(); starts session with hardened cookie params
  (HttpOnly, SameSite=Strict, Secure, Path=/admin) — also resolves
  item #8 (session cookie hardening)
- requireLogin() auto-authenticates from nginx Basic Auth credentials
  ($_SERVER['PHP_AUTH_PW']) so the user only sees one browser prompt;
  falls back to /admin/login.php if the proxy is absent/misconfigured
- config/admin_credentials.php: gitignored credential store; define
  ADMIN_PASSWORD_HASH with a bcrypt hash to enable PHP auth
- config/admin_credentials.example.php: template for the above
- config/bootstrap.php: auto-loads admin_credentials.php if present
- .gitignore: exclude config/admin_credentials.php
- public/admin/login.php: fallback login form (shown only when nginx
  Basic Auth is bypassed / proxy absent)
- public/admin/logout.php: session destruction + redirect to login
- All 7 admin PHP files: replace session_start() with
  AdminAuth::requireLogin() (defence-in-depth behind nginx Basic Auth)
- public/admin/inc/head.php: Déconnexion button when ADMIN_PASSWORD_HASH
  is defined
- nginx/PHP_AUTH_LAYER.md: documents dual-auth architecture, UX flow,
  and setup instructions
- docs/TODO.SECURITY.md: items #2 and #8 moved to Resolved; priority
  order updated (all CRITICAL done)
2026-02-08 14:22:45 +01:00

102 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🔒 Security TODO — posterg-website
> Based on `docs/SECURITY_ANALYSIS.md` (2026-02-08).
> Tracks resolution status for all identified vulnerabilities.
---
## ✅ Resolved
### Infrastructure / Deployment
| # | Issue | Severity | Resolution |
|---|-------|----------|------------|
| 1 | No HTTPS — admin credentials exposed in transit | 🔴 CRITICAL | **TLS is terminated upstream by the reverse proxy** (outside nginx). nginx.conf does not need to handle TLS directly. |
| 3 | Uploaded files stored inside the webroot | 🟠 HIGH | Storage moved to `STORAGE_ROOT` (`/var/www/posterg/storage/`), defined in `config/bootstrap.php`. `formulaire.php` updated. |
| 4 | File path mismatch — media files broken and insecure | 🟠 HIGH | DB paths are now storage-relative (`theses/YEAR/ID/file`, `covers/file`). New controller `public/media.php` serves files safely. `memoire.php` and `search.php` updated to use `/media.php?path=…`. Cover recording in `formulaire.php` fixed (was never inserted into DB). |
| 5 | Rate limiter bypassed by IP spoofing (`X-Forwarded-For`) | 🟠 HIGH | `lib/RateLimit.php` `getClientIdentifier()` now uses `REMOTE_ADDR` only. |
| 6 | `.htaccess` security rules silently ignored by nginx | 🟠 HIGH | All rules ported to `nginx/posterg.conf` (CSP to `/admin/` block, `.log` denial, `autoindex off`). See `nginx/HTACCESS_TO_NGINX.md`. |
| 13 | Deprecated `X-XSS-Protection` header | 🔵 LOW | **Removed** from `nginx/posterg.conf`; see `nginx/SECURITY_HEADERS.md` for rationale. |
---
### Frontend / Assets
| # | Issue | Severity | Resolution |
|---|-------|----------|------------|
| 10 | CDN stylesheet (water.css) without Subresource Integrity | 🟡 MEDIUM | **CDN will not be used in production.** The stylesheet will be self-hosted, eliminating the supply-chain risk entirely. |
---
### Frontend
| # | Issue | Severity | Resolution |
|---|-------|----------|------------|
| 14 | Missing `rel="noreferrer"` on external `target="_blank"` links | 🔵 LOW | `rel="noopener noreferrer"` applied in `public/admin/thanks.php`. |
---
### Code Quality / Defence in Depth
| # | Issue | Severity | Resolution |
|---|-------|----------|------------|
| 15 | Unescaped integer outputs (inconsistency) | 🔵 LOW | Explicit `(int)` casts added in `public/index.php` and `public/search.php`. |
| 16 | Redundant `DATABASE_PATH` constant never used | 🔵 LOW | `define('DATABASE_PATH', …)` removed from `config/bootstrap.php`. |
---
### Admin Panel — Authentication & Sessions
| # | Issue | Severity | Resolution |
|---|-------|----------|------------|
| 2 | No PHP-level authentication in admin panel | 🔴 CRITICAL | `lib/AdminAuth.php` implements a session guard with `password_verify` + `session_regenerate_id`. All admin PHP files now call `AdminAuth::requireLogin()` instead of bare `session_start()`. Credentials stored in gitignored `config/admin_credentials.php` (define `ADMIN_PASSWORD_HASH`). No-op when constant is absent (dev / cli-server). Also resolves item #8 (session cookie hardening via `session_set_cookie_params` before `session_start`). See `nginx/PHP_AUTH_LAYER.md`. |
| 8 | Session cookies not hardened (`Secure`, `HttpOnly`, `SameSite` missing) | 🟡 MEDIUM | **Resolved as part of item #2.** `AdminAuth::startSession()` sets `HttpOnly=true`, `SameSite=Strict`, `Secure=true` (off on cli-server), `Path=/admin`, `Lifetime=0` before every `session_start()`. |
---
## 🔧 In Progress
### Database / Input Handling
| # | Issue | Severity | Status |
|---|-------|----------|--------|
| 7 | LIKE wildcard injection in admin search (`public/admin/index.php`) | 🟡 MEDIUM | **Needs standardisation of DB input sanitisation across the whole codebase.** The public `Database::searchTheses()` already escapes `%` and `_` correctly; the same pattern must be applied to admin search and any other raw LIKE queries. |
---
## ❌ Not Yet Implemented
### Infrastructure / Deployment
| # | Issue | Severity | Files |
|---|-------|----------|-------|
| 11 | Missing Content-Security-Policy on public pages | 🟡 MEDIUM | `nginx/posterg.conf` → add `Content-Security-Policy` header to main server block (admin already has CSP via item #6) |
---
### Admin Panel — Error Logging
| # | Issue | Severity | Files |
|---|-------|----------|-------|
| 9 | `error.log` written to a web-accessible path | 🟡 MEDIUM | `public/admin/actions/formulaire.php` → use absolute path outside webroot |
---
### File Import
| # | Issue | Severity | Files |
|---|-------|----------|-------|
| 12 | CSV import missing server-side MIME validation | 🟡 MEDIUM | `public/admin/import.php` → add `finfo` MIME check |
---
## Priority Order for Remaining Work
1. 🔴 **CRITICAL** — ✅ All done (items 12)
2. 🟡 **MEDIUM** — Items 7, 9, 11, 12 (sanitisation standardisation, error log, CSP, CSV MIME) — item 8 resolved with item 2
3. 🔵 **LOW** — ✅ All done (items 1316)
---
*Last updated: 2026-02-08*