From 4b6eecd679b6210a67142d00f3bfd4d347046ddf Mon Sep 17 00:00:00 2001 From: ttipo Date: Tue, 3 Nov 2026 22:31:53 +0900 Subject: [PATCH] =?UTF-8?q?docs(rules):=20=EC=9C=A0=EC=98=88=20=EC=B7=A8?= =?UTF-8?q?=EC=95=BD=EC=A0=90=EA=B3=BC=20=EC=9E=A0=EA=B8=88=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20npm=20=EB=B2=84=EC=A0=84=20=EC=A3=BC=EC=9D=98=20?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - security.md: 남은 36건(glob·minimatch 보통, deepmerge·jest 낮음)의 도달 가능성·유예 이유·다시 볼 조건, multer ^2.5.0 · swagger 아래 js-yaml override 근거 - nestjs 스킬: 컨테이너 npm 11.20 이 지운 선택 peer 항목 때문에 CI(npm 10)의 npm ci 가 깨질 수 있다 — npx npm@10 ci --dry-run 으로 확인하는 절차 Co-Authored-By: Claude Opus 5.5 --- .claude/rules/security.md | 16 +++++++++++++--- .claude/skills/nestjs/SKILL.md | 6 +++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.claude/rules/security.md b/.claude/rules/security.md index 60b5646..a035a36 100644 --- a/.claude/rules/security.md +++ b/.claude/rules/security.md @@ -85,7 +85,12 @@ 2. **수정이 다른 것을 깨뜨리는가** — 생태계 버전이 어긋나면 더 큰 위험 3. 미룬다면 **언제 다시 볼지** 조건을 적어둔다 -> **현재 유예 중인 항목**: 없음 (`npm audit` 0건) +> **현재 유예 중인 항목** (2026-11-03 backend `npm audit` 36건: 보통 33 · 낮음 3, 높음·치명 0) +> +> | 항목 | 경로 | 도달 가능성 | 미루는 이유 | 다시 볼 조건 | +> | --- | --- | --- | --- | --- | +> | `glob`·`minimatch` (보통) | typeorm(엔티티·마이그레이션 경로 탐색), jest·eslint·@nestjs/cli | 패턴이 코드에 고정된 값이라 외부 입력이 닿지 않는다. 나머지는 개발 도구 | 수정판이 typeorm 1.x 등 메이저 업그레이드뿐 | typeorm 1.x 전환 · jest/eslint 메이저 업그레이드 때 | +> | `deepmerge` · `jest` (낮음) | @nestjs/cli, jest | 개발 도구 전용(운영 이미지에 없음) | 수정판이 메이저 업그레이드뿐 | @nestjs/cli 12 · jest 다음 메이저 때 | ### 전이 의존성 취약점은 overrides 로 끊는다 @@ -95,18 +100,23 @@ ```jsonc // backend/package.json "overrides": { - "multer": "^2.4.0" + "multer": "^2.5.0", + "@nestjs/swagger": { "js-yaml": "^5.4.3" } // 특정 패키지 아래에서만 올릴 때 } ``` > 실제 사례: `@nestjs/platform-express@11` 은 `multer` 를 `2.2.0` 으로 고정하는데 이 버전에 DoS 취약점(high)이 있었다. > `@nestjs/platform-express@12` 는 `multer@2.4.0` 을 쓰지만, v12 로 올리면 나머지 Nest 생태계(v11)와 호환이 깨진다. > **v12 가 하는 일이 결국 multer 를 올리는 것**이므로, override 로 같은 결과를 생태계 업그레이드 없이 얻었다. +> +> 2026-11-03 갱신: `multer@2.4.0` 에도 DoS 취약점(high)이 나와 `^2.5.0` 으로 올렸다(platform-express 12.3.2 가 2.5.0 을 선언). +> `@nestjs/swagger@11.4.7` 은 `js-yaml@5.3.0`(보통)을 고정한다. swagger 12.1.0 이 5.5.0 을 선언하므로 swagger 아래에서만 올렸다 +> — 최상위로 올리면 `js-yaml@4` 를 쓰는 eslint 까지 메이저가 바뀐다. 규칙: - override 는 **상위 패키지가 그 버전을 실제로 쓰는지 근거를 확인**하고 적용한다 - (위 사례는 platform-express v12 가 2.4.0 을 선언하는 것이 근거). + (위 사례는 platform-express v12 가 2.5.0 을, swagger 12.1.0 이 js-yaml 5.5.0 을 선언하는 것이 근거). - 같은 메이저 안에서만 올린다. 메이저를 건너뛰면 API 가 달라져 상위 패키지가 깨질 수 있다. - 적용 후 **lint·테스트·빌드·런타임 기동까지 확인**한다. override 는 npm 이 검증해 주지 않는다. - 상위 패키지를 정식으로 올릴 때 **override 를 제거**한다. 남겨두면 나중에 버전이 거꾸로 고정된다. diff --git a/.claude/skills/nestjs/SKILL.md b/.claude/skills/nestjs/SKILL.md index 82200e2..bc97af5 100644 --- a/.claude/skills/nestjs/SKILL.md +++ b/.claude/skills/nestjs/SKILL.md @@ -298,7 +298,11 @@ dc exec backend npm uninstall <패키지> - 호스트에서 실행해버렸다면 `git checkout backend/package-lock.json` 으로 되돌린 뒤 위 방법으로 다시 한다. - 커밋 전 `docker compose ... build backend` 로 `npm ci` 가 통과하는지 확인한다. CI 도 같은 검사를 한다. - 전이 의존성의 취약점이 `npm audit fix` 로 안 풀리면 `package.json` 의 `overrides` 를 쓴다 ([[security]]). - 현재 `multer: ^2.4.0` 이 걸려 있다 — `@nestjs/platform-express` 를 v12 로 올릴 때 제거한다. + 현재 `multer: ^2.5.0` 과 `@nestjs/swagger` 아래 `js-yaml: ^5.4.3` 이 걸려 있다 — 각각 `@nestjs/platform-express`·`@nestjs/swagger` 를 v12 로 올릴 때 제거한다. +- **컨테이너 npm(11.20) 이 만든 잠금 파일이 CI 의 npm 10 에서 깨질 수 있다.** 새 npm 은 선택 peer 의존성(chokidar 등)· + 다른 플랫폼용 선택 의존성 항목을 잠금 파일에서 지우는데, npm 10 의 `npm ci` 는 그 항목이 없으면 실패한다(2026-11-03). + 의존성을 바꾼 뒤 호스트에서 `npx -y npm@10 ci --dry-run` 으로 확인하고, 실패하면 지워진 항목을 이전 잠금 파일에서 되살린다 + (또는 컨테이너에서 `npx -y npm@11.6.2 install --package-lock-only` 로 다시 계산). ---