Skip to content

fix: resolve security issues #800 #803 #804 #806#946

Merged
RUKAYAT-CODER merged 3 commits into
rinafcode:mainfrom
JudeDaniel6:fix/security-issues-800-803-804-806
Jul 6, 2026
Merged

fix: resolve security issues #800 #803 #804 #806#946
RUKAYAT-CODER merged 3 commits into
rinafcode:mainfrom
JudeDaniel6:fix/security-issues-800-803-804-806

Conversation

@JudeDaniel6

Copy link
Copy Markdown
Contributor

Summary

Resolves all four open security issues assigned to @JudeDaniel6.


#800 — EncryptionService uses SHA-256 instead of a proper KDF

Problem: Key derivation via crypto.createHash('sha256') has no work factor, making brute-force trivial.

Fix:

  • Replace with crypto.scryptSync(secret, salt, 32, { N: 16384, r: 8, p: 1 })
  • Add ENCRYPTION_SALT env var (startup fails fast if absent)
  • Document migration path in commit message
  • Unit tests verify scrypt is used (and SHA-256 is not)

#803 — AuthService logout does not blacklist the current access token

Problem: logout() only nulls the refresh token; the access token stays valid until natural expiry.

Fix:

  • Add jti claim to access token in generateTokens()
  • Update logout(userId, accessToken?) to decode the token, extract jti, and call tokenBlacklistService.addToBlacklist(jti, remainingTtlMs)
  • Update AuthController.logout to extract the Bearer token and pass it to the service
  • Tests verify immediate invalidation on logout

#804 — GDPR erasure does not cascade-delete financial records and active sessions

Problem: eraseUserData() only nulls profile fields, leaving orphaned payments/enrollments/audit logs and usable sessions.

Fix:

  • Revoke all active sessions immediately (before transaction)
  • Wrap all erasure in a TypeORM DataSource.transaction()
  • Anonymize payments, enrollment, audit_logs, and notifications tables inside the transaction
  • GdprModule updated to import TypeOrmModule (provides DataSource)
  • Tests: cascade anonymization, NotFoundException, idempotency (second call succeeds)

#806 — FraudDetectionService has hardcoded thresholds and no behavioral signals

Problem: Three hardcoded threshold checks are trivially bypassed; no velocity or geo signals.

Fix:

  • Introduce FraudSignalProvider interface for pluggable signal sources
  • IpRateSignalProvider, NewDeviceSignalProvider, LargeTransactionSignalProvider — existing logic, now configurable via ConfigService
  • VelocitySignalProvider — flags users exceeding FRAUD_MAX_PURCHASES_PER_HOUR (configurable)
  • GeoAnomalySignalProvider — flags when purchase country differs from registration country
  • All thresholds read from env vars (FRAUD_IP_RATE_THRESHOLD, FRAUD_NEW_DEVICE_AMOUNT_THRESHOLD, FRAUD_LARGE_TX_THRESHOLD, FRAUD_MAX_PURCHASES_PER_HOUR)
  • Unit tests for each provider independently + the aggregate service

Testing

All 4 target test suites pass (37 new/updated tests):

  • encryption.service.spec.ts — 6 tests ✅
  • auth.service.spec.ts — 10 tests ✅
  • gdpr.service.spec.ts — 5 tests ✅
  • fraud-detection.service.spec.ts — 16 tests ✅

Closes #800
Closes #803
Closes #804
Closes #806

…rinafcode#806

rinafcode#800 - EncryptionService: replace SHA-256 with scrypt KDF
- Use crypto.scryptSync(secret, salt, 32) for AES-256 key derivation
- Require ENCRYPTION_SALT env var at startup (fails fast if missing)
- Add ENCRYPTION_SALT to .env.example with generation instructions
- Add unit tests verifying scrypt is used (not SHA-256)

rinafcode#803 - AuthService logout: blacklist the current access token
- Add jti claim to access token payload in generateTokens()
- Update logout(userId, accessToken?) to decode and blacklist the JTI
  with TTL equal to remaining token lifetime
- Update AuthController.logout to extract Bearer token and pass it
- Add tests covering JTI blacklisting and graceful fallback

rinafcode#804 - GDPR erasure: cascade-delete financial records and active sessions
- Wrap erasure in a TypeORM DataSource transaction
- Anonymize payments, enrollments, audit_logs, notifications inside tx
- Revoke active sessions before transaction (fast path)
- Update GdprModule to import TypeOrmModule (provides DataSource)
- Add tests: cascade anonymization, NotFoundException, idempotency

rinafcode#806 - FraudDetectionService: configurable thresholds + behavioral signals
- Introduce FraudSignalProvider interface for pluggable signal sources
- IpRateSignalProvider, NewDeviceSignalProvider, LargeTransactionSignalProvider
- VelocitySignalProvider: flag users exceeding N purchases/hour
- GeoAnomalySignalProvider: flag purchase country != registration country
- All thresholds configurable via ConfigService env vars (FRAUD_*)
- Unit tests for each provider independently + aggregate service

Closes rinafcode#800, Closes rinafcode#803, Closes rinafcode#804, Closes rinafcode#806
@RUKAYAT-CODER

Copy link
Copy Markdown
Contributor

kindly resolve conflict

@RUKAYAT-CODER

Copy link
Copy Markdown
Contributor

Great job so far

There are just two blockers — the workflow is failing and merge conflict. Could you take a look and fix it so all checks pass?

Happy to review again once that’s done.

@drips-wave

drips-wave Bot commented Jul 3, 2026

Copy link
Copy Markdown

@JudeDaniel6 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@JudeDaniel6

Copy link
Copy Markdown
Contributor Author

Thanks Ma i have resolve the conflict

- Merge duplicate @nestjs/typeorm import in gdpr.service.ts (no-duplicate-imports)
- Apply prettier formatting in auth.service.spec.ts
- Apply prettier formatting in fraud-detection.service.ts

No behavior changes; formatting and import de-duplication only.
@RUKAYAT-CODER

Copy link
Copy Markdown
Contributor

Thank you for contributing to the project

@RUKAYAT-CODER RUKAYAT-CODER merged commit ce6bf71 into rinafcode:main Jul 6, 2026
1 check passed
@JudeDaniel6

JudeDaniel6 commented Jul 6, 2026 via email

Copy link
Copy Markdown
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants