Skip to content

createNextRoutesUrlGroup에서 미등록 경로에 대한 카디널리티 폭발 취약점 제보 #9

Description

@yceffort-naver

요약

createNextRoutesUrlGroup에서 routes-manifest.json에 매칭되지 않는 경로 요청 시 원본 URL이 그대로 메트릭 label에 들어가, 외부 공격자가 임의 URL을 대량 생성하여 요청하면 시계열이 무한 증가하여 OOM 또는 시스템 지연이 발생할 수 있습니다.

영향 범위

@naverpay/prometheus-corecreateNextRoutesUrlGroup을 사용하는 모든 패키지에 해당됩니다.

패키지 취약 지점
@naverpay/prometheus-core packages/core/src/next/utils.ts:72 — fallback으로 원본 URL 반환
@naverpay/prometheus-next normalizePath 미제공 시 위 함수의 반환값이 그대로 label에 사용
@naverpay/prometheus-koa nextjs 옵션 미사용 + normalizePath 미제공 시 context.path 원본 사용
@naverpay/prometheus-hono 동일하게 url.pathname 원본 사용

추가로 Koa/Hono의 api-trace 미들웨어도 normalizePath 미제공 시 동일한 문제가 있습니다.

재현 방법

# routes-manifest에 존재하지 않는 임의 경로를 대량 요청
for i in $(seq 1 10000); do
  curl -s "http://localhost:3000/random-path-$i" > /dev/null
done

# /metrics 확인 시 path label이 10,000개 생성됨
curl http://localhost:3000/metrics | grep http_request_duration_seconds | wc -l

원인

// packages/core/src/next/utils.ts:66-73
for (const {regex, page} of routes) {
    if (regex.test(withoutBasePathUrl)) {
        return page
    }
}

return withoutBasePathUrl // ← 매칭 실패 시 원본 URL 그대로 반환

isBypassPath//, \, /_next/webpack-hmr, /healthcheck, /metrics만 필터링하므로, 일반적인 형태의 임의 경로는 모두 통과합니다.

제안

1. core — createNextRoutesUrlGroup fallback 수정

// 매칭 실패 시 고정 문자열 반환
return 'UNKNOWN'

2. koa/hono — metrics 미들웨어의 최종 fallback 처리

nextjs 옵션 없이 사용할 때 context.path / url.pathname이 그대로 들어가는 부분도 동일한 처리가 필요합니다.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions