Improve outbound URL validation (#10833)

This commit is contained in:
Andras Bacsai authored and GitHub committed 2026-07-02 15:02:37 +02:00
commit bed058b826
12 files changed
+440 -85

No files matched your search

+18 -1
View File
@@ -3,6 +3,7 @@
namespace App\Jobs;
use App\Notifications\Dto\DiscordMessage;
use App\Rules\SafeWebhookUrl;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
use Illuminate\Contracts\Queue\ShouldQueue;
@@ -10,6 +11,8 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
class SendMessageToDiscordJob implements ShouldBeEncrypted, ShouldQueue
{
@@ -41,6 +44,20 @@ class SendMessageToDiscordJob implements ShouldBeEncrypted, ShouldQueue
*/
public function handle(): void
{
Http::post($this->webhookUrl, $this->message->toPayload());
$validator = Validator::make(
['webhook_url' => $this->webhookUrl],
['webhook_url' => ['required', 'url', new SafeWebhookUrl]]
);
if ($validator->fails()) {
Log::warning('SendMessageToDiscordJob: blocked unsafe webhook URL', [
'url' => $this->webhookUrl,
'errors' => $validator->errors()->all(),
]);
return;
}
Http::withOptions(['allow_redirects' => false])->post($this->webhookUrl, $this->message->toPayload());
}
}
+19 -2
View File
@@ -3,6 +3,7 @@
namespace App\Jobs;
use App\Notifications\Dto\SlackMessage;
use App\Rules\SafeWebhookUrl;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
use Illuminate\Contracts\Queue\ShouldQueue;
@@ -10,6 +11,8 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
class SendMessageToSlackJob implements ShouldBeEncrypted, ShouldQueue
{
@@ -34,6 +37,20 @@ class SendMessageToSlackJob implements ShouldBeEncrypted, ShouldQueue
public function handle(): void
{
$validator = Validator::make(
['webhook_url' => $this->webhookUrl],
['webhook_url' => ['required', 'url', new SafeWebhookUrl]]
);
if ($validator->fails()) {
Log::warning('SendMessageToSlackJob: blocked unsafe webhook URL', [
'url' => $this->webhookUrl,
'errors' => $validator->errors()->all(),
]);
return;
}
if ($this->isSlackWebhook()) {
$this->sendToSlack();
@@ -64,7 +81,7 @@ class SendMessageToSlackJob implements ShouldBeEncrypted, ShouldQueue
private function sendToSlack(): void
{
Http::post($this->webhookUrl, [
Http::withOptions(['allow_redirects' => false])->post($this->webhookUrl, [
'text' => $this->message->title,
'blocks' => [
[
@@ -106,7 +123,7 @@ class SendMessageToSlackJob implements ShouldBeEncrypted, ShouldQueue
{
$username = config('app.name');
Http::post($this->webhookUrl, [
Http::withOptions(['allow_redirects' => false])->post($this->webhookUrl, [
'username' => $username,
'attachments' => [
[
+1 -1
View File
@@ -64,7 +64,7 @@ class SendWebhookJob implements ShouldBeEncrypted, ShouldQueue
]);
}
$response = Http::post($this->webhookUrl, $this->payload);
$response = Http::withOptions(['allow_redirects' => false])->post($this->webhookUrl, $this->payload);
if (isDev()) {
ray('Webhook response', [