diff --git a/TODO.md b/TODO.md index b556239..1a17db3 100644 --- a/TODO.md +++ b/TODO.md @@ -1,9 +1,10 @@ # TODO > Last updated: 2026-06-24 -> Context: Setup biome + rolldown + lightningcss build pipeline for JS/CSS bundling & minification +> Context: Security audit — fix open redirects, fragment auth, dead code, CSRF gaps ## Completed +- [x] #sec-open-redirect Fix open redirect in tag.php + language.php (protocol-relative URL bypass via str_starts_with) ✓ - [x] #build-pipeline Setup biome + rolldown + lightningcss build pipeline ✓ - [x] #build-packagejson Create package.json with devDependencies ✓ - [x] #build-biomecss Update biome.json to handle CSS formatting ✓ @@ -15,6 +16,9 @@ - [x] #build-cssfix Fix stray `}` syntax error in admin.css line 305 ✓ ## Pending +- [ ] #sec-fragments-auth Gate partagé fragments on share_active session + CSRF `(partage/fragments/*.php, partage/index.php)` +- [ ] #sec-retry-csrf Add CSRF check to partage/retry-email.php POST +- [ ] #sec-cleanup-dead-code Remove dead App::verifyCsrf() or refactor action handlers to use it - [ ] #rep-student-touch Replace hover student popover with tap-to-open drawer for mobile `(repertoire.php, repertoire.css)` - [ ] #rep-polish Polish: scroll-position memory on HTMX swap, animation tuning `(repertoire.css)` - [ ] #icon-color-verify Verify icon colors render correctly across all pages (header, admin tables, forms, dialogs, cleanup modal) diff --git a/app/public/admin/actions/language.php b/app/public/admin/actions/language.php index 6242d1f..c171f70 100644 --- a/app/public/admin/actions/language.php +++ b/app/public/admin/actions/language.php @@ -74,9 +74,10 @@ try { } $redirect = '/admin/contenus.php'; -// Allow the caller to override the redirect -if (!empty($_POST['return']) && str_starts_with($_POST['return'], '/')) { - $redirect = $_POST['return']; +// Allow the caller to override the redirect (same-origin only, no protocol-relative) +$return = $_POST['return'] ?? ''; +if ($return !== '' && str_starts_with($return, '/') && !str_starts_with($return, '//')) { + $redirect = $return; } header('Location: ' . $redirect); exit(); diff --git a/app/public/admin/actions/tag.php b/app/public/admin/actions/tag.php index abcb191..b7936ab 100644 --- a/app/public/admin/actions/tag.php +++ b/app/public/admin/actions/tag.php @@ -79,9 +79,10 @@ try { } $redirect = '/admin/tags.php'; -// Allow the caller to override the redirect -if (!empty($_POST['return']) && str_starts_with($_POST['return'], '/')) { - $redirect = $_POST['return']; +// Allow the caller to override the redirect (same-origin only, no protocol-relative) +$return = $_POST['return'] ?? ''; +if ($return !== '' && str_starts_with($return, '/') && !str_starts_with($return, '//')) { + $redirect = $return; } header('Location: ' . $redirect); exit();