Skip to content
Snippets Groups Projects
Commit 4906ca0d authored by Geoff Appleby's avatar Geoff Appleby
Browse files

Issue #3389249 by gapple: Add nonce service

parent dfc94e04
No related branches found
No related tags found
1 merge request!17Issue #3389249: Add nonce service
......@@ -11,7 +11,7 @@
"source": "https://git.drupalcode.org/project/csp"
},
"require": {
"php": ">=7.2",
"php": ">=7.4",
"ext-json": "*",
"drupal/core": "^9.5 || ^10"
}
......
......
services:
csp.nonce:
class: Drupal\csp\Nonce
csp.response_listener:
class: Drupal\csp\EventSubscriber\ResponseCspSubscriber
arguments:
......
......
<?php
namespace Drupal\csp;
use Drupal\Component\Utility\Crypt;
/**
* Service for retrieving a per-request nonce value.
*/
class Nonce {
/**
* The request nonce.
*
* @var null|string
*/
private ?string $value;
/**
* Generate a new nonce value.
*
* @return string
* A base64-encoded string.
*/
protected static function generateValue(): string {
// Nonce should be at least 128 bits.
// @see https://www.w3.org/TR/CSP/#security-nonces
return Crypt::randomBytesBase64(16);
}
/**
* Return if a nonce value has been generated.
*
* @return bool
* If a nonce value has been generated.
*/
public function hasValue(): bool {
return !empty($this->value);
}
/**
* Get the nonce value.
*
* @return string
* A base64-encoded string.
*/
public function getValue(): string {
return $this->value ??= self::generateValue();
}
/**
* Get the nonce value formatted for inclusion in a directive.
*
* @return string
* The nonce in the format "'nonce-{value}'"
*/
public function getSource(): string {
return "'nonce-{$this->getValue()}'";
}
}
<?php
namespace Drupal\Tests\csp\Unit;
use Drupal\csp\Nonce;
use Drupal\Tests\UnitTestCase;
/**
* Test the Nonce service.
*
* @coversDefaultClass \Drupal\csp\Nonce
* @group csp
*/
class NonceTest extends UnitTestCase {
/**
* The hasValue() method should return the expected value.
*/
public function testHas() {
$nonce = new Nonce();
$this->assertFalse($nonce->hasValue());
$nonce->getValue();
$this->assertTrue($nonce->hasValue());
}
/**
* The nonce value should be statically cached.
*/
public function testValue() {
$nonce = new Nonce();
$value1 = $nonce->getValue();
$value2 = $nonce->getValue();
$this->assertIsString($value1);
$this->assertEquals($value1, $value2);
}
/**
* The source value should be properly formatted.
*/
public function testSource() {
$nonce = new Nonce();
$value = $nonce->getValue();
$this->assertEquals(
"'nonce-{$value}'",
$nonce->getSource()
);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment