Die Lato-Dateien liegen jetzt unter public/assets/fonts/ samt OFL-Text und einer Lizenznotiz: auf einem frischen Server fehlt nichts, und es wird nie versehentlich von Google geladen. docs/NEUE-WEBSITE.md beschreibt, wie eine neue Kundenwebsite entsteht - Reihenfolge, Dokumentformat, Bilder, SEO, Pruefungen - und nennt am Ende die fuenf Fehler, die hier immer wieder passiert sind. Permissions-Policy ergaenzt (Kamera, Mikrofon, Standort, Sensoren aus), X-Powered-By entfernt: der Server nannte in jeder Antwort seine genaue PHP-Fassung. Die Browserpruefung misst die Kopfzeilen jetzt. Behoben: der Editor kannte Schema v17, der Validator v18 - die Beitragsnavigation liess sich in keinem aktuellen Dokument einfuegen. Ein Test bindet die Zahl des Editors an die des Validators. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
32 lines
1.5 KiB
PHP
32 lines
1.5 KiB
PHP
<?php
|
|
|
|
namespace App\EventSubscriber;
|
|
|
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
|
use Symfony\Component\HttpKernel\Event\ResponseEvent;
|
|
use Symfony\Component\HttpKernel\KernelEvents;
|
|
|
|
final class AdminHeadersSubscriber implements EventSubscriberInterface
|
|
{
|
|
public static function getSubscribedEvents(): array
|
|
{
|
|
return [KernelEvents::RESPONSE => ['onResponse', -300]];
|
|
}
|
|
|
|
public function onResponse(ResponseEvent $event): void
|
|
{
|
|
if (!preg_match('#^/admin(?:/|$)#', $event->getRequest()->getPathInfo())) {
|
|
return;
|
|
}
|
|
$headers = $event->getResponse()->headers;
|
|
$headers->set('Cache-Control', 'private, no-store');
|
|
$headers->set('X-Robots-Tag', 'noindex, nofollow');
|
|
$headers->set('X-Content-Type-Options', 'nosniff');
|
|
$headers->set('Referrer-Policy', 'same-origin');
|
|
$headers->set('Permissions-Policy', 'accelerometer=(), camera=(), display-capture=(), geolocation=(), gyroscope=(), microphone=(), payment=(), usb=()');
|
|
// The preview must show the same typeface as the published page, so the font hosts are
|
|
// allowed here as well. Everything else stays as narrow as on the public side.
|
|
$headers->set('Content-Security-Policy', "default-src 'self'; script-src 'self'; style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' https:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'");
|
|
}
|
|
}
|