-
hanyul released this
2026-10-03 01:39:23 +09:00 4.6.0 대비 변경사항
보안 전수조사(브라우저·backend·crawler·edge)에서 찾은 1순위 항목을 고친 릴리스입니다. XSS·권한 누락·SQL 주입은 발견되지 않았고, 아래는 방어 강화와 DoS·우회 경로 차단입니다.
backend
- 요청 1건으로 backend가 멈추던 문제 수정(High) — 의심 입력 검사 정규식을 선형 패턴으로 바꾸고 검사 길이를 제한했습니다. 요청 한도 검사가 그보다 먼저 실행됩니다.
- 다른 사이트에서 보내는 요청 차단(CSRF) — 데이터를 바꾸는 요청(POST·PUT·PATCH·DELETE)은 사이트 자체 출처일 때만 받습니다(
403 REQUEST_ORIGIN_REJECTED). form 인코딩 본문 parser를 제거했습니다. - IPv6 요청 한도 우회 차단 — 요청 한도·조회 예산·미디어 예산·가입 시도는 IPv6 주소를 /64 단위로 셉니다.
- 관리자 보안 키 — 틀린 시도를 IP당 1시간 10회로 제한하고(일반 가입 시도에도 함께 적용), 길이를 드러내지 않게 비교합니다. 운영에서
JWT_SECRET·COOKIE_SECRET·ADMIN_SECURITY_KEY가 예제 값(CHANGE_ME…)이거나 JWT와 쿠키 비밀값이 같으면 시작하지 않고, 32자 미만은 경고를 남깁니다. - Web Push — 알려진 Push 서비스 주소(HTTPS)만 등록하고 사용자당 구독은 10개까지입니다. 모든 기기 로그아웃은 Push 구독도 지웁니다.
- DB 연결 고갈 방지 — 개인 route가 클래스의 조회 비용을 낮추지 않게 하고, 계정 내보내기·guest 병합에 비용과 사용자별 단일 실행을 적용했습니다.
X-Powered-By제거, 경로 판정 대소문자·경계 정확화.
crawler
- Hitomi
gg.js를 실행하지 않음(High) — 외부 스크립트를 실행하는 대신 형식 parser로 읽습니다. 실제 응답으로 이전 방식과 결과가 같은 것을 확인했습니다. - 내부 API 토큰 — 새 설정
CRAWLER_INTERNAL_TOKEN이 있으면 backend→crawler 호출을 공유 토큰으로 확인합니다. 비어 있으면 검사하지 않고 시작 경고만 남깁니다. crawler CORS를 제거했습니다. - Hitomi redirect는 Hitomi HTTPS 주소만 따라가고(최대 3회), E-Hentai 보호 응답 판별을 선형 검사로 바꿨습니다.
nginx·web
- CSP 강제 정책 승격 —
unsafe-eval, 임의 외부 이미지·WebSocket 출처를 막고object-src 'none'·base-uri·form-action·frame-ancestors를 추가했습니다(Report-Only 제거). /api/요청 본문 상한 2 MiB, 이미지 검색만 11 MiB. 정적 파일은 GET·HEAD만, upstreamX-Accel-*무시,X-Powered-By숨김.- web API 경로 인코딩과 lint 규칙, 홈
?gallery=UUID 검사, 알림 클릭은 같은 사이트 주소로만 이동, 로그아웃 때 Push 구독·조회 cache·홈 복귀 상태 정리. - 의존성 — Next.js 16.3.8, Nest 11.2.7(multer 2.4.0), axios 1.20.0. 운영 의존성
npm audit0건.
운영
deploy-production.sh는 backend 이미지가 바뀌면 migration 전에 crawler를 멈춰 deadlock을 막습니다.compose.yml: backend·crawler에CRAWLER_INTERNAL_TOKEN(기본 빈 값),sql/init-db.sql읽기 전용 mount.
DB migration은 없습니다. 새 설정은 선택이고 기존 데이터·사용 방식이 유지되므로 minor 버전입니다. 사이트 밖 출처에서 관리 작업을 하던 경우에는 그 출처를
CORS_ORIGIN에 추가해야 합니다.이미지 게시 범위
빌드 입력 지문을 4.6.0 시점
latest와 대조해 nginx·backend·crawler·web을 새로 빌드하고4.7.0·latest를 게시했습니다(publish-images.ps1 -ChangedOnly). nginx는 보안 헤더·CSP·본문 상한 설정, backend·crawler·web은 앱 코드·공유 패키지·lockfile이 바뀌었습니다. byedpi는 입력이 같아 기존latestdigest를 유지하며4.7.0태그를 추가하지 않았습니다.NAS 업데이트
compose.yml과 배포 스크립트가 바뀌었으므로 먼저 받습니다.cd /volume1/2ex-hentai curl -fsSL https://git.2ex.dev/hanyul/2Ex-Hentai/raw/tag/4.7.0/compose.yml -o compose.yml curl -fsSL https://git.2ex.dev/hanyul/2Ex-Hentai/raw/tag/4.7.0/ops/deploy-production.sh -o ops/deploy-production.sh grep -n "CRAWLER_INTERNAL_TOKEN" compose.yml docker login git.2ex.dev sh ops/deploy-production.sh docker compose --env-file .env.production ps- 권장: 배포 전
.env.production에CRAWLER_INTERNAL_TOKEN=<openssl rand -hex 32 결과>를 넣습니다. 없어도 동작하지만 crawler가 경고를 남기고 토큰 검사를 하지 않습니다. - 권장:
ADMIN_SECURITY_KEY가 32자 미만이면 무작위 긴 값으로 바꿉니다(이미 등록된 passkey는 계속 사용). - 배포 뒤 운영 사이트에서 브라우저 개발자도구 console에 CSP 오류가 없는지 확인합니다. Cloudflare가 Web Analytics·Rocket Loader 등으로 스크립트를 주입하면 막힐 수 있습니다.
- 이 릴리스는 변경 서비스에만 버전 태그가 있으므로
IMAGE_TAG로 전체 서비스를 일괄 지정할 수 없습니다.
검증
- 게시 소스 main에서
run-unit.ps1 -Workspace all(web 860 포함),run-crawler-recovery.ps1(내부 토큰 거부 포함),run-operations.ps1 -DeploymentOnly,run-integration.ps1(브라우저 회귀 포함) 통과. worker 단계에서run-hitomi-network(실제 Hitomi, gg.js parser) 통과. - 격리 nginx·web Playwright로 주요 화면·Turnstile 로그인·viewer·이미지 검색에서 강제 CSP 위반 0건을 확인했습니다.
- 개발 서버를 이 소스로 재빌드해 healthy, 외부 출처 POST 403, 강제 CSP 헤더를 확인했습니다. 실제 Push 해제·PWA 설치·운영 Cloudflare 스크립트 주입 여부와 NAS 배포는 실행하지 않았습니다.
게시 확인
- 릴리스 소스:
969a854a(주석 태그4.7.0). - nginx
4.7.0·latest:sha256:8abb8e6c23405656d22150cc1cb632d93042efd9191a0877d8d206e2cb8b41da - backend
4.7.0·latest:sha256:bb61f0134cafc8a8b39c05fb81fe79f4b6a396e6d72f01a382390db96dfaa35f - crawler
4.7.0·latest:sha256:f80c46f91309b07ab29f16c4c9497dce8f881880d5e1ecc82e415aa9818fae45 - web
4.7.0·latest:sha256:a76b2dee8f88f96b3523ea83dcd5d1c7730ff55a87ecb6178e524d653d63fbbd - 네 이미지 모두 OCI version
4.7.0·revision969a854a확인. byedpi(15ac60ab)는 기존latest유지·4.7.0태그 부재 확인.
Downloads 2
-
Source code (zip)
0
2026-10-03 01:39:23 +09:00 -
Source code (tar.gz)
0
2026-10-03 01:39:23 +09:00