diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..5565cdd --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,39 @@ +name: SecureHeaders +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + paths-ignore: + - 'docs/**' + - '*.md' + +jobs: + test: + if: "!contains(github.event.head_commit.message, 'skip ci') && !contains(github.event.head_commit.message, 'ci skip')" + name: SecureHeaders (PHP ${{ matrix.php-versions }}) + runs-on: ubuntu-latest + # env: + # DB_CHARSET: utf8 + strategy: + fail-fast: false + matrix: + php-versions: ['8.1', '8.2'] + + + steps: + + - name: Checkout. + uses: actions/checkout@v4 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + + - name: Install composer dependencies + run: composer install --prefer-dist --no-interaction + + - name: Run tests + run: ./vendor/bin/phpunit + + - name: Run PHP CS Fixer + run: ./vendor/bin/php-cs-fixer fix --dry-run --diff diff --git a/.gitignore b/.gitignore index 2aefb37..950671b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ phpunit.xml .DS_Store .php_cs .php_cs.cache +.php-cs-fixer.cache +.phpunit.result.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..d66337a --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,39 @@ +in(__DIR__.'/src') +; + +return (new \PhpCsFixer\Config()) + ->setRules([ + '@PER-CS' => true, + '@PHP82Migration' => true, + 'array_syntax' => ['syntax' => 'short'], + + 'braces_position' => [ + 'control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end', + 'anonymous_functions_opening_brace' => 'next_line_unless_newline_at_signature_end', + ], + 'new_with_parentheses' => [ + 'named_class' => false + ], + 'list_syntax' => [ + 'syntax' => 'long' + ], + 'trailing_comma_in_multiline' => [ + 'elements' => [] + ], + 'control_structure_continuation_position' => [ + 'position' => 'next_line' + ], + 'concat_space' => [ + 'spacing' => 'none' + ], + 'single_line_empty_body' => false, + 'not_operator_with_space' => true, + 'return_type_declaration' => [ + 'space_before' => 'one', + ], + ]) + ->setFinder($finder) +; diff --git a/.php_cs.dist b/.php_cs.dist deleted file mode 100644 index e30f7a4..0000000 --- a/.php_cs.dist +++ /dev/null @@ -1,26 +0,0 @@ -in(__DIR__); - -$rules = [ - '@PSR2' => true, - 'array_syntax' => [ - 'syntax' => 'short', - ], - 'braces' => [ - 'position_after_control_structures' => 'next', - 'position_after_return_type_hint' => 'next', - 'position_after_anonymous_constructs' => 'next', - ], - 'not_operator_with_space' => true, - 'return_type_declaration' => [ - 'space_before' => 'one', - ], -]; -return Config::create() - ->setRules($rules) - ->setFinder($finder) - ->setUsingCache(false); diff --git a/composer.json b/composer.json index 230cb40..3707210 100644 --- a/composer.json +++ b/composer.json @@ -32,21 +32,15 @@ "Aidantwoods\\SecureHeaders\\": "src/" } }, - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/aidantwoods/PHP-CS-Fixer" - } - ], "suggest": { "psr/http-message": "In case you want to use the PSR-7 adapter", "aidantwoods/markdownphpdocs": "Install this on its own and add it to your path, to auto-generate documentation if contributing to this repo." }, "require-dev": { - "friendsofphp/php-cs-fixer": "dev-feature/braces/position_after_return_type_hint", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4", - "psr/http-message": "^1.0", - "zendframework/zend-diactoros": "^1.0" + "friendsofphp/php-cs-fixer": "3.38.*", + "phpunit/phpunit": "10.4.*", + "psr/http-message": "1.1.*", + "zendframework/zend-diactoros": "1.3.*" }, "autoload-dev": { "psr-4": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 5e8b4a3..7850adc 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,16 +1,10 @@ diff --git a/src/Headers/AbstractHeader.php b/src/Headers/AbstractHeader.php index 24c2a46..aa16953 100644 --- a/src/Headers/AbstractHeader.php +++ b/src/Headers/AbstractHeader.php @@ -190,7 +190,7 @@ public function forEachAttribute(callable $callable) */ public function __toString() { - return $this->name . ':' .($this->value === '' ? '' : ' ' . $this->value); + return $this->name.':'.($this->value === '' ? '' : ' '.$this->value); } /** @@ -217,7 +217,7 @@ protected function parseAttributes() $this->attributes[$type][] = [ 'name' => $attrParts[0], - 'value' => isset($attrParts[1]) ? $attrParts[1] : true + 'value' => $attrParts[1] ?? true ]; } } diff --git a/src/Operations/CompileExpectCT.php b/src/Operations/CompileExpectCT.php index 2863b83..51045eb 100644 --- a/src/Operations/CompileExpectCT.php +++ b/src/Operations/CompileExpectCT.php @@ -41,7 +41,7 @@ public function modify(HeaderBag &$headers) */ private function makeHeaderValue() { - $pieces = ['max-age=' . (int) $this->config['max-age']]; + $pieces = ['max-age='.(int) $this->config['max-age']]; if ($this->config['enforce']) { @@ -50,7 +50,7 @@ private function makeHeaderValue() if ($this->config['report-uri']) { - $pieces[] = 'report-uri="' . $this->config['report-uri'] . '"'; + $pieces[] = 'report-uri="'.$this->config['report-uri'].'"'; } return implode('; ', $pieces); diff --git a/src/Operations/CompileHPKP.php b/src/Operations/CompileHPKP.php index 4abf1b9..74e9a0d 100644 --- a/src/Operations/CompileHPKP.php +++ b/src/Operations/CompileHPKP.php @@ -81,7 +81,7 @@ private function compile(array $config) return ''; } - $maxAge = isset($config['max-age']) ? $config['max-age'] : 10; + $maxAge = $config['max-age'] ?? 10; $pieces = ["max-age=$maxAge"]; @@ -99,7 +99,7 @@ private function compile(array $config) if ($config['report-uri']) { - $pieces[] = 'report-uri="' . $config['report-uri'] . '"'; + $pieces[] = 'report-uri="'.$config['report-uri'].'"'; } return implode('; ', $pieces); diff --git a/src/Operations/CompileHSTS.php b/src/Operations/CompileHSTS.php index 1547ae5..f36d6eb 100644 --- a/src/Operations/CompileHSTS.php +++ b/src/Operations/CompileHSTS.php @@ -41,7 +41,7 @@ public function modify(HeaderBag &$headers) */ private function makeHeaderValue() { - $pieces = ['max-age=' . $this->config['max-age']]; + $pieces = ['max-age='.$this->config['max-age']]; if ($this->config['subdomains']) { diff --git a/src/Operations/InjectStrictDynamic.php b/src/Operations/InjectStrictDynamic.php index cdf9f59..79c3ee5 100644 --- a/src/Operations/InjectStrictDynamic.php +++ b/src/Operations/InjectStrictDynamic.php @@ -10,8 +10,8 @@ class InjectStrictDynamic extends OperationWithErrors implements Operation, ExposesErrors { - const ENFORCE = 0b01; - const REPORT = 0b10; + public const ENFORCE = 0b01; + public const REPORT = 0b10; private $allowedCSPHashAlgs; private $mode; @@ -59,8 +59,8 @@ public function modify(HeaderBag &$HeaderBag) $this->addError( "Strict-Mode is enabled, but 'strict-dynamic' could not be added to " - . $Header->getFriendlyName() - . ' because no hash or nonce was used.', + .$Header->getFriendlyName() + .' because no hash or nonce was used.', E_USER_WARNING ); } diff --git a/src/SecureHeaders.php b/src/SecureHeaders.php index 458213c..6fe9d38 100644 --- a/src/SecureHeaders.php +++ b/src/SecureHeaders.php @@ -49,11 +49,10 @@ class SecureHeaders { - # ~~ # Version - const version = '2.0.0'; + public const version = '2.0.0'; # ~~ # protected variables: settings @@ -195,28 +194,28 @@ class SecureHeaders # auto-headers - const AUTO_ADD = 0b0000001; - const AUTO_REMOVE = 0b0000010; + public const AUTO_ADD = 0b0000001; + public const AUTO_REMOVE = 0b0000010; ## cookie attribute injection - const AUTO_COOKIE_SECURE = 0b0000100; - const AUTO_COOKIE_HTTPONLY = 0b0001000; - const AUTO_COOKIE_SAMESITE = 0b0010000; + public const AUTO_COOKIE_SECURE = 0b0000100; + public const AUTO_COOKIE_HTTPONLY = 0b0001000; + public const AUTO_COOKIE_SAMESITE = 0b0010000; ## opportunistic strict-dynamic injection - const AUTO_STRICTDYNAMIC_ENFORCE = 0b0100000; - const AUTO_STRICTDYNAMIC_REPORT = 0b1000000; - const AUTO_STRICTDYNAMIC = 0b1100000; + public const AUTO_STRICTDYNAMIC_ENFORCE = 0b0100000; + public const AUTO_STRICTDYNAMIC_REPORT = 0b1000000; + public const AUTO_STRICTDYNAMIC = 0b1100000; - const AUTO_ALL = 0b1111111; + public const AUTO_ALL = 0b1111111; # cookie upgrades - const COOKIE_NAME = 0b00001; - const COOKIE_SUBSTR = 0b00010; - const COOKIE_ALL = 0b00011; # COOKIE_NAME | COOKIE_SUBSTR - const COOKIE_REMOVE = 0b00100; - const COOKIE_DEFAULT = 0b00010; # ~COOKIE_REMOVE & COOKIE_SUBSTR + public const COOKIE_NAME = 0b00001; + public const COOKIE_SUBSTR = 0b00010; + public const COOKIE_ALL = 0b00011; # COOKIE_NAME | COOKIE_SUBSTR + public const COOKIE_REMOVE = 0b00100; + public const COOKIE_DEFAULT = 0b00010; # ~COOKIE_REMOVE & COOKIE_SUBSTR # ~~ # Public Functions @@ -711,11 +710,11 @@ public function csp() # or null: directive is flag) if ( ($i + 1 < $num) - and (is_string($args[$i+1]) or is_null($args[$i+1])) + and (is_string($args[$i + 1]) or is_null($args[$i + 1])) ) { # then use the value we specified, and skip over the next # item in the loop (since we just used it as a source value) - $friendlySource = $args[$i+1]; + $friendlySource = $args[$i + 1]; $i++; } # if no source is specified (either no more args, or one of @@ -1494,7 +1493,7 @@ public function apply(HttpAdapter $http = null) # which will cause the headers to be sent with PHP's global methods. if (is_null($http)) { - $http = new GlobalHttpAdapter(); + $http = new GlobalHttpAdapter; } $headers = $http->getHeaders(); @@ -1629,7 +1628,7 @@ private function pipeline() $operations[] = new CompileHPKP($this->hpkp, $this->hpkpro); - $operations[] = new RemoveCookies(array_keys($this->removedCookies)); + $operations[] = new RemoveCookies($this->removedCookies); # Remove all headers that were configured to be removed $operations[] = new RemoveHeaders(array_keys($this->removedHeaders)); @@ -1680,7 +1679,7 @@ public function returnBuffer($buffer = null) { # prepend any errors to the buffer string (any errors that were # echoed will have been lost during an ob_start callback) - $buffer = $this->errorString . $buffer; + $buffer = $this->errorString.$buffer; } # if we were called as part of ob_start, make note of this @@ -1730,7 +1729,7 @@ private function cspAllow( $reportOnly = null ) { Types::assert( - ['string' => [$friendlyDirective, $friendlySource]] + ['?string' => [$friendlyDirective, $friendlySource]] ); $directive = $this->longDirective($friendlyDirective); @@ -1749,9 +1748,9 @@ private function cspAllow( */ private function longDirective($friendlyDirective) { - Types::assert(['string' => [$friendlyDirective]]); + Types::assert(['?string' => [$friendlyDirective]]); - $friendlyDirective = strtolower($friendlyDirective); + $friendlyDirective = strtolower((string) $friendlyDirective); if (isset($this->cspDirectiveShortcuts[$friendlyDirective])) { @@ -1774,9 +1773,9 @@ private function longDirective($friendlyDirective) */ private function longSource($friendlySource) { - Types::assert(['string' => [$friendlySource]]); + Types::assert(['?string' => [$friendlySource]]); - $lowerFriendlySource = strtolower($friendlySource); + $lowerFriendlySource = strtolower((string) $friendlySource); if (isset($this->cspSourceShortcuts[$lowerFriendlySource])) { @@ -1983,7 +1982,7 @@ private function cspDoHash( { $this->addError( __FUNCTION__.': The specified file ' - . "'$string', does not exist" + ."'$string', does not exist" ); return ''; @@ -2010,7 +2009,6 @@ private function cspGenerateNonce() 'OpenSSL (openssl_random_pseudo_bytes) reported that it did not use a cryptographically strong algorithm to generate the nonce for CSP.', - E_USER_WARNING ); } @@ -2135,11 +2133,11 @@ private function errorHandler($level, $message) ) { if ($level === E_USER_NOTICE) { - $error = 'Notice: ' .$message. "

\n\n"; + $error = 'Notice: '.$message."

\n\n"; } elseif ($level === E_USER_WARNING) { - $error = 'Warning: ' .$message. "

\n\n"; + $error = 'Warning: '.$message."

\n\n"; } if (isset($error)) diff --git a/src/Validator.php b/src/Validator.php index a5b61f3..f4f11ea 100644 --- a/src/Validator.php +++ b/src/Validator.php @@ -4,10 +4,10 @@ abstract class Validator { - const CSP = 'content-security-policy'; - const CSPRO = 'content-security-policy-report-only'; + public const CSP = 'content-security-policy'; + public const CSPRO = 'content-security-policy-report-only'; - const VALIDATOR_NAMESPACE = 'Aidantwoods\SecureHeaders\ValidatorDelegates'; + public const VALIDATOR_NAMESPACE = 'Aidantwoods\SecureHeaders\ValidatorDelegates'; private static $delegates = [ 'CSPBadFlags' diff --git a/src/ValidatorDelegates/CSPBadFlags.php b/src/ValidatorDelegates/CSPBadFlags.php index 29a291d..f3475bb 100644 --- a/src/ValidatorDelegates/CSPBadFlags.php +++ b/src/ValidatorDelegates/CSPBadFlags.php @@ -55,12 +55,11 @@ private static function validateSrcAttribute(Header $header, $attributeName) $friendlyHeader = $header->getFriendlyName(); $Errors[] = new Error( - $friendlyHeader . ' contains the ' - . $badFlag . ' keyword in ' . $attributeName - . ', which prevents CSP protecting + $friendlyHeader.' contains the ' + .$badFlag.' keyword in '.$attributeName + .', which prevents CSP protecting against the injection of arbitrary code into the page.', - E_USER_WARNING ); } diff --git a/src/ValidatorDelegates/CSPWildcards.php b/src/ValidatorDelegates/CSPWildcards.php index 9e1710f..c2ed15b 100644 --- a/src/ValidatorDelegates/CSPWildcards.php +++ b/src/ValidatorDelegates/CSPWildcards.php @@ -9,7 +9,7 @@ class CSPWildcards implements ValidatorDelegate { - const CSP_SOURCE_WILDCARD_RE + public const CSP_SOURCE_WILDCARD_RE = '/(?:[ ]|^)\K (?: # catch open protocol wildcards @@ -112,15 +112,14 @@ private static function enumerateWildcards( $friendlyHeader = $header->getFriendlyName(); return new Error( - $friendlyHeader . ' ' . (count($matches[0]) > 1 ? + $friendlyHeader.' '.(count($matches[0]) > 1 ? 'contains the following wildcards ' : 'contains a wildcard ') - . '' . implode(', ', $matches[0]) . ' as a - source value in ' . $directive . '; this can + .''.implode(', ', $matches[0]).' as a + source value in '.$directive.'; this can allow anyone to insert elements covered by - the ' . $directive . ' directive into the + the '.$directive.' directive into the page.', - E_USER_WARNING ); } @@ -150,14 +149,13 @@ private static function enumerateNonHttps( $friendlyHeader = $header->getFriendlyName(); return new Error( - $friendlyHeader . ' contains the insecure protocol - HTTP in ' . (count($matches[0]) > 1 ? + $friendlyHeader.' contains the insecure protocol + HTTP in '.(count($matches[0]) > 1 ? 'the following source values ' : 'a source value ') - . '' . implode(', ', $matches[0]) . '; this can + .''.implode(', ', $matches[0]).'; this can allow anyone to insert elements covered by the - ' . $directive . ' directive into the page.', - + '.$directive.' directive into the page.', E_USER_WARNING ); } diff --git a/tests/CSPTest.php b/tests/CSPTest.php index 24fb1d0..a15af73 100644 --- a/tests/CSPTest.php +++ b/tests/CSPTest.php @@ -24,8 +24,8 @@ public function testStrictDynamicInjectableForNonInternalPolicy() $headersString = $headerStrings->getSentHeaders(); - $this->assertContains("Content-Security-Policy: script-src 'nonce-abcdefg+123456' 'strict-dynamic'", $headersString); - $this->assertContains("Content-Security-Policy-Report-Only: script-src 'nonce-abcdefg+123456' 'strict-dynamic'", $headersString); + $this->assertStringContainsString("Content-Security-Policy: script-src 'nonce-abcdefg+123456' 'strict-dynamic'", $headersString); + $this->assertStringContainsString("Content-Security-Policy-Report-Only: script-src 'nonce-abcdefg+123456' 'strict-dynamic'", $headersString); } public function testStrictDynamicInjectOnlyEnforced() @@ -45,8 +45,8 @@ public function testStrictDynamicInjectOnlyEnforced() $headersString = $headerStrings->getSentHeaders(); - $this->assertContains("Content-Security-Policy: script-src 'nonce-abcdefg+123456' 'strict-dynamic'", $headersString); - $this->assertNotContains("Content-Security-Policy-Report-Only: script-src 'nonce-abcdefg+123456' 'strict-dynamic'", $headersString); + $this->assertStringContainsString("Content-Security-Policy: script-src 'nonce-abcdefg+123456' 'strict-dynamic'", $headersString); + $this->assertStringNotContainsString("Content-Security-Policy-Report-Only: script-src 'nonce-abcdefg+123456' 'strict-dynamic'", $headersString); } public function testStrictDynamicInjectOnlyReport() @@ -66,8 +66,8 @@ public function testStrictDynamicInjectOnlyReport() $headersString = $headerStrings->getSentHeaders(); - $this->assertNotContains("Content-Security-Policy: script-src 'nonce-abcdefg+123456' 'strict-dynamic'", $headersString); - $this->assertContains("Content-Security-Policy-Report-Only: script-src 'nonce-abcdefg+123456' 'strict-dynamic'", $headersString); + $this->assertStringNotContainsString("Content-Security-Policy: script-src 'nonce-abcdefg+123456' 'strict-dynamic'", $headersString); + $this->assertStringContainsString("Content-Security-Policy-Report-Only: script-src 'nonce-abcdefg+123456' 'strict-dynamic'", $headersString); } public function testCSPHeaderMerge() @@ -119,12 +119,12 @@ public function assertEquivalentCSP($policy, $headersString) { $source = preg_quote($source, '/'); - $this->assertRegexp('/Content-Security-Policy:.*?'.$directive.'[^;]+'.$source.'/', $headersString); + $this->assertMatchesRegularExpression('/Content-Security-Policy:.*?'.$directive.'[^;]+'.$source.'/', $headersString); } } else { - $this->assertRegexp('/Content-Security-Policy:.*?'.$directive.';/', $headersString); + $this->assertMatchesRegularExpression('/Content-Security-Policy:.*?'.$directive.';/', $headersString); } } } diff --git a/tests/CookieTest.php b/tests/CookieTest.php index cd71479..eb6ef19 100644 --- a/tests/CookieTest.php +++ b/tests/CookieTest.php @@ -22,8 +22,8 @@ public function testCookieUpgrades() $headersString = $headerStrings->getSentHeaders(); - $this->assertContains('Set-Cookie: normalcookie=value1', $headersString); - $this->assertContains('Set-Cookie: authcookie=value2; Secure; HttpOnly; SameSite=Lax', $headersString); + $this->assertStringContainsString('Set-Cookie: normalcookie=value1', $headersString); + $this->assertStringContainsString('Set-Cookie: authcookie=value2; Secure; HttpOnly; SameSite=Lax', $headersString); } public function testSameSiteCookiesNoSameSite() @@ -41,7 +41,7 @@ public function testSameSiteCookiesNoSameSite() $headersString = $headerStrings->getSentHeaders(); - $this->assertNotContains('SameSite', $headersString); + $this->assertStringNotContainsString('SameSite', $headersString); } public function testSameSiteCookiesStrictModeNoSameSite() @@ -61,7 +61,7 @@ public function testSameSiteCookiesStrictModeNoSameSite() $headersString = $headerStrings->getSentHeaders(); - $this->assertNotContains('SameSite', $headersString); + $this->assertStringNotContainsString('SameSite', $headersString); } public function testSameSiteCookiesStrictMode() @@ -79,7 +79,7 @@ public function testSameSiteCookiesStrictMode() $headersString = $headerStrings->getSentHeaders(); - $this->assertContains('Set-Cookie: authcookie=value; Secure; HttpOnly; SameSite=Strict', $headersString); + $this->assertStringContainsString('Set-Cookie: authcookie=value; Secure; HttpOnly; SameSite=Strict', $headersString); } public function testSameSiteCookiesStrictModeExplicitLax() @@ -98,7 +98,7 @@ public function testSameSiteCookiesStrictModeExplicitLax() $headersString = $headerStrings->getSentHeaders(); - $this->assertContains('Set-Cookie: authcookie=value; Secure; HttpOnly; SameSite=Lax', $headersString); + $this->assertStringContainsString('Set-Cookie: authcookie=value; Secure; HttpOnly; SameSite=Lax', $headersString); } public function testSameSiteCookiesExplicitLax() @@ -116,7 +116,7 @@ public function testSameSiteCookiesExplicitLax() $headersString = $headerStrings->getSentHeaders(); - $this->assertContains('Set-Cookie: authcookie=value; Secure; HttpOnly; SameSite=Lax', $headersString); + $this->assertStringContainsString('Set-Cookie: authcookie=value; Secure; HttpOnly; SameSite=Lax', $headersString); } public function testSameSiteCookiesExplicitStrict() @@ -134,7 +134,7 @@ public function testSameSiteCookiesExplicitStrict() $headersString = $headerStrings->getSentHeaders(); - $this->assertContains('Set-Cookie: authcookie=value; Secure; HttpOnly; SameSite=Strict', $headersString); + $this->assertStringContainsString('Set-Cookie: authcookie=value; Secure; HttpOnly; SameSite=Strict', $headersString); } public function testCookiesRemovable() @@ -154,8 +154,8 @@ public function testCookiesRemovable() $headersString = $headerStrings->getSentHeaders(); - $this->assertNotContains('Set-Cookie: authcookie', $headersString); - $this->assertNotContains('Set-Cookie: regularcookie', $headersString); - $this->assertNotContains('Set-Cookie:', $headersString); + $this->assertStringNotContainsString('Set-Cookie: authcookie', $headersString); + $this->assertStringNotContainsString('Set-Cookie: regularcookie', $headersString); + $this->assertStringNotContainsString('Set-Cookie:', $headersString); } } diff --git a/tests/HeaderFactoryTest.php b/tests/HeaderFactoryTest.php index 11eaa34..4efe6d2 100644 --- a/tests/HeaderFactoryTest.php +++ b/tests/HeaderFactoryTest.php @@ -7,7 +7,7 @@ class HeaderFactoryTest extends TestCase { - public function provideCSPHeaders() + public static function provideCSPHeaders() { return [ ['Content-SECURITY-Policy', "default-src 'none'"], @@ -32,7 +32,7 @@ public function testCSPHeaders($name, $value) ); } - public function provideRegularHeaders() + public static function provideRegularHeaders() { return [ ['Set-Cookie', 'foo=bar'], diff --git a/tests/Operations/CompileCSPTest.php b/tests/Operations/CompileCSPTest.php index e3c87f5..b9c947d 100644 --- a/tests/Operations/CompileCSPTest.php +++ b/tests/Operations/CompileCSPTest.php @@ -7,7 +7,7 @@ use Aidantwoods\SecureHeaders\Operations\CompileCSP; use PHPUnit\Framework\TestCase; -class CSPTest extends TestCase +class CompileCSPTest extends TestCase { public function testStrictDynamicInjectableForNonInternalPolicy() { diff --git a/tests/Operations/CompileExpectCTTest.php b/tests/Operations/CompileExpectCTTest.php index 155e2b9..b94d4b3 100644 --- a/tests/Operations/CompileExpectCTTest.php +++ b/tests/Operations/CompileExpectCTTest.php @@ -8,7 +8,7 @@ class CompileExpectCTTest extends TestCase { - public function provideExpectCTTestCases() + public static function provideExpectCTTestCases() { return [ [ diff --git a/tests/Operations/CompileHPKPTest.php b/tests/Operations/CompileHPKPTest.php index 8aec8e7..9739d73 100644 --- a/tests/Operations/CompileHPKPTest.php +++ b/tests/Operations/CompileHPKPTest.php @@ -8,7 +8,7 @@ class CompileHPKPTest extends TestCase { - public function provideHPKPTestCases() + public static function provideHPKPTestCases() { return [ [ @@ -92,18 +92,18 @@ public function testHPKP(array $compileHPKPConfig, $expectedHeader) * @param $compileHPKPConfig * @param $expectedHeader */ - public function testHPKPRO(array $compileHPKPConfig, $expectedHeader) + public static function testHPKPRO(array $compileHPKPConfig, $expectedHeader) { $HeaderBag = new HeaderBag; $CompileHPKP = new CompileHPKP([], $compileHPKPConfig); $CompileHPKP->modify($HeaderBag); - $this->assertCount(1, $HeaderBag->get()); + static::assertCount(1, $HeaderBag->get()); $headersString = (string) $HeaderBag->get()[0]; - $this->assertSame( + static::assertSame( "Public-Key-Pins-Report-Only: $expectedHeader", $headersString ); diff --git a/tests/Operations/CompileHSTSTest.php b/tests/Operations/CompileHSTSTest.php index 82986d6..fe0a276 100644 --- a/tests/Operations/CompileHSTSTest.php +++ b/tests/Operations/CompileHSTSTest.php @@ -8,7 +8,7 @@ class CompileHSTSTest extends TestCase { - public function provideHSTSTestCases() + public static function provideHSTSTestCases() { return [ [ diff --git a/tests/Operations/InjectStrictDynamicTest.php b/tests/Operations/InjectStrictDynamicTest.php index 83f1de2..15a23fa 100644 --- a/tests/Operations/InjectStrictDynamicTest.php +++ b/tests/Operations/InjectStrictDynamicTest.php @@ -134,7 +134,7 @@ public function testSDInjectedInCSPROExclusive() $this->assertCount(2, $HeaderBag->get()); - $this->assertNotContains('strict-dynamic', (string) $HeaderBag->get()[0]); + $this->assertStringNotContainsString('strict-dynamic', (string) $HeaderBag->get()[0]); $headerString = (string) $HeaderBag->get()[1]; @@ -153,7 +153,7 @@ public function testSDInjectedInCSPExclusive() $this->assertCount(2, $HeaderBag->get()); - $this->assertNotContains('strict-dynamic', (string) $HeaderBag->get()[1]); + $this->assertStringNotContainsString('strict-dynamic', (string) $HeaderBag->get()[1]); $headerString = (string) $HeaderBag->get()[0]; diff --git a/tests/Operations/RemovieCookiesTest.php b/tests/Operations/RemoveCookiesTest.php similarity index 100% rename from tests/Operations/RemovieCookiesTest.php rename to tests/Operations/RemoveCookiesTest.php diff --git a/tests/SafeModeTest.php b/tests/SafeModeTest.php index 1a098d7..4d52c81 100644 --- a/tests/SafeModeTest.php +++ b/tests/SafeModeTest.php @@ -9,14 +9,14 @@ class SafeModeTest extends TestCase { private $assertions = [ - 'Contains', - 'NotContains', + 'StringContainsString', + 'StringNotContainsString', 'Equals', - 'Regexp', - 'NotRegExp' + 'MatchesRegularExpression', + 'DoesNotMatchRegularExpression' ]; - public function dataSafeMode() + public static function dataSafeMode() { return [ [ @@ -26,7 +26,7 @@ function (&$headers) $headers->hsts(31536000, true, true); }, 'assertions' => [ - 'Contains' => + 'StringContainsString' => 'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload' ] ], @@ -38,9 +38,9 @@ function (&$headers) $headers->hsts(31536000, true, true); }, 'assertions' => [ - 'NotContains' => + 'StringNotContainsString' => 'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload', - 'Contains' => + 'StringContainsString' => 'Strict-Transport-Security: max-age=86400' ] ], @@ -52,9 +52,9 @@ function (&$headers) $headers->strictMode(); }, 'assertions' => [ - 'NotContains' => + 'StringNotContainsString' => 'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload', - 'Contains' => + 'StringContainsString' => 'Strict-Transport-Security: max-age=86400' ] ], @@ -66,9 +66,9 @@ function (&$headers) $headers->hpkp('abcd', 31536000, true); }, 'assertions' => [ - 'NotContains' => + 'StringNotContainsString' => 'max-age=31536000; pin-sha256="abcd"; includeSubDomains', - 'Contains' => + 'StringContainsString' => 'Public-Key-Pins: max-age=10; pin-sha256="abcd"' ] ], @@ -79,7 +79,7 @@ function (&$headers) $headers->expectCT(31536000, true, 'https://report.exampe.com'); }, 'assertions' => [ - 'Contains' => + 'StringContainsString' => 'Expect-CT: max-age=31536000; enforce; report-uri="https://report.exampe.com"' ] ], @@ -91,9 +91,9 @@ function (&$headers) $headers->expectCT(31536000, true, 'https://report.exampe.com'); }, 'assertions' => [ - 'NotContains' => + 'StringNotContainsString' => 'Expect-CT: max-age=31536000; enforce; report-uri="https://report.exampe.com"', - 'Contains' => + 'StringContainsString' => 'Expect-CT: max-age=31536000; report-uri="https://report.exampe.com"' ] ], @@ -105,9 +105,9 @@ function (&$headers) $headers->strictMode(); }, 'assertions' => [ - 'NotContains' => + 'StringNotContainsString' => 'Expect-CT: max-age=31536000; enforce', - 'Contains' => + 'StringContainsString' => 'Expect-CT: max-age=31536000', ] ], diff --git a/tests/SecureHeadersTest.php b/tests/SecureHeadersTest.php index 11e7181..11ff761 100644 --- a/tests/SecureHeadersTest.php +++ b/tests/SecureHeadersTest.php @@ -28,7 +28,7 @@ public function testExistingHeadersAreSent() $headersString = $headerStrings->getSentHeaders(); - $this->assertContains('X-Foo: Bar', $headersString); + $this->assertStringContainsString('X-Foo: Bar', $headersString); } public function testSevenDefaultHeadersAreAdded() @@ -41,13 +41,13 @@ public function testSevenDefaultHeadersAreAdded() $headersString = $headerStrings->getSentHeaders(); - $this->assertContains('Expect-CT: max-age=0', $headersString); + $this->assertStringContainsString('Expect-CT: max-age=0', $headersString); # we want to ensure ordering here, hence two header test - $this->assertContains("Referrer-Policy: no-referrer\nReferrer-Policy: strict-origin-when-cross-origin", $headersString); - $this->assertContains('X-Permitted-Cross-Domain-Policies: none', $headersString); - $this->assertContains('X-XSS-Protection: 1; mode=block', $headersString); - $this->assertContains('X-Content-Type-Options: nosniff', $headersString); - $this->assertContains('X-Frame-Options: Deny', $headersString); + $this->assertStringContainsString("Referrer-Policy: no-referrer\nReferrer-Policy: strict-origin-when-cross-origin", $headersString); + $this->assertStringContainsString('X-Permitted-Cross-Domain-Policies: none', $headersString); + $this->assertStringContainsString('X-XSS-Protection: 1; mode=block', $headersString); + $this->assertStringContainsString('X-Content-Type-Options: nosniff', $headersString); + $this->assertStringContainsString('X-Frame-Options: Deny', $headersString); } public function testDefaultHeadersDoNotReplaceExistingHeaders() @@ -62,14 +62,14 @@ public function testDefaultHeadersDoNotReplaceExistingHeaders() $headersString = $headerStrings->getSentHeaders(); - $this->assertContains('Expect-CT: max-age=0', $headersString); + $this->assertStringContainsString('Expect-CT: max-age=0', $headersString); # we want to ensure ordering here, hence two header test - $this->assertContains("Referrer-Policy: no-referrer\nReferrer-Policy: strict-origin-when-cross-origin", $headersString); - $this->assertContains('X-Permitted-Cross-Domain-Policies: none', $headersString); - $this->assertContains('X-XSS-Protection: 1; mode=block', $headersString); - $this->assertContains('X-Content-Type-Options: nosniff', $headersString); - $this->assertContains('X-Frame-Options: sameorigin', $headersString); - $this->assertNotContains('X-Frame-Options: Deny', $headersString); + $this->assertStringContainsString("Referrer-Policy: no-referrer\nReferrer-Policy: strict-origin-when-cross-origin", $headersString); + $this->assertStringContainsString('X-Permitted-Cross-Domain-Policies: none', $headersString); + $this->assertStringContainsString('X-XSS-Protection: 1; mode=block', $headersString); + $this->assertStringContainsString('X-Content-Type-Options: nosniff', $headersString); + $this->assertStringContainsString('X-Frame-Options: sameorigin', $headersString); + $this->assertStringNotContainsString('X-Frame-Options: Deny', $headersString); } public function testDefaultHeadersCanBeExplicitlyRemoved() @@ -83,12 +83,12 @@ public function testDefaultHeadersCanBeExplicitlyRemoved() $headersString = $headerStrings->getSentHeaders(); - $this->assertContains('Expect-CT: max-age=0', $headersString); + $this->assertStringContainsString('Expect-CT: max-age=0', $headersString); # we want to ensure ordering here, hence two header test - $this->assertContains("Referrer-Policy: no-referrer\nReferrer-Policy: strict-origin-when-cross-origin", $headersString); - $this->assertContains('X-Permitted-Cross-Domain-Policies: none', $headersString); - $this->assertContains('X-Content-Type-Options: nosniff', $headersString); - $this->assertContains('X-Frame-Options: Deny', $headersString); - $this->assertNotContains('X-XSS-Protection', $headersString); + $this->assertStringContainsString("Referrer-Policy: no-referrer\nReferrer-Policy: strict-origin-when-cross-origin", $headersString); + $this->assertStringContainsString('X-Permitted-Cross-Domain-Policies: none', $headersString); + $this->assertStringContainsString('X-Content-Type-Options: nosniff', $headersString); + $this->assertStringContainsString('X-Frame-Options: Deny', $headersString); + $this->assertStringNotContainsString('X-XSS-Protection', $headersString); } } diff --git a/tests/StrictModeHeadersTest.php b/tests/StrictModeHeadersTest.php index f3f8eea..4d3d5df 100644 --- a/tests/StrictModeHeadersTest.php +++ b/tests/StrictModeHeadersTest.php @@ -9,14 +9,14 @@ class StrictModeHeadersTest extends TestCase { private $assertions = [ - 'Contains', - 'NotContains', + 'StringContainsString', + 'StringNotContainsString', 'Equals', - 'Regexp', - 'NotRegExp' + 'MatchesRegularExpression', + 'DoesNotMatchRegularExpression' ]; - public function dataStrictMode() + public static function dataStrictMode() { return [ [ @@ -26,7 +26,7 @@ function (&$headers) $headers->strictMode(); }, 'assertions' => [ - 'Contains' => + 'StringContainsString' => 'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload' ] ], @@ -37,7 +37,7 @@ function (&$headers) $headers->strictMode(); }, 'assertions' => [ - 'Contains' => + 'StringContainsString' => 'Expect-CT: max-age=31536000; enforce' ] ], @@ -49,7 +49,7 @@ function (&$headers) $headers->cspNonce('script'); }, 'assertions' => [ - 'Regexp' => + 'MatchesRegularExpression' => "/Content-Security-Policy: script-src 'nonce-[^']+' 'strict-dynamic'/" ] ], @@ -61,7 +61,7 @@ function (&$headers) $headers->cspNonce('default'); }, 'assertions' => [ - 'Regexp' => + 'MatchesRegularExpression' => "/Content-Security-Policy: default-src 'nonce-[^']+' 'strict-dynamic'/" ] ], @@ -74,9 +74,9 @@ function (&$headers) $headers->cspNonce('script'); }, 'assertions' => [ - 'Regexp' => + 'MatchesRegularExpression' => "/script-src 'nonce-[^']+' 'strict-dynamic'/", - 'NotRegexp' => + 'DoesNotMatchRegularExpression' => "/default-src 'nonce-[^']+' 'strict-dynamic'/" ] ], @@ -88,7 +88,7 @@ function (&$headers) $headers->cspHash('default', 'abcd'); }, 'assertions' => [ - 'Regexp' => + 'MatchesRegularExpression' => "/Content-Security-Policy: default-src 'sha[^']+' 'strict-dynamic'/" ] ], @@ -100,7 +100,7 @@ function (&$headers) $headers->cspHash('script', 'abcd'); }, 'assertions' => [ - 'Regexp' => + 'MatchesRegularExpression' => "/Content-Security-Policy: script-src 'sha[^']+' 'strict-dynamic'/" ] ], @@ -113,9 +113,9 @@ function (&$headers) $headers->cspHash('script', 'abcd'); }, 'assertions' => [ - 'Regexp' => + 'MatchesRegularExpression' => "/script-src 'sha[^']+' 'strict-dynamic'/", - 'NotRegexp' => + 'DoesNotMatchRegularExpression' => "/default-src 'sha[^']+' 'strict-dynamic'/" ] ], @@ -128,7 +128,7 @@ function (&$headers) $headers->csp('script', 'http://other-cdn.net'); }, 'assertions' => [ - 'NotContains' => + 'StringNotContainsString' => "'strict-dynamic'" ] ], diff --git a/tests/Util/TypesTest.php b/tests/Util/TypesTest.php index a9b4f16..27b8849 100644 --- a/tests/Util/TypesTest.php +++ b/tests/Util/TypesTest.php @@ -20,7 +20,7 @@ public function testValidValues($type, $variable) $this->assertNull($result); } - public function validValues() + public static function validValues() { return [ ['string', 'abcde'], @@ -44,16 +44,16 @@ public function validValues() /** * @dataProvider invalidValues - * @expectedException Aidantwoods\SecureHeaders\Util\TypeError */ public function testInvalidStringsRaiseExceptions($type, $variable) { + $this->expectException(\Aidantwoods\SecureHeaders\Util\TypeError::class); Types::assert([ $type => [$variable] ]); } - public function invalidValues() + public static function invalidValues() { return [ ['string', 42], diff --git a/tests/ValidatorDelegates/CSPBadFlagsTest.php b/tests/ValidatorDelegates/CSPBadFlagsTest.php index 41f7569..51bdec7 100644 --- a/tests/ValidatorDelegates/CSPBadFlagsTest.php +++ b/tests/ValidatorDelegates/CSPBadFlagsTest.php @@ -9,7 +9,7 @@ class CSPBadFlagsTest extends TestCase { - public function provideBadFlagTestCases() + public static function provideBadFlagTestCases() { return [ [ diff --git a/tests/ValidatorDelegates/CSPRODestinationTest.php b/tests/ValidatorDelegates/CSPRODestinationTest.php index e8792a1..c9d83a5 100644 --- a/tests/ValidatorDelegates/CSPRODestinationTest.php +++ b/tests/ValidatorDelegates/CSPRODestinationTest.php @@ -18,7 +18,7 @@ class CSPRODestinationTest extends TestCase reporting address to make full use of this header.' ; - public function provideDestinationCases() + public static function provideDestinationCases() { return [ ["default-src 'unsafe-inline'"], diff --git a/tests/ValidatorDelegates/CSPWildcardsTest.php b/tests/ValidatorDelegates/CSPWildcardsTest.php index 018c7d7..2bc0a0f 100644 --- a/tests/ValidatorDelegates/CSPWildcardsTest.php +++ b/tests/ValidatorDelegates/CSPWildcardsTest.php @@ -9,7 +9,7 @@ class CSPWildcardsTest extends TestCase { - public function provideWildcardTestCases() + public static function provideWildcardTestCases() { return [ [