fix(#279): Validate orchestrator URL configuration (SSRF risk)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Implemented comprehensive URL validation to prevent SSRF attacks: - Created URL validator utility with protocol whitelist (http/https only) - Blocked access to private IP ranges (10.x, 192.168.x, 172.16-31.x) - Blocked loopback addresses (127.x, localhost, 0.0.0.0) - Blocked link-local addresses (169.254.x) - Blocked IPv6 localhost (::1, ::) - Allow localhost in development/test environments only - Added structured audit logging for invalid URL attempts - Comprehensive test coverage (37 tests for URL validator) Security Impact: - Prevents attackers from redirecting agent spawn requests to internal services - Blocks data exfiltration via malicious orchestrator URL - All agent operations now validated against SSRF Files changed: - apps/api/src/federation/utils/url-validator.ts (new) - apps/api/src/federation/utils/url-validator.spec.ts (new) - apps/api/src/federation/federation-agent.service.ts (validation integration) - apps/api/src/federation/federation-agent.service.spec.ts (test updates) - apps/api/src/federation/audit.service.ts (audit logging) - apps/api/src/federation/federation.module.ts (service exports) Fixes #279 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,9 @@ import { ConfigService } from "@nestjs/config";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { PrismaService } from "../prisma/prisma.service";
|
||||
import { CommandService } from "./command.service";
|
||||
import { FederationAuditService } from "./audit.service";
|
||||
import { FederationConnectionStatus } from "@prisma/client";
|
||||
import { validateUrl } from "./utils/url-validator";
|
||||
import type { CommandMessageDetails } from "./types/message.types";
|
||||
import type {
|
||||
SpawnAgentCommandPayload,
|
||||
@@ -46,10 +48,24 @@ export class FederationAgentService {
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly commandService: CommandService,
|
||||
private readonly httpService: HttpService,
|
||||
private readonly configService: ConfigService
|
||||
private readonly configService: ConfigService,
|
||||
private readonly auditService: FederationAuditService
|
||||
) {
|
||||
this.orchestratorUrl =
|
||||
this.configService.get<string>("orchestrator.url") ?? "http://localhost:3001";
|
||||
const url = this.configService.get<string>("orchestrator.url") ?? "";
|
||||
const nodeEnv = this.configService.get<string>("NODE_ENV") ?? "production";
|
||||
const isDevelopment = nodeEnv === "development" || nodeEnv === "test";
|
||||
|
||||
// Validate orchestrator URL (SSRF prevention)
|
||||
const validationResult = validateUrl(url, isDevelopment);
|
||||
if (!validationResult.valid) {
|
||||
const errorMessage = validationResult.error ?? "Unknown validation error";
|
||||
this.logger.error(`Invalid orchestrator URL: ${errorMessage}`);
|
||||
// Log security event
|
||||
this.auditService.logInvalidOrchestratorUrl(url, errorMessage);
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
this.orchestratorUrl = url;
|
||||
this.logger.log(
|
||||
`FederationAgentService initialized with orchestrator URL: ${this.orchestratorUrl}`
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user