From 5973bb4d4f3c236d76ac25cb77c22e5317d5379f Mon Sep 17 00:00:00 2001
From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com>
Date: Thu, 4 Jun 2026 11:24:19 +0200
Subject: [PATCH] fix(security): hide notification secrets from non-admins
Prevent users without update permission from reading notification credentials and manual webhook secrets in Livewire state or rendered forms.
---
app/Livewire/Notifications/Discord.php | 4 +-
app/Livewire/Notifications/Pushover.php | 9 ++-
app/Livewire/Notifications/Slack.php | 4 +-
app/Livewire/Notifications/Telegram.php | 9 ++-
app/Livewire/Notifications/Webhook.php | 4 +-
app/Livewire/Project/Shared/Webhooks.php | 19 +++--
.../livewire/notifications/discord.blade.php | 12 ++-
.../livewire/notifications/pushover.blade.php | 21 ++++--
.../livewire/notifications/slack.blade.php | 12 ++-
.../livewire/notifications/telegram.blade.php | 21 ++++--
.../livewire/notifications/webhook.blade.php | 12 ++-
.../project/shared/webhooks.blade.php | 16 ++--
.../NotificationAuthorizationTest.php | 74 ++++++++++++++++++-
.../SharedResourceAuthorizationTest.php | 47 +++++++++++-
14 files changed, 219 insertions(+), 45 deletions(-)
diff --git a/app/Livewire/Notifications/Discord.php b/app/Livewire/Notifications/Discord.php
index ab3884320..59350a3e1 100644
--- a/app/Livewire/Notifications/Discord.php
+++ b/app/Livewire/Notifications/Discord.php
@@ -110,7 +110,9 @@ public function syncData(bool $toModel = false)
refreshSession();
} else {
$this->discordEnabled = $this->settings->discord_enabled;
- $this->discordWebhookUrl = $this->settings->discord_webhook_url;
+ $this->discordWebhookUrl = auth()->user()->can('update', $this->settings)
+ ? $this->settings->discord_webhook_url
+ : null;
$this->deploymentSuccessDiscordNotifications = $this->settings->deployment_success_discord_notifications;
$this->deploymentFailureDiscordNotifications = $this->settings->deployment_failure_discord_notifications;
diff --git a/app/Livewire/Notifications/Pushover.php b/app/Livewire/Notifications/Pushover.php
index d79eea87b..f894c5005 100644
--- a/app/Livewire/Notifications/Pushover.php
+++ b/app/Livewire/Notifications/Pushover.php
@@ -113,8 +113,13 @@ public function syncData(bool $toModel = false)
refreshSession();
} else {
$this->pushoverEnabled = $this->settings->pushover_enabled;
- $this->pushoverUserKey = $this->settings->pushover_user_key;
- $this->pushoverApiToken = $this->settings->pushover_api_token;
+ if (auth()->user()->can('update', $this->settings)) {
+ $this->pushoverUserKey = $this->settings->pushover_user_key;
+ $this->pushoverApiToken = $this->settings->pushover_api_token;
+ } else {
+ $this->pushoverUserKey = null;
+ $this->pushoverApiToken = null;
+ }
$this->deploymentSuccessPushoverNotifications = $this->settings->deployment_success_pushover_notifications;
$this->deploymentFailurePushoverNotifications = $this->settings->deployment_failure_pushover_notifications;
diff --git a/app/Livewire/Notifications/Slack.php b/app/Livewire/Notifications/Slack.php
index f870b3986..58cab5494 100644
--- a/app/Livewire/Notifications/Slack.php
+++ b/app/Livewire/Notifications/Slack.php
@@ -110,7 +110,9 @@ public function syncData(bool $toModel = false)
refreshSession();
} else {
$this->slackEnabled = $this->settings->slack_enabled;
- $this->slackWebhookUrl = $this->settings->slack_webhook_url;
+ $this->slackWebhookUrl = auth()->user()->can('update', $this->settings)
+ ? $this->settings->slack_webhook_url
+ : null;
$this->deploymentSuccessSlackNotifications = $this->settings->deployment_success_slack_notifications;
$this->deploymentFailureSlackNotifications = $this->settings->deployment_failure_slack_notifications;
diff --git a/app/Livewire/Notifications/Telegram.php b/app/Livewire/Notifications/Telegram.php
index fc3966cf6..78eb7ef9f 100644
--- a/app/Livewire/Notifications/Telegram.php
+++ b/app/Livewire/Notifications/Telegram.php
@@ -169,8 +169,13 @@ public function syncData(bool $toModel = false)
$this->settings->save();
} else {
$this->telegramEnabled = $this->settings->telegram_enabled;
- $this->telegramToken = $this->settings->telegram_token;
- $this->telegramChatId = $this->settings->telegram_chat_id;
+ if (auth()->user()->can('update', $this->settings)) {
+ $this->telegramToken = $this->settings->telegram_token;
+ $this->telegramChatId = $this->settings->telegram_chat_id;
+ } else {
+ $this->telegramToken = null;
+ $this->telegramChatId = null;
+ }
$this->deploymentSuccessTelegramNotifications = $this->settings->deployment_success_telegram_notifications;
$this->deploymentFailureTelegramNotifications = $this->settings->deployment_failure_telegram_notifications;
diff --git a/app/Livewire/Notifications/Webhook.php b/app/Livewire/Notifications/Webhook.php
index 630d422a9..4a67180ff 100644
--- a/app/Livewire/Notifications/Webhook.php
+++ b/app/Livewire/Notifications/Webhook.php
@@ -105,7 +105,9 @@ public function syncData(bool $toModel = false)
refreshSession();
} else {
$this->webhookEnabled = $this->settings->webhook_enabled;
- $this->webhookUrl = $this->settings->webhook_url;
+ $this->webhookUrl = auth()->user()->can('update', $this->settings)
+ ? $this->settings->webhook_url
+ : null;
$this->deploymentSuccessWebhookNotifications = $this->settings->deployment_success_webhook_notifications;
$this->deploymentFailureWebhookNotifications = $this->settings->deployment_failure_webhook_notifications;
diff --git a/app/Livewire/Project/Shared/Webhooks.php b/app/Livewire/Project/Shared/Webhooks.php
index eafc653d5..eb90262e9 100644
--- a/app/Livewire/Project/Shared/Webhooks.php
+++ b/app/Livewire/Project/Shared/Webhooks.php
@@ -34,19 +34,24 @@ public function mount()
{
$this->deploywebhook = generateDeployWebhook($this->resource);
- $this->githubManualWebhookSecret = data_get($this->resource, 'manual_webhook_secret_github');
+ if ($this->canViewSecrets()) {
+ $this->githubManualWebhookSecret = data_get($this->resource, 'manual_webhook_secret_github');
+ $this->gitlabManualWebhookSecret = data_get($this->resource, 'manual_webhook_secret_gitlab');
+ $this->bitbucketManualWebhookSecret = data_get($this->resource, 'manual_webhook_secret_bitbucket');
+ $this->giteaManualWebhookSecret = data_get($this->resource, 'manual_webhook_secret_gitea');
+ }
+
$this->githubManualWebhook = generateGitManualWebhook($this->resource, 'github');
-
- $this->gitlabManualWebhookSecret = data_get($this->resource, 'manual_webhook_secret_gitlab');
$this->gitlabManualWebhook = generateGitManualWebhook($this->resource, 'gitlab');
-
- $this->bitbucketManualWebhookSecret = data_get($this->resource, 'manual_webhook_secret_bitbucket');
$this->bitbucketManualWebhook = generateGitManualWebhook($this->resource, 'bitbucket');
-
- $this->giteaManualWebhookSecret = data_get($this->resource, 'manual_webhook_secret_gitea');
$this->giteaManualWebhook = generateGitManualWebhook($this->resource, 'gitea');
}
+ public function canViewSecrets(): bool
+ {
+ return auth()->user()->can('update', $this->resource);
+ }
+
public function submit()
{
try {
diff --git a/resources/views/livewire/notifications/discord.blade.php b/resources/views/livewire/notifications/discord.blade.php
index 0e5406c78..64e445441 100644
--- a/resources/views/livewire/notifications/discord.blade.php
+++ b/resources/views/livewire/notifications/discord.blade.php
@@ -26,9 +26,15 @@
helper="If enabled, a ping (@here) will be sent to the notification when a critical event happens."
label="Ping Enabled" />
-
diff --git a/resources/views/livewire/notifications/pushover.blade.php b/resources/views/livewire/notifications/pushover.blade.php
index 74cd9e8d2..4ea1a159c 100644
--- a/resources/views/livewire/notifications/pushover.blade.php
+++ b/resources/views/livewire/notifications/pushover.blade.php
@@ -24,12 +24,21 @@
diff --git a/resources/views/livewire/notifications/telegram.blade.php b/resources/views/livewire/notifications/telegram.blade.php
index f87a13c37..98ec128d5 100644
--- a/resources/views/livewire/notifications/telegram.blade.php
+++ b/resources/views/livewire/notifications/telegram.blade.php
@@ -24,12 +24,21 @@