Show a warning banner on the homepage recommending to configure the trusted headers env
Some checks are pending
Build assets artifact / Build assets artifact (push) Waiting to run
Docker Image Build / build (linux/amd64, amd64, ubuntu-latest) (push) Waiting to run
Docker Image Build / build (linux/arm/v7, armv7, ubuntu-24.04-arm) (push) Waiting to run
Docker Image Build / build (linux/arm64, arm64, ubuntu-24.04-arm) (push) Waiting to run
Docker Image Build / merge (push) Blocked by required conditions
Docker Image Build (FrankenPHP) / build (linux/amd64, amd64, ubuntu-latest) (push) Waiting to run
Docker Image Build (FrankenPHP) / build (linux/arm/v7, armv7, ubuntu-24.04-arm) (push) Waiting to run
Docker Image Build (FrankenPHP) / build (linux/arm64, arm64, ubuntu-24.04-arm) (push) Waiting to run
Docker Image Build (FrankenPHP) / merge (push) Blocked by required conditions
Static analysis / Static analysis (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, mysql) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, mysql) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, mysql) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.5, mysql) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, postgres) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, postgres) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, postgres) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.5, postgres) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, sqlite) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, sqlite) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, sqlite) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.5, sqlite) (push) Waiting to run

This commit is contained in:
Jan Böhmer 2026-07-19 16:46:46 +02:00
parent e80e4a1bcd
commit 43ac8c23c7
5 changed files with 84 additions and 0 deletions

8
.env
View file

@ -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
###################################################################################

View file

@ -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(),
]);
}
}

View file

@ -0,0 +1,45 @@
<?php
/*
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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) === '';
}
}

View file

@ -95,6 +95,16 @@
</div>
{% endif %}
{% if trusted_hosts_unconfigured and is_granted('@system.server_infos') %}
<div class="alert alert-warning" role="alert">
<h5><i class="fa-solid fa-triangle-exclamation fa-fw"></i> {% trans %}system.trusted_hosts.unconfigured.title{% endtrans %}</h5>
<p class="mb-1">{% trans %}system.trusted_hosts.unconfigured.message{% endtrans %}</p>
<p class="mb-0">{% trans %}system.trusted_hosts.unconfigured.suggestion{% endtrans %}
<br><code>TRUSTED_HOSTS='^({{ app.request.host|replace({'.': '\\.'}) }})$'</code></p>
<small>{% trans %}update_manager.new_version_available.only_administrators_can_see{% endtrans %}</small>
</div>
{% endif %}
{% if is_granted('@system.show_updates') %}
{{ nv.new_version_alert(new_version_available, new_version, new_version_url) }}
{% endif %}

View file

@ -13697,6 +13697,24 @@ Buerklin-API Authentication server:
<target>You can use this randomly generated value (share it with nobody):</target>
</segment>
</unit>
<unit id="OP7MacF" name="system.trusted_hosts.unconfigured.title">
<segment state="translated">
<source>system.trusted_hosts.unconfigured.title</source>
<target>TRUSTED_HOSTS not configured</target>
</segment>
</unit>
<unit id="88NkHLV" name="system.trusted_hosts.unconfigured.message">
<segment state="translated">
<source>system.trusted_hosts.unconfigured.message</source>
<target>The &lt;code&gt;TRUSTED_HOSTS&lt;/code&gt; 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.</target>
</segment>
</unit>
<unit id="qZ_kgWT" name="system.trusted_hosts.unconfigured.suggestion">
<segment state="translated">
<source>system.trusted_hosts.unconfigured.suggestion</source>
<target>Set it to a regular expression matching all host names Part-DB should be reachable under in your &lt;code&gt;.env.local&lt;/code&gt; or &lt;code&gt;docker-compose.yaml&lt;/code&gt; file, e.g. based on the host name you used to access this page:</target>
</segment>
</unit>
<unit id="cEwxoSj" name="info_providers.provider_key">
<segment state="translated">
<source>info_providers.provider_key</source>