mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-06-08 19:51:36 +00:00
Show a warning if using the default APP_SECRET value
This commit is contained in:
parent
c229208bd5
commit
f888e10827
5 changed files with 111 additions and 3 deletions
|
|
@ -22,6 +22,7 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace App\Command;
|
||||
|
||||
use App\Services\System\AppSecretChecker;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
|
@ -33,7 +34,9 @@ use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
|
|||
#[AsCommand('partdb:check-requirements', 'Checks if the requirements Part-DB needs or recommends are fulfilled.')]
|
||||
class CheckRequirementsCommand extends Command
|
||||
{
|
||||
public function __construct(protected ContainerBagInterface $params)
|
||||
public function __construct(protected ContainerBagInterface $params, AppSecretChecker $secretChecker,
|
||||
private readonly AppSecretChecker $appSecretChecker
|
||||
)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
|
@ -121,6 +124,16 @@ class CheckRequirementsCommand extends Command
|
|||
$io->success('Debug mode disabled.');
|
||||
}
|
||||
|
||||
//Check if APP_SECRET has been changed from the default
|
||||
if ($io->isVerbose()) {
|
||||
$io->comment('Checking APP_SECRET...');
|
||||
}
|
||||
if ($this->appSecretChecker->isInsecureSecret()) {
|
||||
$io->warning('APP_SECRET is set to the default value shipped with Part-DB. This is a security risk! Generate a new secret (e.g. using "openssl rand -hex 32") and set it as APP_SECRET in your .env.local file.');
|
||||
} elseif (!$only_issues) {
|
||||
$io->success('APP_SECRET has been changed from the default value.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function checkPHPExtensions(SymfonyStyle $io, bool $only_issues = false): void
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ namespace App\Controller;
|
|||
|
||||
use App\DataTables\LogDataTable;
|
||||
use App\Entity\Parts\Part;
|
||||
use App\Services\System\AppSecretChecker;
|
||||
use App\Services\System\BannerHelper;
|
||||
use App\Services\System\GitVersionInfoProvider;
|
||||
use App\Services\System\UpdateAvailableFacade;
|
||||
|
|
@ -36,8 +37,11 @@ use Symfony\Component\Routing\Attribute\Route;
|
|||
|
||||
class HomepageController extends AbstractController
|
||||
{
|
||||
public function __construct(private readonly DataTableFactory $dataTable, private readonly BannerHelper $bannerHelper)
|
||||
{
|
||||
public function __construct(
|
||||
private readonly DataTableFactory $dataTable,
|
||||
private readonly BannerHelper $bannerHelper,
|
||||
private readonly AppSecretChecker $appSecretChecker,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -84,6 +88,8 @@ class HomepageController extends AbstractController
|
|||
'new_version_available' => $updateAvailableManager->isUpdateAvailable(),
|
||||
'new_version' => $updateAvailableManager->getLatestVersionString(),
|
||||
'new_version_url' => $updateAvailableManager->getLatestVersionUrl(),
|
||||
'insecure_app_secret' => $this->appSecretChecker->isInsecureSecret(),
|
||||
'suggested_app_secret' => $this->appSecretChecker->isInsecureSecret() ? $this->appSecretChecker->generateSecret() : null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
62
src/Services/System/AppSecretChecker.php
Normal file
62
src/Services/System/AppSecretChecker.php
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<?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 APP_SECRET has been changed from the default value shipped with Part-DB.
|
||||
*/
|
||||
final readonly class AppSecretChecker
|
||||
{
|
||||
/** Known default/example secrets that must not be used in production. */
|
||||
public const INSECURE_SECRETS = [
|
||||
'a03498528f5a5fc089273ec9ae5b2849', // default in .env
|
||||
'318b5d659e07a0b3f96d9b3a83b254ca', // default in .env.dev
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
#[Autowire('%kernel.secret%')]
|
||||
private string $appSecret,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool True if the app secret is one of the known insecure default secrets, false otherwise.
|
||||
*/
|
||||
public function isInsecureSecret(): bool
|
||||
{
|
||||
return in_array($this->appSecret, self::INSECURE_SECRETS, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new random app secret that can be used to replace the default insecure one.
|
||||
* @return string
|
||||
* @throws \Random\RandomException
|
||||
*/
|
||||
public function generateSecret(): string
|
||||
{
|
||||
//Symfony docs recommend 32 characters for the app secret, which are 16 random bytes when hex-encoded.
|
||||
return bin2hex(random_bytes(16));
|
||||
}
|
||||
}
|
||||
|
|
@ -85,6 +85,15 @@
|
|||
|
||||
{% block content %}
|
||||
|
||||
{% if insecure_app_secret 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.app_secret.insecure.title{% endtrans %}</h5>
|
||||
<p class="mb-1">{% trans %}system.app_secret.insecure.message{% endtrans %}</p>
|
||||
<p class="mb-0">{% trans %}system.app_secret.insecure.suggestion{% endtrans %}
|
||||
<br><code>APP_SECRET={{ suggested_app_secret }}</code></p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if is_granted('@system.show_updates') %}
|
||||
{{ nv.new_version_alert(new_version_available, new_version, new_version_url) }}
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -13649,5 +13649,23 @@ Buerklin-API Authentication server:
|
|||
<target>When enabled users with the info provider permission can submit pages to Part-DB and retrieve them later.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="JqcvhX_" name="system.app_secret.insecure.title">
|
||||
<segment state="translated">
|
||||
<source>system.app_secret.insecure.title</source>
|
||||
<target>Insecure APP_SECRET</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="XSSYWTJ" name="system.app_secret.insecure.message">
|
||||
<segment state="translated">
|
||||
<source>system.app_secret.insecure.message</source>
|
||||
<target>APP_SECRET is set to the default value shipped with Part-DB. This is a security risk! Set it to a new random value in your .env.local or docker-compose.yaml file.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="e7.f3m0" name="system.app_secret.insecure.suggestion">
|
||||
<segment state="translated">
|
||||
<source>system.app_secret.insecure.suggestion</source>
|
||||
<target>You can use this randomly generated value (share it with nobody):</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue