Files
portal/app/tests/Feature/SecurityHeadersTest.php
T
Дмитрий 380aedb04e feat(security): CSP Report-Only под Vue+Vuetify SPA — 2-я ZAP Medium go-live
Report-Only политика в middleware SecurityHeaders; Pest 6/6 GREEN.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:30:51 +03:00

41 lines
1.7 KiB
PHP

<?php
declare(strict_types=1);
/**
* SecurityHeaders middleware — безопасные HTTP-заголовки на всех web-ответах.
* Закрывает ZAP Medium «Missing Anti-clickjacking Header» (go-live аудит 17.06.2026).
* Бьём по публичному / (welcome SPA) — auth и БД не нужны.
*/
test('публичный / отдаёт заголовок X-Frame-Options SAMEORIGIN', function () {
$this->get('/')->assertHeader('X-Frame-Options', 'SAMEORIGIN');
});
test('публичный / отдаёт X-Content-Type-Options nosniff', function () {
$this->get('/')->assertHeader('X-Content-Type-Options', 'nosniff');
});
test('публичный / отдаёт Referrer-Policy strict-origin-when-cross-origin', function () {
$this->get('/')->assertHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
});
test('публичный / отдаёт непустой Content-Security-Policy-Report-Only', function () {
$csp = $this->get('/')->headers->get('Content-Security-Policy-Report-Only');
expect($csp)->not->toBeNull()
->and($csp)->toContain("default-src 'self'");
});
test('CSP Report-Only выверен под Vuetify-инлайн-стили и шрифты Google', function () {
$csp = $this->get('/')->headers->get('Content-Security-Policy-Report-Only');
expect($csp)->toContain("frame-ancestors 'self'")
->and($csp)->toContain("style-src 'self' 'unsafe-inline' https://fonts.googleapis.com")
->and($csp)->toContain('https://fonts.gstatic.com');
});
test('на шаге Report-Only блокирующий Content-Security-Policy НЕ ставится', function () {
$this->get('/')->assertHeaderMissing('Content-Security-Policy');
});