| 标题 | 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 09時16分 (1 月前) |
|---|
| 管理 | 2026-08-30 16時44分 (1 month later) |
|---|
| 状态 | 已接受 |
|---|
| VulDB条目 | 397161 [yaojingang GEOFlow 直到 2.1.0 GenericHttpEndpointResolver.php DistributionController.isValidHttpEndpoint endpoint_url 权限提升] |
|---|
| 积分 | 20 |
|---|