This document describes how to manage security vulnerabilities in the Material Management System, including how to detect them, how to respond, and how to keep dependencies up to date.
| Version | Supported |
|---|---|
| Latest (main) | ✅ |
| Previous releases | ❌ (patch and upgrade to latest) |
Only the latest version on the main branch receives security patches.
If you discover a security vulnerability in this project, do not open a public GitHub issue.
Please report it privately by emailing the maintainers or using GitHub's private vulnerability reporting.
Include in your report:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if known)
You will receive a response within 72 hours. If the vulnerability is confirmed, a patch will be released as soon as possible.
This project uses npm audit to scan for known vulnerabilities in dependencies.
# From the project root
npm audit
# Backend only
cd backend && npm audit
# Frontend only
cd frontend && npm auditSeverity levels returned by npm audit:
| Level | Action Required |
|---|---|
| critical | Fix immediately — block PRs |
| high | Fix within 1–2 days |
| moderate | Fix within 1 week |
| low | Address in next scheduled maintenance |
The repository has Dependabot enabled. It automatically:
- Scans dependencies on every push to main
- Opens Dependabot alerts in the Security tab for known CVEs
- Can open automated PRs for patch/minor version upgrades if Dependabot security updates are enabled
To review alerts: GitHub → Security → Dependabot alerts
npm audit fixThis upgrades transitive dependencies to the nearest non-vulnerable version within the existing version range. It will not break the API.
npm audit fix --force
⚠️ Use with caution. --force allows major version bumps which may contain breaking changes. Always run the test suite after.
npm install <package>@<safe-version>Example: pm install minimatch@9.0.5
cd backend && npm test # 109+ Jest tests must pass
cd frontend && npm test # Vitest tests must pass
npm run lint # ESLint must pass with 0 errorsIf a package is listed in package.json but is never imported in the codebase, remove it entirely:
grep -r "require('multer')" backend/src # Check if used
npm uninstall multer # Remove if not used# Check for outdated packages
npm outdated
# Update all packages within semver range
npm update
# After updating, always verify
npm audit
npm testnpx npm-check-updates -u # Updates package.json to latest versions
npm install # Installs new versions
npm test # Verify nothing brokegit add package.json package-lock.json
git commit -m "chore(deps): update dependencies"Critical: Always commit package-lock.json alongside package.json. CI uses pm ci which reads the lock file exactly — if the lock file is missing or out of sync, CI will fail to install packages.
| Date | Package | CVE / Issue | Resolution |
|---|---|---|---|
| 2026-03-10 | xlsx@0.18.5 | Prototype Pollution | Replaced with exceljs@4.4.0 |
| 2026-03-10 | multer@1.4.5-lts.2 | DoS (CVE-2024-45296 + 3 others) | Removed — package was unused |
| 2026-03-10 | minimatch@3.1.3 | ReDoS (CVE-2022-3517) | Auto-fixed via |
| pm audit fix | |||
| 2026-03-10 | eslint@8.x | High severity (transitive) | Upgraded to eslint@9.x |
- JWT tokens are signed with JWT_SECRET — store this in .env, never commit it
- Rate limiting is applied to /api/auth/* endpoints (express-rate-limit)
- Role-based access control enforced on all sensitive routes (�dmin, manager, staff)
- Passwords are hashed with �cryptjs (12 salt rounds)
- All request bodies are validated with express-validator before reaching controllers
- SQL injection is prevented by Prisma's parameterized queries — never use raw SQL with user input
- helmet is applied globally in �pp.js — sets CSP, HSTS, X-Frame-Options, etc.
- Never commit .env files — they are in .gitignore
- Rotate JWT_SECRET immediately if it is ever exposed
- Use strong, randomly generated secrets: ode -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
- All create/update/delete operations are recorded in the AuditLog table via �uditLog() utility
- Review audit logs to detect unauthorized access patterns
The project enforces comprehensive security gates across three dedicated workflows:
Runs on: Every PR to main + every push to main/feature/fix branches
- Linting: Prettier + ESLint (frontend & backend) — catches code style and security anti-patterns
- Type Checking: TypeScript strict mode + Prisma schema validation — eliminates entire classes of bugs
- Unit Tests: Backend Jest (23+ tests) + Frontend Vitest (12+ tests) — ensures functionality before merge
- Build Validation: Full frontend build with TypeScript compilation — catches build-time errors
- Concurrency: Cancels previous runs on feature branches (fast feedback), but never cancels on main (ensures all security checks complete)
Runs on: Every PR + every push to main + weekly scheduled scan
- Detects: API keys, tokens, passwords, database credentials, SSH keys
- Scope: Scans entire git history (including commits before this project started)
- Action: Fails the build if any secrets are detected
- Metadata: Posts detailed findings to PR comments with remediation steps
Runs on: Every PR + every push to main + weekly scheduled scan
- Detects: Known CVEs in npm dependencies (frontend + backend node_modules)
- Severity Threshold: Fails the build on CRITICAL or HIGH severity vulnerabilities
- Scanners: Runs both vulnerability + built-in secret scanners
- Reports: Uploads SARIF results to GitHub Security tab for tracking
- Dependencies Scanned: All transitive dependencies in package-lock.json
To enforce all CI/CD security standards, enable branch protection on main:
- Go to Settings → Branches → Branch protection rules
- Create rule for branch name pattern:
main - Enable:
- ✅ Require a pull request before merging (dismiss stale PR approvals on push)
- ✅ Require approvals (minimum 1 reviewer)
- ✅ Require status checks to pass before merging:
CI / LintCI / Type CheckCI / Backend TestsCI / Frontend TestsCI / BuildGitleaksTrivy
- ✅ Require branches to be up to date before merging
- ✅ Include administrators (admins must also pass checks)
- ✅ Restrict who can push to matching branches (optional: limit to admins)
On every PR:
- CI workflow: ~2-5 minutes (lint + typecheck + tests + build)
- Gitleaks scan: ~30 seconds
- Trivy scan: ~1-2 minutes
- Total: ~4-8 minutes before merge is permitted
On main branch push (after squash/merge):
- All checks must complete (no cancellation)
- Ensures production code quality gate is never bypassed