Procházet zdrojové kódy

Fix R01-N02 / R01-N31: gate runtime panel on home page to admins

Anonymous visitors to `/` were shown a Runtime <details> panel that leaked
PHP_VERSION, APP_ENV, the SQLite file path, the schema version, and the
OIDC / local-admin enablement flags — recon gold for a casual scanner.
The same block also exposed a "/healthz" hint (R01-N31).

Tightens the existing twig guard from
`{% if currentUser is null or currentUser.isAdmin %}`
to
`{% if currentUser is not null and currentUser.isAdmin %}`
so the panel renders only for signed-in admins. Public liveness probing
still works at `/healthz` itself; only the in-page hint goes away.

Locks the new behaviour in TwigViewTest::testHomeForAnonymousUserHidesRuntimePanel,
asserting the leaked strings are absent from the anonymous render.
Suite: 150 / 430 (was 149 / 424).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chiappa před 2 dny
rodič
revize
7fd849bb92
2 změnil soubory, kde provedl 27 přidání a 1 odebrání
  1. 26 0
      tests/Http/TwigViewTest.php
  2. 1 1
      views/home.twig

+ 26 - 0
tests/Http/TwigViewTest.php

@@ -59,6 +59,32 @@ final class TwigViewTest extends TestCase
         self::assertStringContainsString('/assets/js/vendor/htmx.min.js', $html);
     }
 
+    public function testHomeForAnonymousUserHidesRuntimePanel(): void
+    {
+        $html = $this->view->render('home', [
+            'title'             => 'Sprint Planner',
+            'csrfToken'         => 'tok',
+            'currentUser'       => null,
+            'schemaVersion'     => 3,
+            'dbPath'            => '/var/data/app.sqlite',
+            'appEnv'            => 'production',
+            'oidcConfigured'    => true,
+            'localAdminEnabled' => true,
+            'authError'         => false,
+            'sprintRows'        => [],
+        ]);
+
+        self::assertStringContainsString('Sign in with Microsoft', $html);
+        // R01-N02: the Runtime <details> panel must not leak PHP_VERSION,
+        // dbPath, schema version, OIDC/local-admin flags to anonymous visitors.
+        self::assertStringNotContainsString('Runtime', $html);
+        self::assertStringNotContainsString('Schema version', $html);
+        self::assertStringNotContainsString('/var/data/app.sqlite', $html);
+        self::assertStringNotContainsString(PHP_VERSION, $html);
+        // R01-N31 falls out of the same gate: no /healthz hint either.
+        self::assertStringNotContainsString('/healthz', $html);
+    }
+
     public function testAuditRendersWithEmptyResults(): void
     {
         $html = $this->view->render('audit/index', [

+ 1 - 1
views/home.twig

@@ -109,7 +109,7 @@
         </div>
     {% endif %}
 
-    {% if currentUser is null or currentUser.isAdmin %}
+    {% if currentUser is not null and currentUser.isAdmin %}
     <details class="rounded-lg border bg-white p-4 dark:bg-slate-800 dark:border-slate-700">
         <summary class="text-sm font-semibold text-slate-700 uppercase tracking-wider cursor-pointer dark:text-slate-200">Runtime</summary>
         <dl class="mt-3 grid grid-cols-[max-content_1fr] gap-x-6 gap-y-1 text-sm">