# Strapi Security Audit Report (nrel-cms)

**Audit date:** March 2025  
**Strapi version:** 5.39.0 (upgraded from 5.33.1)

---

## Fixes applied

1. **Strapi upgraded to 5.39.0** – Addresses critical `@casl/ability` prototype pollution (CVE-2026-1774) and related Strapi admin vulnerabilities.
2. **`npm audit fix`** – Applied safe dependency updates.
3. **`.env.example`** – All secret-like values replaced with placeholders.
4. **CORS headers** – Restricted from `"*"` to explicit list: `Content-Type`, `Authorization`, `Origin`, `Accept`, `X-Requested-With`.
5. **Body/file limits** – `maxFileSize` reduced from 2GB to 500MB; `formLimit` from 1GB to 100MB to reduce DoS risk.
6. **Database config** – In production, app now throws if Postgres is used without `DATABASE_PASSWORD` or `DATABASE_URL` set (no silent default).

---

## Vulnerability reduction applied

- **npm overrides** in `package.json`: `ajv` ≥8.18.0 (ReDoS fix), `tar` ≥7.5.11 (path traversal fix), `undici` ≥6.24.0 (high-severity fixes).
- **xlsx removed**: Replaced with **exceljs** (no known audit issues). Export scripts `scripts/export-all-properties-excel.js` and `scripts/export-properties-by-type.js` now use ExcelJS.

**Before:** 35 vulnerabilities (6 low, 13 moderate, 16 high).  
**After:** 28 vulnerabilities (15 low, 13 moderate, **0 high**). Overrides for `undici` ≥6.24.0 removed the last high-severity issues. Remaining items are low/moderate and in Strapi transitive deps; fixing would require `npm audit fix --force` (Strapi 4.x downgrade).

## Remaining npm audit items (transitive / upstream)

The remaining issues **cannot be fixed without breaking changes** (e.g. `npm audit fix --force` would downgrade Strapi to 4.x). They live in Strapi’s dependencies:

| Type | Examples |
|------|----------|
| **Strapi transitive** | elliptic (grant/jwk-to-pem), esbuild, file-type, markdown-it, tmp (inquirer), vite |

**What to do:** Run `npx @strapi/upgrade latest` and `npm audit fix` periodically. Do not run `npm audit fix --force` (it would downgrade Strapi).

---

## Already in good shape

- **Strapi CVEs (CVE-2024-56143, CVE-2025-53092):** Fixed in 5.5.2 and 5.20.0; 5.39.0 is above both.
- **CORS:** Explicit origin allowlist (no dynamic Origin reflection).
- **Admin secrets:** All read from env (no hardcoding).
- **Production:** Error stack hiding, `emitErrors: false`, CSP, and production-only flags set.
- **`.env`:** In `.gitignore`; only `.env.example` is tracked with placeholders.

---

## Checklist

- [x] Upgrade Strapi to 5.39.0+ and run `npm audit fix`
- [x] Replace all secret-like values in `.env.example` with placeholders
- [x] Restrict CORS headers and lower `maxFileSize` / form limits
- [x] Require production database password when not using `DATABASE_URL`
- [ ] Confirm production uses strong, unique values for all secrets (never from `.env.example`)
- [ ] (Optional) Replace `xlsx` with a safer library if processing untrusted Excel files
- [ ] Re-run `npm audit` and `npx @strapi/upgrade latest` periodically
