From f9451188276b6a9ad8c6320c0fe2fb79ea2ecc33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Fri, 29 Aug 2025 23:24:42 +0200 Subject: [PATCH] Redact API keys overwritten via env variables to prevent leakage to undesired users --- src/Form/Type/APIKeyType.php | 31 +++++++++++++++++++++++++++++-- translations/messages.en.xlf | 6 ++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/Form/Type/APIKeyType.php b/src/Form/Type/APIKeyType.php index ae72f2a6..57eaea96 100644 --- a/src/Form/Type/APIKeyType.php +++ b/src/Form/Type/APIKeyType.php @@ -28,9 +28,14 @@ use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Contracts\Translation\TranslatorInterface; class APIKeyType extends AbstractType { + public function __construct(private readonly TranslatorInterface $translator) + { + } + public function getParent(): string { return PasswordType::class; @@ -38,8 +43,30 @@ class APIKeyType extends AbstractType public function buildView(FormView $view, FormInterface $form, array $options): void { - //Ensure that the field is never empty - $view->vars['value'] = $form->getViewData(); + $viewData = $form->getViewData(); + + //If the field is disabled, show the redacted API key + if ($options['disabled'] ?? false) { + if ($viewData === null || $viewData === '') { + $view->vars['value'] = $viewData; + } else { + + $view->vars['value'] = self::redact((string)$viewData) . ' (' . $this ->translator->trans("form.apikey.redacted") . ')'; + } + } else { //Otherwise, show the actual value + $view->vars['value'] = $viewData; + } + } + + public static function redact(string $apiKey): string + { + //Show only the last 2 characters of the API key if it is long enough (more than 16 characters) + //Replace all other characters with dots + if (strlen($apiKey) > 16) { + return str_repeat('*', strlen($apiKey) - 2) . substr($apiKey, -2); + } + + return str_repeat('*', strlen($apiKey)); } public function configureOptions(OptionsResolver $resolver): void diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index d9c4b1fd..481a5083 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -13051,5 +13051,11 @@ Please note, that you can not impersonate a disabled user. If you try you will g Info provider settings + + + form.apikey.redacted + Redacted for security reasons + +