-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Encrypt POST data before sending it to sentry
- Loading branch information
1 parent
3b7a878
commit 7b452e0
Showing
17 changed files
with
709 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Netlogix\Sentry\Controller; | ||
|
||
use function json_decode; | ||
use function json_encode; | ||
use const JSON_PRETTY_PRINT; | ||
use Neos\Flow\Mvc\Controller\ActionController; | ||
use Netlogix\Sentry\Encryption\EncryptionService; | ||
use Netlogix\Sentry\Encryption\Sealed; | ||
|
||
class EncryptedPayloadController extends ActionController | ||
{ | ||
protected EncryptionService $encryptionService; | ||
|
||
public function injectEncryptionService(EncryptionService $encryptionService): void | ||
{ | ||
$this->encryptionService = $encryptionService; | ||
} | ||
|
||
/** | ||
* @param string $encryptedData | ||
* @param string $initializationVector | ||
* @param string $envelopeKey | ||
*/ | ||
public function decryptAction( | ||
string $encryptedData, | ||
string $initializationVector, | ||
string $envelopeKey | ||
): string { | ||
$sealed = Sealed::fromArray([ | ||
'encryptedData' => $encryptedData, | ||
'initializationVector' => $initializationVector, | ||
'envelopeKey' => $envelopeKey, | ||
]); | ||
$unencrypted = $this->encryptionService->open($sealed); | ||
$this->response->setContentType('application/json'); | ||
|
||
return json_encode(json_decode($unencrypted, true), JSON_PRETTY_PRINT); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Netlogix\Sentry\Encryption; | ||
|
||
use function http_build_query; | ||
use Neos\Flow\Http\BaseUriProvider; | ||
use Neos\Flow\Security\Cryptography\RsaWalletServiceInterface; | ||
use Neos\Flow\Security\Cryptography\RsaWalletServicePhp; | ||
use Neos\Flow\Security\Exception\InvalidKeyPairIdException; | ||
use Neos\Utility\ObjectAccess; | ||
use function openssl_open; | ||
use function openssl_random_pseudo_bytes; | ||
use function openssl_seal; | ||
use Psr\Http\Message\UriInterface; | ||
|
||
class EncryptionService | ||
{ | ||
const ALGORITHM = 'AES256'; | ||
|
||
private string $rsaKeyFingerprint; | ||
|
||
private string $encryptionModuleUri; | ||
|
||
private RsaWalletServiceInterface $rsaWallet; | ||
|
||
private BaseUriProvider $baseUriProvider; | ||
|
||
public function injectSettings(array $settings): void | ||
{ | ||
$privacySettings = $settings['privacy'] ?? []; | ||
$this->rsaKeyFingerprint = (string) ($privacySettings['rsaKeyFingerprint'] ?? ''); | ||
$this->encryptionModuleUri = (string) ($privacySettings['encryptionModuleUri'] ?? ''); | ||
} | ||
|
||
public function injectRsaWalletService(RsaWalletServiceInterface $rsaWallet): void | ||
{ | ||
$this->rsaWallet = $rsaWallet; | ||
} | ||
|
||
public function injectBaseUriProvider(BaseUriProvider $baseUriProvider): void | ||
{ | ||
$this->baseUriProvider = $baseUriProvider; | ||
} | ||
|
||
public function seal(string $unencryptedData): Sealed | ||
{ | ||
$publicKeyString = $this->getKeyString('publicKey'); | ||
|
||
$initializationVector = openssl_random_pseudo_bytes(32); | ||
|
||
openssl_seal( | ||
$unencryptedData, | ||
$encryptedData, | ||
$envelopeKeys, | ||
[$publicKeyString], | ||
self::ALGORITHM, | ||
$initializationVector | ||
); | ||
|
||
return new Sealed($encryptedData, $initializationVector, $envelopeKeys[0]); | ||
} | ||
|
||
public function open(Sealed $package): string | ||
{ | ||
$privateKeyString = $this->getKeyString('privateKey'); | ||
|
||
$encryptedData = $package->getEncryptedData(); | ||
$envelopeKey = $package->getEnvelopeKey(); | ||
$initializationVector = $package->getInitializationVector(); | ||
|
||
openssl_open( | ||
$encryptedData, | ||
$unencryptedData, | ||
$envelopeKey, | ||
$privateKeyString, | ||
self::ALGORITHM, | ||
$initializationVector | ||
); | ||
|
||
return $unencryptedData; | ||
} | ||
|
||
public function getEncryptionUriForSealedPayload(Sealed $sealed): UriInterface | ||
{ | ||
return $this->baseUriProvider | ||
->getConfiguredBaseUriOrFallbackToCurrentRequest() | ||
->withPath($this->encryptionModuleUri) | ||
->withQuery(http_build_query($sealed->toArray())); | ||
} | ||
|
||
/** | ||
* @param 'privateKey' | 'publicKey' $slotName | ||
*/ | ||
private function getKeyString(string $slotName): string | ||
{ | ||
assert($this->rsaWallet instanceof RsaWalletServicePhp); | ||
// Prime key pair, male rsaWallet load the key pair | ||
$this->rsaWallet->getPublicKey($this->rsaKeyFingerprint); | ||
// Private property | ||
$keys = ObjectAccess::getProperty($this->rsaWallet, 'keys', true); | ||
// Property path in plain array | ||
$keyString = ObjectAccess::getPropertyPath( | ||
$keys, | ||
sprintf('%s.%s.keyString', $this->rsaKeyFingerprint, $slotName) | ||
); | ||
if (!\is_string($keyString)) { | ||
throw new InvalidKeyPairIdException('Invalid key fingerprint given', 1693231337); | ||
} | ||
|
||
return $keyString; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Netlogix\Sentry\Encryption; | ||
|
||
use function base64_decode; | ||
use function base64_encode; | ||
use Neos\Flow\Annotations as Flow; | ||
|
||
/** | ||
* @Flow\Proxy(false) | ||
*/ | ||
final class Sealed | ||
{ | ||
private string $encryptedData; | ||
|
||
private string $initializationVector; | ||
|
||
private string $envelopeKey; | ||
|
||
public function __construct(string $encryptedData, string $initializationVector, string $envelopeKeys) | ||
{ | ||
$this->encryptedData = $encryptedData; | ||
$this->initializationVector = $initializationVector; | ||
$this->envelopeKey = $envelopeKeys; | ||
} | ||
|
||
public static function fromArray(array $package): self | ||
{ | ||
return new self( | ||
$package['encryptedData'] ? base64_decode($package['encryptedData'], true) : '', | ||
$package['initializationVector'] ? base64_decode($package['initializationVector'], true) : '', | ||
$package['envelopeKey'] ? base64_decode($package['envelopeKey'], true) : '' | ||
); | ||
} | ||
|
||
public function toArray(): array | ||
{ | ||
return [ | ||
'encryptedData' => base64_encode($this->encryptedData), | ||
'initializationVector' => base64_encode($this->initializationVector), | ||
'envelopeKey' => base64_encode($this->envelopeKey), | ||
]; | ||
} | ||
|
||
public function getEncryptedData(): string | ||
{ | ||
return $this->encryptedData; | ||
} | ||
|
||
public function getInitializationVector(): string | ||
{ | ||
return $this->initializationVector; | ||
} | ||
|
||
public function getEnvelopeKey(): string | ||
{ | ||
return $this->envelopeKey; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Netlogix\Sentry\EventProcessor; | ||
|
||
use function json_encode; | ||
use Neos\Flow\Annotations as Flow; | ||
use Netlogix\Sentry\Encryption\EncryptionService; | ||
use Sentry\Event; | ||
use Sentry\EventHint; | ||
|
||
/** | ||
* @Flow\Scope("singleton") | ||
*/ | ||
final class EncryptedPayload implements EventProcessor | ||
{ | ||
private EncryptionService $encryption; | ||
|
||
private bool $encryptPostBody; | ||
|
||
public function injectEncryptionService(EncryptionService $encryption): void | ||
{ | ||
$this->encryption = $encryption; | ||
} | ||
|
||
public function injectSettings(array $settings): void | ||
{ | ||
$privacyCettings = $settings['privacy'] ?? []; | ||
$this->encryptPostBody = (bool) ($privacyCettings['encryptPostBody'] ?? false); | ||
} | ||
|
||
public function rewriteEvent(Event $event, EventHint $hint): Event | ||
{ | ||
if (!$this->encryptPostBody) { | ||
return $event; | ||
} | ||
|
||
$request = $event->getRequest(); | ||
|
||
$data = $request['data'] ?? []; | ||
if (!$data || !is_array($data)) { | ||
return $event; | ||
} | ||
|
||
$unencrypted = (string) json_encode($data, \JSON_PRETTY_PRINT); | ||
|
||
$encrypted = $this->encryption | ||
->seal($unencrypted); | ||
$uri = (string) $this->encryption | ||
->getEncryptionUriForSealedPayload($encrypted); | ||
|
||
$request['data'] = [ | ||
'__ENCRYPTED__DATA__' => $encrypted->toArray(), | ||
]; | ||
$event->setRequest($request); | ||
|
||
$extra = $event->getExtra() ?? []; | ||
$extra['Encrypted POST Data'] = $uri; | ||
$event->setExtra($extra); | ||
|
||
return $event; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Netlogix\Sentry\EventProcessor; | ||
|
||
use Sentry\Event; | ||
use Sentry\EventHint; | ||
|
||
interface EventProcessor | ||
{ | ||
public function rewriteEvent(Event $event, EventHint $hint): Event; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
privilegeTargets: | ||
|
||
'Neos\Flow\Security\Authorization\Privilege\Method\MethodPrivilege': | ||
|
||
'Netlogix.Sentry:Backend.EncryptedPayload': | ||
matcher: 'method(Netlogix\Sentry\Controller\EncryptedPayloadController->.*())' | ||
|
||
roles: | ||
|
||
'Neos.Flow:Anonymous': | ||
privileges: | ||
- | ||
privilegeTarget: 'Netlogix.Sentry:Backend.EncryptedPayload' | ||
permission: DENY | ||
|
||
'Neos.Neos:Administrator': | ||
privileges: | ||
- | ||
privilegeTarget: 'Netlogix.Sentry:Backend.EncryptedPayload' | ||
permission: GRANT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
- name: 'HashToken Login' | ||
uriPattern: 'neos/sentry/show-parameters' | ||
defaults: | ||
'@package': 'Netlogix.Sentry' | ||
'@controller': 'EncryptedPayload' | ||
'@action': 'decrypt' | ||
'@format': 'html' | ||
appendExceedingArguments: TRUE | ||
httpMethods: ['GET'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
Neos: | ||
Flow: | ||
|
||
mvc: | ||
routes: | ||
'Netlogix.Sentry': | ||
position: before Neos.Neos | ||
|
||
# Use the following configuration snippet when this package is used in conjunction with the neos/neos CMS. | ||
# Use something similar when another authentication provider will be used. | ||
# Unfortunately, this cannot be done preemptively. | ||
# | ||
# security: | ||
# authentication: | ||
# providers: | ||
# 'Neos.Neos:Backend': | ||
# requestPatterns: | ||
# 'Netlogix.Sentry:ShowEncryptedPayload': | ||
# pattern: ControllerObjectName | ||
# patternOptions: | ||
# controllerObjectNamePattern: 'Netlogix\Sentry\Controller\.*' | ||
|
||
|
Oops, something went wrong.