Skip to content

Feat/bound unpaginated audit queries - #1118

Open
ajulaybeeb wants to merge 2 commits into
rinafcode:mainfrom
ajulaybeeb:feat/bound-unpaginated-audit-queries
Open

Feat/bound unpaginated audit queries#1118
ajulaybeeb wants to merge 2 commits into
rinafcode:mainfrom
ajulaybeeb:feat/bound-unpaginated-audit-queries

Conversation

@ajulaybeeb

Copy link
Copy Markdown

Fixes #1019

**: Bounds unpaginated repository reads in AuditQueryService to prevent OOM / memory exhaustion vulnerabilities during compliance and incident investigations. Audit logs are append-only and the fastest-growing table in the system; this PR guarantees that all queries are safely bounded by pagination and temporal limits.

Security Mitigations & Enhancements

  1. Mandatory Pagination Ceilings:
    • Modified all six find* methods (findAll, findByUser, findByAction, findByEntity, findByIpAddress, findByDateRange) to enforce a hard server-side pagination ceiling (take: Math.min(limit, 1000)).
  2. Default Bounded Time Windows:
    • All query paths now inject a bounded default 30-day time window (startDate/endDate) if none is explicitly provided, neutralizing unbound historical full-table scans.
  3. Cursor/Streaming Bulk Exports:
    • Introduced a new streamAll(filters) method utilizing TypeORM's stream() capabilities for safe bulk exporting, allowing unbounded cursor traversal without materializing result sets into memory.
  4. Index Optimizations:
    • Updated the composite index on ['entityType', 'entityId'] to include timestamp, allowing queries filtering by entity targets to utilize the index for their ORDER BY timestamp DESC clauses.
  5. Unit Tests:
    • Added a new unit test suite (audit-query.service.spec.ts) strictly asserting that pagination parameters are clamped to the 1000 hard limit ceiling and that the 30-day bounds are applied automatically.

AbuJulaybeeb and others added 2 commits July 28, 2026 17:52
…uard

- Refactored the file size guard in main.ts to enforce stream-level byte counting.
- Missing or unparseable Content-Length requests without chunked encoding are now rejected with 411 Length Required.
- Added a counting stream guard that destroys the request if actual payload bytes exceed the limit.
- Updated multer config in upload-validation.util.ts to dynamically read FILE_UPLOAD_MAX_BYTES.
- Added e2e tests for chunked upload bypassing and understated Content-Length scenarios.
Closes rinafcode#989
- Added explicit skip/take pagination with a hard server-side max of 1000 items to all six AuditQueryService find methods.
- Enforced a default 30-day time window for all temporal queries to protect against massive history scans.
- Added a streamAll cursor-based method for bulk exports to prevent memory exhaustion.
- Optimized the entity index for entityType/entityId to include timestamp.
- Added tests asserting pagination ceiling clamp and the default time window.
Closes rinafcode#1019
@drips-wave

drips-wave Bot commented Jul 28, 2026

Copy link
Copy Markdown

@ajulaybeeb 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

@RUKAYAT-CODER

Copy link
Copy Markdown
Contributor

Well done on the job done so far!
kindly fix workflow to pass

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bound the unpaginated repository reads in AuditQueryService

3 participants