Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge up 4.9.x to 5.0.x #619

Merged
merged 5 commits into from
Jul 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 90 additions & 12 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,11 @@ parameters:
count: 1
path: src/symfony/src/Controller/AttestationControllerFactory.php

-
message: "#^Method Webauthn\\\\Bundle\\\\CredentialOptionsBuilder\\\\PublicKeyCredentialCreationOptionsBuilder\\:\\:getFromRequest\\(\\) invoked with 3 parameters, 2 required\\.$#"
count: 1
path: src/symfony/src/Controller/AttestationRequestController.php

-
message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpFoundation\\\\Request\\:\\:getContentType\\(\\)\\.$#"
count: 1
Expand Down Expand Up @@ -807,11 +812,6 @@ parameters:
count: 1
path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedRequestOptionsBuilder.php

-
message: "#^Should not use function \"dump\", please change the code\\.$#"
count: 1
path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedRequestOptionsBuilder.php

-
message: """
#^Fetching class constant class of deprecated class Webauthn\\\\Bundle\\\\Event\\\\AuthenticatorAssertionResponseValidationFailedEvent\\:
Expand Down Expand Up @@ -1061,6 +1061,11 @@ parameters:
count: 4
path: src/symfony/src/DependencyInjection/WebauthnExtension.php

-
message: "#^Cannot access offset 'hide_existing…' on mixed\\.$#"
count: 1
path: src/symfony/src/DependencyInjection/WebauthnExtension.php

-
message: "#^Cannot access offset 'host' on mixed\\.$#"
count: 4
Expand Down Expand Up @@ -2416,6 +2421,41 @@ parameters:
count: 1
path: src/webauthn/src/Denormalizer/AttestationStatementDenormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\AttestedCredentialDataNormalizer\\:\\:normalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/AttestedCredentialDataNormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\AttestedCredentialDataNormalizer\\:\\:normalize\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/AttestedCredentialDataNormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\AttestedCredentialDataNormalizer\\:\\:supportsNormalization\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/AttestedCredentialDataNormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\AuthenticationExtensionNormalizer\\:\\:normalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/AuthenticationExtensionNormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\AuthenticationExtensionNormalizer\\:\\:normalize\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/AuthenticationExtensionNormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\AuthenticationExtensionNormalizer\\:\\:normalize\\(\\) should return array but returns mixed\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/AuthenticationExtensionNormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\AuthenticationExtensionNormalizer\\:\\:supportsNormalization\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/AuthenticationExtensionNormalizer.php

-
message: """
#^Fetching class constant class of deprecated class Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensionsClientInputs\\:
Expand Down Expand Up @@ -2469,7 +2509,7 @@ parameters:

-
message: "#^Cannot access offset 'clientDataJSON' on mixed\\.$#"
count: 3
count: 2
path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php

-
Expand All @@ -2479,7 +2519,7 @@ parameters:

-
message: "#^Cannot access offset 'userHandle' on mixed\\.$#"
count: 3
count: 1
path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php

-
Expand Down Expand Up @@ -2517,11 +2557,6 @@ parameters:
count: 1
path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php

-
message: "#^Parameter \\#4 \\$userHandle of static method Webauthn\\\\AuthenticatorAssertionResponse\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php

-
message: "#^Parameter \\#5 \\$attestationObject of static method Webauthn\\\\AuthenticatorAssertionResponse\\:\\:create\\(\\) expects Webauthn\\\\AttestationStatement\\\\AttestationObject\\|null, mixed given\\.$#"
count: 1
Expand Down Expand Up @@ -2682,6 +2717,21 @@ parameters:
count: 1
path: src/webauthn/src/Denormalizer/PublicKeyCredentialDenormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\PublicKeyCredentialDescriptorNormalizer\\:\\:normalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/PublicKeyCredentialDescriptorNormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\PublicKeyCredentialDescriptorNormalizer\\:\\:normalize\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/PublicKeyCredentialDescriptorNormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\PublicKeyCredentialDescriptorNormalizer\\:\\:supportsNormalization\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/PublicKeyCredentialDescriptorNormalizer.php

-
message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#"
count: 1
Expand Down Expand Up @@ -2957,11 +3007,26 @@ parameters:
count: 1
path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\PublicKeyCredentialSourceDenormalizer\\:\\:normalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\PublicKeyCredentialSourceDenormalizer\\:\\:normalize\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\PublicKeyCredentialSourceDenormalizer\\:\\:supportsDenormalization\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php

-
message: "#^Method Webauthn\\\\Denormalizer\\\\PublicKeyCredentialSourceDenormalizer\\:\\:supportsNormalization\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php

-
message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\Util\\\\Base64\\:\\:decode\\(\\) expects string, mixed given\\.$#"
count: 1
Expand Down Expand Up @@ -3287,3 +3352,16 @@ parameters:
message: "#^Parameter \\#1 \\$ecdaaKeyId of class Webauthn\\\\TrustPath\\\\EcdaaKeyIdTrustPath constructor expects string, mixed given\\.$#"
count: 1
path: src/webauthn/src/TrustPath/EcdaaKeyIdTrustPath.php

-
message: """
#^Instantiation of deprecated class Webauthn\\\\TrustPath\\\\EcdaaKeyIdTrustPath\\:
since 4\\.2\\.0 and will be removed in 5\\.0\\.0\\. The ECDAA Trust Anchor does no longer exist in Webauthn specification\\.$#
"""
count: 1
path: src/webauthn/src/TrustPath/TrustPathLoader.php

-
message: "#^Parameter \\#1 \\$certificates of static method Webauthn\\\\TrustPath\\\\CertificateTrustPath\\:\\:create\\(\\) expects array\\<string\\>, array given\\.$#"
count: 1
path: src/webauthn/src/TrustPath/TrustPathLoader.php
4 changes: 3 additions & 1 deletion src/symfony/src/Controller/AttestationControllerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,15 @@ public function createRequestController(
OptionsStorage $optionStorage,
CreationOptionsHandler $creationOptionsHandler,
FailureHandler|AuthenticationFailureHandlerInterface $failureHandler,
bool $hideExistingExcludedCredentials = false
): AttestationRequestController {
return new AttestationRequestController(
$optionsBuilder,
$userEntityGuesser,
$optionStorage,
$creationOptionsHandler,
$failureHandler
$failureHandler,
$hideExistingExcludedCredentials
);
}

Expand Down
7 changes: 6 additions & 1 deletion src/symfony/src/Controller/AttestationRequestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,19 @@ public function __construct(
private readonly OptionsStorage $optionsStorage,
private readonly CreationOptionsHandler $creationOptionsHandler,
private readonly FailureHandler|AuthenticationFailureHandlerInterface $failureHandler,
private readonly bool $hideExistingExcludedCredentials = false,
) {
}

public function __invoke(Request $request): Response
{
try {
$userEntity = $this->userEntityGuesser->findUserEntity($request);
$publicKeyCredentialCreationOptions = $this->extractor->getFromRequest($request, $userEntity);
$publicKeyCredentialCreationOptions = $this->extractor->getFromRequest(
$request,
$userEntity,
$this->hideExistingExcludedCredentials
);

$response = $this->creationOptionsHandler->onCreationOptions(
$publicKeyCredentialCreationOptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public function __construct(

public function getFromRequest(
Request $request,
PublicKeyCredentialUserEntity $userEntity
PublicKeyCredentialUserEntity $userEntity,
bool $hideExistingExcludedCredentials = false
): PublicKeyCredentialCreationOptions {
$format = method_exists(
$request,
Expand All @@ -57,7 +58,7 @@ public function getFromRequest(
$format === 'json' || throw new BadRequestHttpException('Only JSON content type allowed');
$content = $request->getContent();

$excludedCredentials = $this->getCredentials($userEntity);
$excludedCredentials = $hideExistingExcludedCredentials === true ? [] : $this->getCredentials($userEntity);
$optionsRequest = $this->getServerPublicKeyCredentialCreationOptionsRequest($content);
$authenticatorSelectionData = $optionsRequest->authenticatorSelection;
$authenticatorSelection = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public function getFromRequest(
$userEntity = $optionsRequest->username === null ? null : $this->userEntityRepository->findOneByUsername(
$optionsRequest->username
);
dump($this->fakeCredentialGenerator?->generate($request, $optionsRequest->username ?? ''));

$allowedCredentials = match (true) {
$userEntity === null && $optionsRequest->username === null, $userEntity === null && $optionsRequest->username !== null && $this->fakeCredentialGenerator === null => [],
$userEntity === null && $optionsRequest->username !== null && $this->fakeCredentialGenerator !== null => $this->fakeCredentialGenerator->generate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface PublicKeyCredentialCreationOptionsBuilder
{
public function getFromRequest(
Request $request,
PublicKeyCredentialUserEntity $userEntity
PublicKeyCredentialUserEntity $userEntity,
/*bool $hideExistingExcludedCredentials = false*/
): PublicKeyCredentialCreationOptions;
}
57 changes: 45 additions & 12 deletions src/symfony/src/DataCollector/WebauthnCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
use Symfony\Component\Serializer\Encoder\JsonEncode;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\VarDumper\Cloner\Data;
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Throwable;
Expand Down Expand Up @@ -52,6 +56,11 @@ class WebauthnCollector extends DataCollector implements EventSubscriberInterfac
*/
private array $authenticatorAssertionResponseValidationFailed = [];

public function __construct(
private readonly SerializerInterface $serializer
) {
}

public function collect(Request $request, Response $response, ?Throwable $exception = null): void
{
$this->data = [
Expand Down Expand Up @@ -110,9 +119,13 @@ public function addPublicKeyCredentialCreationOptions(PublicKeyCredentialCreatio
$cloner = new VarCloner();
$this->publicKeyCredentialCreationOptions[] = [
'options' => $cloner->cloneVar($event->publicKeyCredentialCreationOptions),
'json' => json_encode(
'json' => $this->serializer->serialize(
$event->publicKeyCredentialCreationOptions,
JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT
JsonEncoder::FORMAT,
[
AbstractObjectNormalizer::SKIP_NULL_VALUES => true,
JsonEncode::OPTIONS => JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT,
]
),
];
}
Expand All @@ -124,9 +137,13 @@ public function addAuthenticatorAttestationResponseValidationSucceeded(
$this->authenticatorAttestationResponseValidationSucceeded[] = [
'attestation_response' => $cloner->cloneVar($event->authenticatorAttestationResponse),
'options' => $cloner->cloneVar($event->publicKeyCredentialCreationOptions),
'options_json' => json_encode(
'options_json' => $this->serializer->serialize(
$event->publicKeyCredentialCreationOptions,
JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT
JsonEncoder::FORMAT,
[
AbstractObjectNormalizer::SKIP_NULL_VALUES => true,
JsonEncode::OPTIONS => JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT,
]
),
'credential_source' => $cloner->cloneVar($event->publicKeyCredentialSource),
];
Expand All @@ -139,9 +156,13 @@ public function addAuthenticatorAttestationResponseValidationFailed(
$this->authenticatorAttestationResponseValidationFailed[] = [
'attestation_response' => $cloner->cloneVar($event->authenticatorAttestationResponse),
'options' => $cloner->cloneVar($event->publicKeyCredentialCreationOptions),
'options_json' => json_encode(
'options_json' => $this->serializer->serialize(
$event->publicKeyCredentialCreationOptions,
JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT
JsonEncoder::FORMAT,
[
AbstractObjectNormalizer::SKIP_NULL_VALUES => true,
JsonEncode::OPTIONS => JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT,
]
),
'exception' => $cloner->cloneVar($event->throwable),
];
Expand All @@ -152,9 +173,13 @@ public function addPublicKeyCredentialRequestOptions(PublicKeyCredentialRequestO
$cloner = new VarCloner();
$this->publicKeyCredentialRequestOptions[] = [
'options' => $cloner->cloneVar($event->publicKeyCredentialRequestOptions),
'json' => json_encode(
'json' => $this->serializer->serialize(
$event->publicKeyCredentialRequestOptions,
JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT
JsonEncoder::FORMAT,
[
AbstractObjectNormalizer::SKIP_NULL_VALUES => true,
JsonEncode::OPTIONS => JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT,
]
),
];
}
Expand All @@ -168,9 +193,13 @@ public function addAuthenticatorAssertionResponseValidationSucceeded(
'credential_id' => $cloner->cloneVar($event->credentialId),
'assertion_response' => $cloner->cloneVar($event->authenticatorAssertionResponse),
'options' => $cloner->cloneVar($event->publicKeyCredentialRequestOptions),
'options_json' => json_encode(
'options_json' => $this->serializer->serialize(
$event->publicKeyCredentialRequestOptions,
JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT
JsonEncoder::FORMAT,
[
AbstractObjectNormalizer::SKIP_NULL_VALUES => true,
JsonEncode::OPTIONS => JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT,
]
),
'credential_source' => $cloner->cloneVar($event->publicKeyCredentialSource),
];
Expand All @@ -185,9 +214,13 @@ public function addAuthenticatorAssertionResponseValidationFailed(
'credential_id' => $cloner->cloneVar($event->getCredential()?->publicKeyCredentialId),
'assertion_response' => $cloner->cloneVar($event->authenticatorAssertionResponse),
'options' => $cloner->cloneVar($event->publicKeyCredentialRequestOptions),
'options_json' => json_encode(
'options_json' => $this->serializer->serialize(
$event->publicKeyCredentialRequestOptions,
JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT
JsonEncoder::FORMAT,
[
AbstractObjectNormalizer::SKIP_NULL_VALUES => true,
JsonEncode::OPTIONS => JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT,
]
),
'exception' => $cloner->cloneVar($event->throwable),
];
Expand Down
6 changes: 6 additions & 0 deletions src/symfony/src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,12 @@ private function addControllersConfig(ArrayNodeDefinition $rootNode): void
->scalarNode('user_entity_guesser')
->isRequired()
->end()
->scalarNode('hide_existing_credentials')
->info(
'In order to prevent username enumeration, the existing credentials can be hidden. This is highly recommended when the attestation ceremony is performed by anonymous users.'
)
->defaultFalse()
->end()
->scalarNode('options_storage')
->defaultValue(SessionStorage::class)
->info('Service responsible of the options/user entity storage during the ceremony')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ private function createAttestationRequestControllerAndRoute(
new Reference($optionsStorageId),
new Reference($optionsHandlerId),
new Reference($failureHandlerId),
true,
]);
$this->createControllerAndRoute(
$container,
Expand Down
1 change: 1 addition & 0 deletions src/symfony/src/DependencyInjection/WebauthnExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ private function loadCreationControllersSupport(ContainerBuilder $container, arr
new Reference($creationConfig['options_storage']),
new Reference($creationConfig['options_handler']),
new Reference($creationConfig['failure_handler']),
$creationConfig['hide_existing_credentials'] ?? false,
])
->addTag(DynamicRouteCompilerPass::TAG, [
'method' => $creationConfig['options_method'],
Expand Down
Loading
Loading