From 43ac8c23c7d70361e0df5f7cf15127ca0d28722a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 19 Jul 2026 16:46:46 +0200 Subject: [PATCH] Show a warning banner on the homepage recommending to configure the trusted headers env --- .env | 8 ++++ src/Controller/HomepageController.php | 3 ++ src/Services/System/TrustedHostsChecker.php | 45 +++++++++++++++++++++ templates/homepage.html.twig | 10 +++++ translations/messages.en.xlf | 18 +++++++++ 5 files changed, 84 insertions(+) create mode 100644 src/Services/System/TrustedHostsChecker.php diff --git a/.env b/.env index 8cd39f31..557ed6e8 100644 --- a/.env +++ b/.env @@ -5,6 +5,14 @@ # Share that value with nobody and keep it secret APP_SECRET=a03498528f5a5fc089273ec9ae5b2849 +# Change this and uncomment the following line to set the trusted hosts for your Part-DB installation, aka under which +# domain names it is reachable. This is makes things more secure, because it can prevent certain header attacks. +# You have to escape dots in the domain name with a backslash +#TRUSTED_HOSTS='^(your-domain\.invalid)$' + +# You can also allow multiple domain names, e.g. for testing or development purposes, with an | between the domain names. +#TRUSTED_HOSTS='^(localhost|your-domain\.invalid)$' + ################################################################################### # Database settings ################################################################################### diff --git a/src/Controller/HomepageController.php b/src/Controller/HomepageController.php index f64f281f..bd7f7593 100644 --- a/src/Controller/HomepageController.php +++ b/src/Controller/HomepageController.php @@ -27,6 +27,7 @@ use App\Entity\Parts\Part; use App\Services\System\AppSecretChecker; use App\Services\System\BannerHelper; use App\Services\System\GitVersionInfoProvider; +use App\Services\System\TrustedHostsChecker; use App\Services\System\UpdateAvailableFacade; use Doctrine\ORM\EntityManagerInterface; use Omines\DataTablesBundle\DataTableFactory; @@ -41,6 +42,7 @@ class HomepageController extends AbstractController private readonly DataTableFactory $dataTable, private readonly BannerHelper $bannerHelper, private readonly AppSecretChecker $appSecretChecker, + private readonly TrustedHostsChecker $trustedHostsChecker, ) { } @@ -90,6 +92,7 @@ class HomepageController extends AbstractController 'new_version_url' => $updateAvailableManager->getLatestVersionUrl(), 'insecure_app_secret' => $this->appSecretChecker->isInsecureSecret(), 'suggested_app_secret' => $this->appSecretChecker->isInsecureSecret() ? $this->appSecretChecker->generateSecret() : null, + 'trusted_hosts_unconfigured' => $this->trustedHostsChecker->isTrustedHostsUnconfigured(), ]); } } diff --git a/src/Services/System/TrustedHostsChecker.php b/src/Services/System/TrustedHostsChecker.php new file mode 100644 index 00000000..49587dc9 --- /dev/null +++ b/src/Services/System/TrustedHostsChecker.php @@ -0,0 +1,45 @@ +. + */ + +declare(strict_types=1); + +namespace App\Services\System; + +use Symfony\Component\DependencyInjection\Attribute\Autowire; + +/** + * Checks whether the TRUSTED_HOSTS environment variable has been configured. + */ +final readonly class TrustedHostsChecker +{ + public function __construct( + #[Autowire('%env(TRUSTED_HOSTS)%')] + private string $trustedHosts, + ) { + } + + /** + * @return bool True if TRUSTED_HOSTS is not configured (meaning Part-DB accepts requests with any Host header), false otherwise. + */ + public function isTrustedHostsUnconfigured(): bool + { + return trim($this->trustedHosts) === ''; + } +} diff --git a/templates/homepage.html.twig b/templates/homepage.html.twig index 2a191f14..7b000e9d 100644 --- a/templates/homepage.html.twig +++ b/templates/homepage.html.twig @@ -95,6 +95,16 @@ {% endif %} + {% if trusted_hosts_unconfigured and is_granted('@system.server_infos') %} + + {% endif %} + {% if is_granted('@system.show_updates') %} {{ nv.new_version_alert(new_version_available, new_version, new_version_url) }} {% endif %} diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index 2a537775..d4d40359 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -13697,6 +13697,24 @@ Buerklin-API Authentication server: You can use this randomly generated value (share it with nobody): + + + system.trusted_hosts.unconfigured.title + TRUSTED_HOSTS not configured + + + + + system.trusted_hosts.unconfigured.message + The <code>TRUSTED_HOSTS</code> environment variable is not set. This means Part-DB will accept requests for any host name, which can be a security risk (e.g. HTTP Host header injection). It is recommended to restrict this to the host names Part-DB is actually reachable under. + + + + + system.trusted_hosts.unconfigured.suggestion + Set it to a regular expression matching all host names Part-DB should be reachable under in your <code>.env.local</code> or <code>docker-compose.yaml</code> file, e.g. based on the host name you used to access this page: + + info_providers.provider_key