| 제목 | 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) |
|---|
| 제출 | 2026. 07. 17. AM 09:16 (1 월 ago) |
|---|
| 모더레이션 | 2026. 08. 30. PM 04:44 (1 month later) |
|---|
| 상태 | 수락 |
|---|
| VulDB 항목 | 397161 [yaojingang GEOFlow 까지 2.1.0 GenericHttpEndpointResolver.php DistributionController.isValidHttpEndpoint endpoint_url 권한 상승] |
|---|
| 포인트들 | 20 |
|---|