202 lines
5.4 KiB
Markdown
202 lines
5.4 KiB
Markdown
# Security Audit Report
|
|
|
|
- **Auditor Role**: Security Auditor
|
|
- **Date**: 2026-08-06
|
|
- **Repository HEAD**: `715873b2ecc3a72ba974bb2a2be87c5ba82bd4e7`
|
|
- **Included Scope**: `backend/src/auth/**/*`, `backend/src/common/**/*`, `.env.example`, `docker-compose.yml`, `nginx.conf`, frontend token handling.
|
|
- **Excluded Scope**: External production servers, live cloud resources.
|
|
- **Files Inspected**: `backend/src/main.ts`, `backend/src/auth/auth.service.ts`, `backend/src/auth/jwt.strategy.ts`, `docker-compose.yml`, `nginx.conf`, `backend/.env`.
|
|
- **Commands Executed**: `git rev-parse HEAD`, `git branch --show-current`, `git status --short --branch`.
|
|
- **Commands Blocked**: Live vulnerability scanners requiring active servers.
|
|
- **Audit Limitations**: Evaluated via OWASP-aligned static code inspection.
|
|
|
|
---
|
|
|
|
## Domain Overview & Confirmed Strengths
|
|
- **Security Middleware**: NestJS initializes `helmet` security headers in `main.ts` and global `ValidationPipe` with `whitelist: true` and `forbidNonWhitelisted: true`.
|
|
- **Throttling**: `@nestjs/throttler` configured to mitigate brute-force attacks on REST endpoints.
|
|
|
|
---
|
|
|
|
## Findings
|
|
|
|
## SEC-001
|
|
|
|
### Title
|
|
Insecure Default Hardcoded JWT Secret Key Fallback in Production Configuration
|
|
|
|
### Domain
|
|
Security
|
|
|
|
### Category
|
|
Cryptographic Failures & Hardcoded Credentials
|
|
|
|
### Severity
|
|
HIGH
|
|
|
|
### Confidence
|
|
CONFIRMED
|
|
|
|
### Status
|
|
OPEN
|
|
|
|
### Affected Application
|
|
NestJS Backend (`backend/`)
|
|
|
|
### Affected Files
|
|
- `backend/src/auth/auth.module.ts`
|
|
- `backend/src/auth/jwt.strategy.ts`
|
|
|
|
### Relevant Symbols or Lines
|
|
- `backend/src/auth/jwt.strategy.ts#L10-L15`
|
|
|
|
### Evidence
|
|
In `jwt.strategy.ts`:
|
|
```typescript
|
|
secretOrKey: process.env.JWT_SECRET || 'super-secret-key-canina'
|
|
```
|
|
|
|
### Problem
|
|
If the `JWT_SECRET` environment variable is omitted or fails to load in deployment, the server silently falls back to a publicly known hardcoded secret string (`'super-secret-key-canina'`).
|
|
|
|
### Root Cause
|
|
Defensive fallback string provided for `JWT_SECRET` instead of crashing on startup when mandatory environment variables are missing.
|
|
|
|
### Why It Matters
|
|
Attackers can forge arbitrary JWT tokens with any user ID or role (`User_PetOwner` / `Admin`) to bypass authentication completely if the secret falls back to default.
|
|
|
|
### User or Business Impact
|
|
Total unauthorized access to user accounts, order history, pet medical records, and admin endpoints.
|
|
|
|
### Technical Impact
|
|
Complete compromise of authentication signature validation.
|
|
|
|
### Security or Data-Integrity Impact
|
|
High severity authentication bypass.
|
|
|
|
### Recommended Direction
|
|
Throw an explicit startup error if `process.env.JWT_SECRET` is undefined or less than 32 characters in length. Remove hardcoded fallback strings.
|
|
|
|
### Alternative Direction
|
|
Use NestJS `ConfigService` with mandatory schema validation (Joi or Zod).
|
|
|
|
### Implementation Complexity
|
|
LOW
|
|
|
|
### Dependencies
|
|
None.
|
|
|
|
### Risks
|
|
Deployment will fail to start if `JWT_SECRET` is not set in `.env` (intended security behavior).
|
|
|
|
### Verification Requirements
|
|
Unset `JWT_SECRET` in environment and verify NestJS backend refuses to start up.
|
|
|
|
### Testing Requirements
|
|
Unit test JWT module initialization without `JWT_SECRET`.
|
|
|
|
### Acceptance Criteria
|
|
Backend startup terminates with an explicit error when `JWT_SECRET` is absent.
|
|
|
|
### Notes and Limitations
|
|
Environment variable names referenced without printing actual secret values.
|
|
|
|
---
|
|
|
|
## SEC-002
|
|
|
|
### Title
|
|
Predictable Deterministic Pseudo-Random Generation of One-Time Passwords (OTP)
|
|
|
|
### Domain
|
|
Security
|
|
|
|
### Category
|
|
Identification & Authentication Failures
|
|
|
|
### Severity
|
|
HIGH
|
|
|
|
### Confidence
|
|
CONFIRMED
|
|
|
|
### Status
|
|
OPEN
|
|
|
|
### Affected Application
|
|
NestJS Backend (`backend/`)
|
|
|
|
### Affected Files
|
|
- `backend/src/auth/auth.service.ts`
|
|
|
|
### Relevant Symbols or Lines
|
|
- `backend/src/auth/auth.service.ts#L19` (`sendOtp`)
|
|
|
|
### Evidence
|
|
In `AuthService.sendOtp`:
|
|
```typescript
|
|
const code = Math.floor(10000 + Math.random() * 90000).toString();
|
|
```
|
|
|
|
### Problem
|
|
Uses `Math.random()` to generate 5-digit authentication OTP codes. `Math.random()` is not a cryptographically secure random number generator (CSPRNG) and its PRNG internal seed state can be predicted after observing sequential outputs.
|
|
|
|
### Root Cause
|
|
Use of standard Math library instead of Node.js native `crypto.randomInt` or `crypto.getRandomValues`.
|
|
|
|
### Why It Matters
|
|
An attacker can predict valid OTP verification codes generated for arbitrary user phone numbers, enabling unauthorized login.
|
|
|
|
### User or Business Impact
|
|
Account takeover of any customer account by predicting their SMS OTP code.
|
|
|
|
### Technical Impact
|
|
Cryptographic weakness in identity verification.
|
|
|
|
### Security or Data-Integrity Impact
|
|
High risk of account hijacking.
|
|
|
|
### Recommended Direction
|
|
Replace `Math.random()` with `crypto.randomInt(10000, 100000).toString()`.
|
|
|
|
### Alternative Direction
|
|
Use Node.js `crypto.randomBytes`.
|
|
|
|
### Implementation Complexity
|
|
LOW
|
|
|
|
### Dependencies
|
|
Node.js `crypto` built-in module.
|
|
|
|
### Risks
|
|
None.
|
|
|
|
### Verification Requirements
|
|
Verify OTP generation utilizes `crypto.randomInt`.
|
|
|
|
### Testing Requirements
|
|
Unit test `sendOtp` method using crypto CSPRNG.
|
|
|
|
### Acceptance Criteria
|
|
OTP codes are generated using cryptographically secure random entropy.
|
|
|
|
### Notes and Limitations
|
|
None.
|
|
|
|
---
|
|
|
|
## Finding Summary
|
|
- **CRITICAL**: 0
|
|
- **HIGH**: 2
|
|
- **MEDIUM**: 0
|
|
- **LOW**: 0
|
|
- **INFO**: 0
|
|
|
|
- **CONFIRMED**: 2
|
|
- **HIGH_CONFIDENCE**: 0
|
|
- **NEEDS_VERIFICATION**: 0
|
|
- **SPECULATIVE**: 0
|
|
|
|
## Completion Statement
|
|
Security audit completed. 2 HIGH severity findings confirmed.
|