[P0][security] 수작업 HTTP parser에 body size limit 및 read timeout 추가 #21

Closed
opened 2026-05-02 04:34:03 +00:00 by boxqkrtm · 1 comment

문제

crates/portal-relay/src/relay/server.rsread_http_request()는 header size를 16 KiB로 제한하지만 Content-Length body는 사실상 제한 없이 Vec에 누적합니다. header/body read timeout도 보이지 않습니다.

위험

  • Content-Length로 메모리 고갈 유발 가능
  • body를 천천히 보내는 slowloris/connection exhaustion 가능
  • malformed/duplicate header, chunked transfer 등 HTTP edge case 처리가 취약
  • 이미 hyper 의존성이 있는데 서버 parsing은 직접 구현되어 유지보수 부담이 큼

제안

  • MAX_BODY_BYTES 상한 추가, 초과 시 413 또는 연결 종료
  • header/body read에 tokio::time::timeout 적용
  • malformed request는 안정적인 400/408/413 응답으로 매핑
  • 장기적으로 Hyper/Tower 기반 server + middleware로 전환

예시 방향:

const MAX_HEADER_BYTES: usize = 16 * 1024;
const MAX_BODY_BYTES: usize = 1 * 1024 * 1024;
const READ_TIMEOUT: Duration = Duration::from_secs(10);

완료 기준

  • body limit 초과 요청이 메모리를 계속 늘리지 않고 실패
  • slowloris 요청이 timeout으로 종료
  • 정상 API 요청은 기존 호환성 유지
  • body limit/timeout 회귀 테스트 추가

검토 기준: 업로드된 Rust portal-relay 코드 정적 리뷰. 리뷰 환경에서는 cargo check/test/clippy를 실행하지 못했습니다.

## 문제 `crates/portal-relay/src/relay/server.rs`의 `read_http_request()`는 header size를 16 KiB로 제한하지만 `Content-Length` body는 사실상 제한 없이 `Vec`에 누적합니다. header/body read timeout도 보이지 않습니다. ## 위험 - 큰 `Content-Length`로 메모리 고갈 유발 가능 - body를 천천히 보내는 slowloris/connection exhaustion 가능 - malformed/duplicate header, chunked transfer 등 HTTP edge case 처리가 취약 - 이미 `hyper` 의존성이 있는데 서버 parsing은 직접 구현되어 유지보수 부담이 큼 ## 제안 - `MAX_BODY_BYTES` 상한 추가, 초과 시 413 또는 연결 종료 - header/body read에 `tokio::time::timeout` 적용 - malformed request는 안정적인 400/408/413 응답으로 매핑 - 장기적으로 Hyper/Tower 기반 server + middleware로 전환 예시 방향: ```rust const MAX_HEADER_BYTES: usize = 16 * 1024; const MAX_BODY_BYTES: usize = 1 * 1024 * 1024; const READ_TIMEOUT: Duration = Duration::from_secs(10); ``` ## 완료 기준 - body limit 초과 요청이 메모리를 계속 늘리지 않고 실패 - slowloris 요청이 timeout으로 종료 - 정상 API 요청은 기존 호환성 유지 - body limit/timeout 회귀 테스트 추가 --- 검토 기준: 업로드된 Rust `portal-relay` 코드 정적 리뷰. 리뷰 환경에서는 `cargo check/test/clippy`를 실행하지 못했습니다.
Owner

수용했습니다. PR #62에서 manual HTTP parser에 read timeout, header/body size cap, Content-Length/Transfer-Encoding 방어, 400/408/413 계열 매핑 테스트를 추가했습니다. 검증: cargo test --locked, cargo clippy --locked --all-targets -- -D warnings.

수용했습니다. PR #62에서 manual HTTP parser에 read timeout, header/body size cap, Content-Length/Transfer-Encoding 방어, 400/408/413 계열 매핑 테스트를 추가했습니다. 검증: cargo test --locked, cargo clippy --locked --all-targets -- -D warnings.
gofix closed this issue 2026-05-03 18:58:35 +00:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
gofix/portal-tunnel-rs#21
No description provided.