/**
  * Get csp header.
  *
  * @return array
  */
 protected function csp()
 {
     if (!is_null($this->config['custom-csp'])) {
         return ['Content-Security-Policy' => $this->config['custom-csp']];
     }
     $csp = new CSPBuilder($this->config['csp']);
     return $csp->getHeaderArray(false);
 }
Пример #2
0
 public function testPreHash()
 {
     $basic = CSPBuilder::fromFile(__DIR__ . '/vectors/basic-csp.json');
     $hashed = \base64_encode(\hash('sha384', 'Yellow Submarine', true));
     $basic->preHash('script-src', $hashed, 'sha384');
     $this->assertEquals(file_get_contents(__DIR__ . '/vectors/basic-csp-hash.out'), $basic->getCompiledHeader());
 }
Пример #3
0
 /**
  * Add content security policy headers to response.
  *
  * @return void
  *
  * @throws \Exception
  */
 protected function buildCsp()
 {
     if ($this->response instanceof BinaryFileResponse) {
         return;
     }
     $csp = CSPBuilder::fromFile(config_path('csp.json'));
     $csp->addDirective('upgrade-insecure-requests', $this->request->secure());
     $this->response->withHeaders($csp->getHeaderArray(false));
 }
Пример #4
0
 public function testInjectCSPHeaderWithLegacy()
 {
     $originalMessage = $this->getMock(MessageInterface::class, ['withAddedHeader']);
     $modifiedMessage1 = $this->getMock(MessageInterface::class, ['withAddedHeader']);
     $modifiedMessage2 = $this->getMock(MessageInterface::class, ['withAddedHeader']);
     $modifiedMessage3 = $this->getMock(MessageInterface::class, ['withAddedHeader']);
     $basic = CSPBuilder::fromFile(__DIR__ . '/vectors/basic-csp.json');
     $header = $basic->disableOldBrowserSupport()->compile();
     $originalMessage->expects(self::once())->method('withAddedHeader')->with('Content-Security-Policy', $header)->willReturn($modifiedMessage1);
     $modifiedMessage1->expects(self::once())->method('withAddedHeader')->with('X-Content-Security-Policy', $header)->willReturn($modifiedMessage2);
     $modifiedMessage2->expects(self::once())->method('withAddedHeader')->with('X-Webkit-CSP', $header)->willReturn($modifiedMessage3);
     self::assertSame($modifiedMessage3, $basic->injectCSPHeader($originalMessage, true));
 }
Пример #5
0
 public function testBasic()
 {
     $basic = CSPBuilder::fromFile(__DIR__ . '/vectors/basic-csp.json');
     $basic->addSource('img-src', 'ytimg.com');
     $this->assertEquals(file_get_contents(__DIR__ . '/vectors/basic-csp.out'), $basic->getCompiledHeader());
     $noOld = file_get_contents(__DIR__ . '/vectors/basic-csp-no-old.out');
     // We expect different output for ytimg.com when we disable legacy
     // browser support (i.e. Safari):
     $this->assertEquals($noOld, $basic->disableOldBrowserSupport()->getCompiledHeader());
     $array = $basic->getHeaderArray();
     $this->assertEquals($array, ['Content-Security-Policy' => $noOld, 'X-Content-Security-Policy' => $noOld, 'X-Webkit-CSP' => $noOld]);
     $array2 = $basic->getHeaderArray(false);
     $this->assertEquals($array2, ['Content-Security-Policy' => $noOld]);
 }
Пример #6
0
<?php

use ParagonIE\CSPBuilder\CSPBuilder;
require_once \dirname(__DIR__) . '/vendor/autoload.php';
if ($argc < 2) {
    die("Usage: php compile_csp.php [source] [destination]\n");
}
$policy = CSPBuilder::fromFile($argv[1]);
$policy->saveSnippet($argv[2], CSPBuilder::FORMAT_APACHE);
exit(0);
Пример #7
0
if (\file_exists($cspCacheFile) && \filesize($cspCacheFile) > 0) {
    $csp = CSPBuilder::fromFile($cspCacheFile);
} else {
    $cspfile = ROOT . '/config/Cabin/' . AutoPilot::$active_cabin . '/content_security_policy.json';
    if (\file_exists($cspfile)) {
        $cabinPolicy = \Airship\loadJSON($cspfile);
        // Merge the cabin-specific policy with the base policy
        if (!empty($cabinPolicy['inherit'])) {
            $basePolicy = \Airship\loadJSON(ROOT . '/config/content_security_policy.json');
            $cabinPolicy = \Airship\csp_merge($cabinPolicy, $basePolicy);
        }
        \Airship\saveJSON($cspCacheFile, $cabinPolicy);
        $csp = CSPBuilder::fromFile($cspCacheFile);
    } else {
        // No cabin policy, use the default
        $csp = CSPBuilder::fromFile(ROOT . '/config/content_security_policy.json');
    }
}
$state->CSP = $csp;
/**
 * Next, if we're connected over HTTPS, send an HPKP header too:
 */
if (AutoPilot::isHTTPSConnection()) {
    $hpkpCacheFile = ROOT . '/tmp/cache/hpkp.' . AutoPilot::$active_cabin . '.json';
    if (\file_exists($hpkpCacheFile) && \filesize($hpkpCacheFile) > 0) {
        $hpkp = HPKPBuilder::fromFile($hpkpCacheFile);
        $state->HPKP = $hpkp;
    } else {
        $hpkpConfig = $state->cabins[AutoPilot::$cabinIndex]['hpkp'];
        if ($hpkpConfig['enabled'] && \count($hpkpConfig['hashes']) > 1) {
            $hpkp = (new HPKPBuilder())->includeSubdomains($hpkpConfig['include-subdomains'])->maxAge($hpkpConfig['max-age'])->reportOnly($hpkpConfig['report-only'])->reportUri($hpkpConfig['report-uri']);
Пример #8
0
<?php

require_once \dirname(__DIR__) . '/vendor/autoload.php';
if ($argc < 2) {
    die("Usage: php compile_csp.php [json source file]");
}
$policy = \ParagonIE\CSPBuilder\CSPBuilder::fromFile($argv[1]);
echo $policy->getCompiledHeader(), "\n";
exit(0);
Пример #9
0
 /**
  * Execute the middleware.
  *
  * @param ServerRequestInterface $request
  * @param ResponseInterface      $response
  * @param callable               $next
  *
  * @return ResponseInterface
  */
 public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
 {
     $this->csp->compile();
     $response = $this->csp->injectCSPHeader($response);
     return $next($request, $response);
 }
Пример #10
0
 public function execute(ServerHttpRequest $httpRequest) : HttpResponse
 {
     $response = $this->application->execute($httpRequest);
     return $this->cspBuilder->injectCSPHeader($response);
 }