jilo-web/tests/Feature/Security/SecurityHeadersTest.php

161 lines
5.5 KiB
PHP
Raw Permalink Normal View History

<?php
namespace Tests\Framework\Integration\Security;
use PHPUnit\Framework\TestCase;
2025-02-20 08:41:14 +00:00
require_once dirname(__DIR__, 3) . '/app/includes/security_headers_middleware.php';
class SecurityHeadersTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
unset($_GET['page']);
unset($_SERVER['HTTPS']);
unset($_SERVER['REQUEST_URI']);
}
public function testBasicSecurityHeaders()
{
// Apply security headers in test mode
$headers = \applySecurityHeaders(true);
2025-02-19 13:31:01 +00:00
// Check security headers
$this->assertContains('X-Frame-Options: DENY', $headers);
$this->assertContains('X-XSS-Protection: 1; mode=block', $headers);
$this->assertContains('X-Content-Type-Options: nosniff', $headers);
$this->assertContains('Referrer-Policy: strict-origin-when-cross-origin', $headers);
}
public function testContentSecurityPolicy()
{
// Apply security headers in test mode
$headers = \applySecurityHeaders(true);
2025-02-19 13:31:01 +00:00
// Get CSP header
$cspHeader = '';
foreach ($headers as $header) {
if (strpos($header, 'Content-Security-Policy:') === 0) {
$cspHeader = $header;
break;
}
}
// Check CSP directives
$this->assertStringContainsString("default-src 'self'", $cspHeader);
$this->assertStringContainsString("script-src 'self' 'unsafe-inline' 'unsafe-eval'", $cspHeader);
$this->assertStringContainsString("style-src 'self' 'unsafe-inline'", $cspHeader);
$this->assertStringContainsString("frame-ancestors 'none'", $cspHeader);
$this->assertStringContainsString("form-action 'self'", $cspHeader);
$this->assertStringContainsString("base-uri 'self'", $cspHeader);
}
public function testHstsHeader()
{
// Simulate HTTPS
$_SERVER['HTTPS'] = 'on';
// Apply security headers in test mode
$headers = \applySecurityHeaders(true);
// Check HSTS header
$this->assertContains(
'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload',
$headers
);
}
public function testNoHstsHeaderOnHttp()
{
// Apply security headers in test mode
$headers = \applySecurityHeaders(true);
// Check HSTS header is not present
$hasHsts = false;
foreach ($headers as $header) {
if (strpos($header, 'Strict-Transport-Security:') === 0) {
$hasHsts = true;
break;
}
}
$this->assertFalse($hasHsts, 'HSTS header should not be present on HTTP');
}
public function testCacheControlForSensitivePages()
{
$sensitivePages = ['login', 'register', 'profile', 'security'];
foreach ($sensitivePages as $page) {
// Set current page
$_GET['page'] = $page;
// Apply security headers in test mode
$headers = \applySecurityHeaders(true);
// Check cache control headers
$this->assertContains('Cache-Control: no-store, no-cache, must-revalidate, max-age=0', $headers);
$this->assertContains('Pragma: no-cache', $headers);
$this->assertStringContainsString('Expires:', implode(' ', $headers));
}
}
public function testNoCacheControlForNonSensitivePages()
{
$_GET['page'] = 'dashboard';
// Apply security headers in test mode
$headers = \applySecurityHeaders(true);
// Check cache control headers are not present
$this->assertNotContains('Cache-Control: no-store, no-cache, must-revalidate, max-age=0', $headers);
$this->assertNotContains('Pragma: no-cache', $headers);
}
public function testPermissionsPolicy()
{
// Apply security headers in test mode
$headers = \applySecurityHeaders(true);
// Get Permissions-Policy header
$permissionsHeader = '';
foreach ($headers as $header) {
if (strpos($header, 'Permissions-Policy:') === 0) {
$permissionsHeader = $header;
break;
}
}
// Check basic permissions
$this->assertStringContainsString('geolocation=()', $permissionsHeader);
$this->assertStringContainsString('payment=()', $permissionsHeader);
$this->assertStringContainsString('camera=()', $permissionsHeader);
$this->assertStringContainsString('microphone=()', $permissionsHeader);
$this->assertStringContainsString('fullscreen=(self)', $permissionsHeader);
$this->assertStringContainsString('sync-xhr=(self)', $permissionsHeader);
}
public function testPermissionsPolicyForMediaEnabledPages()
{
$_SERVER['REQUEST_URI'] = '/media/upload';
2025-02-19 13:31:01 +00:00
// Apply security headers in test mode
$headers = \applySecurityHeaders(true);
2025-02-19 13:31:01 +00:00
// Get Permissions-Policy header
$permissionsHeader = '';
foreach ($headers as $header) {
if (strpos($header, 'Permissions-Policy:') === 0) {
$permissionsHeader = $header;
break;
}
}
// Check permissions policy header
$this->assertStringContainsString('camera=()', $permissionsHeader);
$this->assertStringContainsString('microphone=()', $permissionsHeader);
$this->assertStringContainsString('geolocation=()', $permissionsHeader);
$this->assertStringContainsString('payment=()', $permissionsHeader);
}
}