Skip to content

[P1][Security][Workflow] Generic HTTP SSRF 차단 및 Worker egress 강제 #471

Description

@HyungminYoon1

배경

최신 origin/dev @ 90394932 기준 Generic HTTP provider는 URL 형식만 확인한 뒤 Workflow Worker에서 HTTP client를 직접 생성했다. 이 구조에서는 loopback, private network, link-local, cloud metadata, 혼합 DNS 응답과 DNS rebinding 목적지로 연결할 수 있었고, Worker 배포 계층의 보조 egress 방어도 없었다.

목표

Generic HTTP의 네트워크 진입점을 application outbound port로 단일화하고, URL·DNS·실제 dial을 하나의 정책 경계로 묶는다. Worker NetworkPolicy를 두 번째 방어선으로 적용해 애플리케이션 검증만으로 구성된 단일 방어선을 피한다.

확정 계약

  • Generic HTTP node/provider는 socket 또는 HTTP client를 직접 생성하지 않고 OutboundHttpPort만 사용한다.
  • 공통 OutboundEgressGuard가 모든 DNS 결과를 검사하고, 검증된 IP로 직접 dial한 뒤 실제 peer 일치를 확인한다.
  • loopback, private, link-local, multicast, reserved, unspecified, cloud metadata와 IPv6 우회 범위를 fail-closed한다.
  • follow_redirects=false로 3xx를 기존 응답 그대로 반환하며 redirect 목적지로 추가 연결하지 않는다.
  • trust_env=false로 환경 proxy 우회를 막고 TLS 인증은 원래 hostname 기준으로 유지한다.
  • method, port, timeout, header, request body와 response body 상한을 적용한다.
  • 정책 거부는 요청 전 영구 실패, 전송 후 read/response 실패는 결과 불확실로 분류해 외부 효과 재시도 계약을 보존한다.
  • Helm과 활성 EKS Worker manifest에 private·metadata 목적지를 제외하는 egress NetworkPolicy를 기본 적용한다.
  • 차단 오류와 trace에는 safe reason code만 사용하고 raw URL query, header, body, credential과 resolved IP를 남기지 않는다.

구현 범위

  • Workflow Engine application outbound HTTP port와 guarded HTTPX/httpcore adapter
  • Generic HTTP provider 및 node composition 변경
  • Shared egress address/header 검증 보강
  • Helm 및 활성 EKS Worker NetworkPolicy
  • ADR-0050과 Workflow 요구사항/API/component/test 계약
  • SSRF, DNS TOCTOU, peer mismatch, 크기 제한, 외부 효과 phase와 배포 정책 회귀 테스트

완료 조건

  • localhost, RFC1918, link-local, metadata, reserved, IPv6 local, 혼합 DNS와 peer mismatch가 요청 전에 차단된다.
  • 검증된 IP로만 dial하고 hostname을 다시 해석하지 않는다.
  • private redirect로 두 번째 요청이 발생하지 않는다.
  • 정상 public 요청의 canonical request, provider response shape와 idempotency/retry 계약이 유지된다.
  • Worker Helm과 활성 EKS manifest가 필요한 내부 service port와 승인된 public port만 허용하고 private·metadata 범위를 제외한다.
  • 관련 테스트, Ruff, lock/diff 검사와 Helm default/production lint/render가 통과한다.

비범위 및 운영 한계

  • 조직별 목적지 allowlist UI
  • 모든 Connector, Knowledge, LLM outbound 경로의 일괄 이전
  • 전용 egress proxy 또는 FQDN-aware CNI 도입
  • private SaaS endpoint 예외 정책
  • Generic HTTP public API·DB schema·정상 응답 shape 변경

표준 Kubernetes NetworkPolicy만으로 public 허용 port의 모든 direct dial을 proxy-only로 강제할 수는 없다. 배포 cluster가 NetworkPolicy를 집행하는 CNI를 사용하는지, 동일 Worker selector에 allow-all 정책이 없는지는 별도 운영 점검이 필요하다.

구현 PR

Metadata

Metadata

Assignees

Type

No type

Fields

Priority

None yet

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions