| Название | yaojingang GEOFlow commit/2aeec4f449c9fa6790392723150c9151b6a4a337 Server-Side Request Forgery |
|---|
| Описание | ## Generic HTTP SSRF Reachable by Regular Admins
### Root Cause
Distribution management routes are available to authenticated admins, not only superadmins. A regular admin can create a `generic_http_api` channel, set `endpoint_url` to an arbitrary `http/https` target, and then trigger backend requests through the health-check and site-settings sync flows.
Relevant code path:
```php
// routes/web.php
Route::middleware(['admin.auth', 'admin.activity'])->group(function () {
Route::prefix('distribution')->name('distribution.')->group(function () {
Route::post('create', [DistributionController::class, 'store'])->name('store');
Route::post('{channelId}/health', [DistributionController::class, 'health'])->name('health');
Route::post('{channelId}/sync-settings', [DistributionController::class, 'syncSettings'])->name('sync-settings');
});
});
```
```php
// app/Http/Controllers/Admin/DistributionController.php
private function isValidHttpEndpoint(string $endpointUrl): bool
{
...
return in_array($scheme, ['http', 'https'], true) && $host !== '';
}
```
```php
// app/Services/GeoFlow/GenericHttpEndpointResolver.php
$baseUrl = rtrim((string) $channel->endpoint_url, '/');
return $baseUrl.(str_starts_with($resolvedPath, '/') ? $resolvedPath : '/'.$resolvedPath);
```
```php
// app/Services/GeoFlow/GenericHttpApiPublisher.php
$response = $method === 'GET'
? $request->send($method, $endpoint)
: $request->withBody($wireBody, 'application/json')->send($method, $endpoint);
```
There is no allowlist, no block on loopback/RFC1918/link-local targets, and no restriction that only superadmins may manage this channel type. As a result, a regular admin can turn the server into a generic outbound HTTP client against arbitrary destinations.
### Trigger Flow
Attack preconditions:
- A regular admin account, or an admin browser session obtained via XSS.
Trigger flow:
1. Log in to `/geo_admin` as a regular admin.
2. Create a distribution channel with `channel_type=generic_http_api`.
3. Set `endpoint_url` to an attacker-controlled or internal-only target such as `http://127.0.0.1:8080`.
4. Trigger `/geo_admin/distribution/<channelId>/health` for SSRF probing, or `/geo_admin/distribution/<channelId>/sync-settings` for server-side POST delivery.
5. The backend sends the request from the server context to the attacker-chosen destination.
|
|---|
| Источник | ⚠️ https://github.com/yaojingang/GEOFlow/issues/60 |
|---|
| Пользователь | iswangxy (UID 99909) |
|---|
| Представление | 17.07.2026 09:16 (1 месяц назад) |
|---|
| Модерация | 30.08.2026 16:44 (1 month later) |
|---|
| Статус | принято |
|---|
| Запись VulDB | 397161 [yaojingang GEOFlow до 2.1.0 GenericHttpEndpointResolver.php DistributionController.isValidHttpEndpoint endpoint_url эскалация привилегий] |
|---|
| Баллы | 20 |
|---|