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

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions