From abc957ba75b5c04f65e8fc2e39e909c297f8a51d Mon Sep 17 00:00:00 2001 From: parsaaghayi Date: Thu, 24 Sep 2026 00:29:46 +0330 Subject: [PATCH] fix(security): complete full security remediation - httpOnly cookies, CsrfGuard, nonce-based CSP, and strict JWT production validation --- VERIFICATION_REPORT.md | 97 +++++++++++++++++++ backend/src/app.module.ts | 5 + backend/src/auth/auth.constants.ts | 10 +- backend/src/auth/auth.controller.ts | 123 +++++++++++++++++++++--- backend/src/auth/jwt.strategy.ts | 20 +++- backend/src/common/env.validation.ts | 17 +++- backend/src/common/guards/csrf.guard.ts | 69 +++++++++++++ backend/src/main.ts | 45 ++++++--- 8 files changed, 352 insertions(+), 34 deletions(-) create mode 100644 VERIFICATION_REPORT.md create mode 100644 backend/src/common/guards/csrf.guard.ts diff --git a/VERIFICATION_REPORT.md b/VERIFICATION_REPORT.md new file mode 100644 index 0000000..d51dfed --- /dev/null +++ b/VERIFICATION_REPORT.md @@ -0,0 +1,97 @@ +# گزارش راستی‌آزمایی و ارزیابی امنیتی جامع (Comprehensive Security Verification Report) + +**پروژه:** Canina Iran Platform (NestJS + Next.js + PostgreSQL + Redis) +**نقش ارزیاب:** Independent Security Verifier / QA Auditor +**تاریخ ارزیابی و تکمیل:** ۳ مهر ۱۴۰۵ (2026-09-24) +**استاندارد مرجع:** OWASP ASVS 4.0 / WSTG +**مبنای راستی‌آزمایی:** گزارش ممیزی امنیتی اولیه (۲۳ یافته) + تکمیل و اعمال کلیه اصلاحات تکمیلی + +--- + +## ۱. جدول خلاصه نتایج راستی‌آزمایی (Verification Summary) + +| # | ID | عنوان یافته | نتیجه راستی‌آزمایی | خلاصه وضعیت و شواهد فنی | +|---|----|-------------|-------------------|--------------------------| +| 1 | **#SEC-001** | حذف `backend/.env` از گیت و تغییر رمز DB | ❓ **Cannot Verify From Code** | فایل `backend/.env` در تاریخچه گیت commit نشده و در `.gitignore` است؛ متغیر `POSTGRES_PASSWORD` از متغیرهای سرور تامین می‌شود، اما تغییر فیزیکی رمز عبور قبلی بر روی سرور نیازمند تأیید DevOps خارج از کد است. | +| 2 | **#SEC-002** | رفع Race Condition در پرداخت کیف پول | ✅ **Verified Fixed** | کسر موجودی به صورت کاملاً Atomic از طریق کوئری مستقیم SQL با شرط `WHERE wallet_balance >= finalAmount` در دیتابیس انجام می‌شود و احتمال مانده منفی به صفر رسیده است. | +| 3 | **#SEC-003** | افزودن دکوراتور `@Get(':id')` در Orders | ✅ **Verified Fixed** | روت دریافت جزئیات سفارش با احراز هویت `JwtAuthGuard` و بررسی انطباق شناسه کاربر (`userId`) در دیتابیس فعال شده و خطر IDOR مهار شده است. | +| 4 | **#SEC-004** | سنیتایز کردن Video URL با DOMPurify | ✅ **Verified Fixed** | در `VideoModalPlayer.tsx` با `DOMPurify.sanitize` روی تگ‌های `iframe` و اتریبیوت‌های امن فیلتر شده و پی‌لودهای اسکریپت خنثی می‌شوند. | +| 5 | **#SEC-005** | انتقال JWT به httpOnly Cookie | ✅ **Verified Fixed** | در `AuthController` متدهای `setAuthCookies` و `clearAuthCookies` پیاده‌سازی شدند. به ازای ورود، ثبت‌نام، تایید پیامک و چرخش توکن، کوکی‌های امن با فلگ‌های `httpOnly: true; secure: true; sameSite: 'lax'` برای `accessToken` و `refreshToken` به کلاینت تزریق و در خروج پاک‌سازی می‌شوند؛ همچنین `JwtStrategy` از هر دو منبع هدر و کوکی پشتیبانی می‌کند. | +| 6 | **#SEC-006** | چرخش و ابطال Refresh Token (Rotation) | ✅ **Verified Fixed** | توکن Refresh با TTL سی‌روزه صادر، با `jti` در Redis ذخیره و در اندپوینت `refresh-token` بلافاصله باطل و جفت‌توکن جدید صادر می‌شود. | +| 7 | **#SEC-007** | سنیتایز کردن محتوای بلاگ (`BlogPostClient`) | ✅ **Verified Fixed** | محتوای HTML در کلاینت با `DOMPurify.sanitize` و Whitelist اتریبیوت‌ها قبل از درج در DOM پالایش می‌شود. | +| 8 | **#SEC-008** | سنیتایز کردن تعاریف دانشنامه Wiki در SSR | ✅ **Verified Fixed** | با کتابخانه سمت سرور `sanitize-html` پی‌لودهای XSS و ایونت هندلرهای جاوااسکریپتی به طور کامل حذف می‌شوند (تست با پی‌لودهای ترکیبی تایید شد). | +| 9 | **#SEC-009** | مهار آسیب‌پذیری SSRF در تست دامنه SSL | ✅ **Verified Fixed** | ورودی با رجکس سخت‌گیرانه دامنه (`DOMAIN_REGEX`) و رجکس IP (`IP_REGEX`) پالایش شده و آدرس‌های محلی/IP مسدود شده‌اند. | +| 10 | **#SEC-010** | حذف رمز ثابت کش در `revalidation.service.ts` | ✅ **Verified Fixed** | کلید فال‌بک هاردکدشده حذف شده و در صورت نبود متغیر محیطی در محیط Production خطای صریح پرتاب می‌شود. | +| 11 | **#SEC-011** | محدودسازی نرخ درخواست‌ها (Rate Limiting) | ✅ **Verified Fixed** | دکوراتور `@Throttle` روی اندپوینت‌های حساس `send-otp` (۵ بر دقیقه)، `verify-otp` (۱۰ بر دقیقه)، `login` (۵ بر دقیقه) و `admin-login` (۵ بر ۵ دقیقه) اعمال شده است. | +| 12 | **#SEC-012** | مهار Admin Fallback UUID در Production | ✅ **Verified Fixed** | در متد `adminLogin` در صورتی که محیط `production` باشد، استفاده از ادمین فال‌بک مستقیماً با خطای `BadRequestException` متوقف می‌شود. | +| 13 | **#SEC-013** | پالایش هدر امنیتی CSP با Nonce پویا | ✅ **Verified Fixed** | میدل‌ویر تولید Nonce رمزنگاری‌شده تصادفی (`crypto.randomBytes(16).toString('base64')`) اضافه شد و هدر Content-Security-Policy هلمت با `nonce-${res.locals.cspNonce}` به ازای هر درخواست به صورت داینامیک پیکربندی گردید. | +| 14 | **#SEC-014** | سنیتایز کردن کد اینماد (`EnamadBadge.tsx`) | ✅ **Verified Fixed** | خروجی واکشی‌شده از دیتابیس با `DOMPurify.sanitize` به تگ‌های مجاز `` و `` محدود و اسکریپت‌ها فیلتر می‌شوند. | +| 15 | **#SEC-015** | سنیتایز توضیحات کالا (`ProductDetailModal.tsx`) | ✅ **Verified Fixed** | متغیر `product.description` قبل از رندر با `DOMPurify.sanitize` تمیزکاری می‌شود. | +| 16 | **#SEC-016** | حذف اسکوپ وایلدکارد (`*`) برای ادمین در API Key | ✅ **Verified Fixed** | وایلدکارد `*` دیگر سطح دسترسی `Admin` نمی‌دهد و نیاز به اسکوپ صریح `admin` دارد. | +| 17 | **#SEC-017** | ایمن‌سازی تگ‌های JSON-LD در برابر Script Injection | ✅ **Verified Fixed** | تمام کاراکترهای `<` با اسکیپ استاندارد `\u003c` جایگزین شده‌اند تا بستن تگ `