fix: restrict deep_link to relative paths and http(s)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BCrwHHnGCB5XH968Nxokqw
This commit is contained in:
@@ -83,6 +83,19 @@ class ClientApiTest extends TestCase
|
||||
->assertStatus(422)->assertJsonValidationErrors(['events']);
|
||||
}
|
||||
|
||||
public function test_deep_link_must_be_relative_or_http(): void
|
||||
{
|
||||
$bad = $this->item(['payload' => ['title' => 'x', 'deep_link' => 'javascript:alert(1)']]);
|
||||
$this->putJson('/api/events', ['events' => [$bad]], $this->auth())
|
||||
->assertStatus(422)->assertJsonValidationErrors(['events.0.payload.deep_link']);
|
||||
|
||||
$ok1 = $this->item(['payload' => ['title' => 'x', 'deep_link' => '/people/42']]);
|
||||
$this->putJson('/api/events', ['events' => [$ok1]], $this->auth())->assertOk();
|
||||
|
||||
$ok2 = $this->item(['topic' => 'birthday:2027', 'payload' => ['title' => 'x', 'deep_link' => 'https://docs.example/x']]);
|
||||
$this->putJson('/api/events', ['events' => [$ok2]], $this->auth())->assertOk();
|
||||
}
|
||||
|
||||
public function test_topic_defaults_to_empty_string(): void
|
||||
{
|
||||
$item = $this->item();
|
||||
|
||||
@@ -88,4 +88,22 @@ class InboxPageTest extends TestCase
|
||||
$this->assertStringContainsString('<title>Hado</title>', $html);
|
||||
$this->assertStringNotContainsString('class="counter"', $html);
|
||||
}
|
||||
|
||||
public function test_unsafe_deep_link_is_not_rendered_as_href(): void
|
||||
{
|
||||
$this->get('/', ['X-Remote-User' => 'nikita']);
|
||||
$user = User::sole();
|
||||
$source = Source::create(['name' => 'docs', 'token_hash' => hash('sha256', 'x')]);
|
||||
Event::create([
|
||||
'source_id' => $source->id, 'user_id' => $user->id, 'source_ref' => 'r', 'topic' => 'a',
|
||||
'due_mode' => DueMode::Local, 'due_date' => '2026-09-04', 'due_time' => '24:00:00', 'fire_on' => '2026-09-04',
|
||||
'after_due' => AfterDue::Keep, 'payload' => ['title' => 'Опасное событие', 'deep_link' => 'javascript:alert(1)'],
|
||||
'state' => EventState::Today, 'quiet_until' => CarbonImmutable::parse('2000-01-01Z'),
|
||||
]);
|
||||
|
||||
$html = $this->get('/', ['X-Remote-User' => 'nikita'])->assertOk()->getContent();
|
||||
|
||||
$this->assertStringNotContainsString('href="javascript:', $html);
|
||||
$this->assertStringContainsString('Опасное событие', $html);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user