Skip to content

Conversation

@github-actions
Copy link
Contributor

This is an automated pull request to release the candidate branch into production, which will trigger a deployment.
It was created by the [Production PR] action.

github-actions bot and others added 2 commits November 11, 2025 23:43
* fix(app): show MDM policy for mac User

* fix(app): fix status issue of mdm policy

* fix(portal): fix status issue of mdm policy

---------

Co-authored-by: chasprowebdev <chasgarciaprowebdev@gmail.com>
@vercel
Copy link

vercel bot commented Nov 12, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
app (staging) Ready Ready Preview Comment Nov 12, 2025 11:28pm
portal (staging) Ready Ready Preview Comment Nov 12, 2025 11:28pm

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@comp-ai-code-review
Copy link

comp-ai-code-review bot commented Nov 12, 2025

🔒 Comp AI - Security Review

🔴 Risk Level: HIGH

One OSV CVE (GHSA-rwvc-j5jr-mgvh) in ai@5.0.0; hardcoded API token found in EmptyState.tsx; multiple files use unsanitized route/IDs directly in DB queries (policyId, riskId, vendorId, taskId, organizationId).


📦 Dependency Vulnerabilities

🟢 NPM Packages (LOW)

Risk Score: 2/10 | Summary: 1 low CVE found

Package Version CVE Severity CVSS Summary Fixed In
ai 5.0.0 GHSA-rwvc-j5jr-mgvh LOW N/A Vercel’s AI SDK's filetype whitelists can be bypassed when uploading files 5.0.52

🛡️ Code Security Analysis

View 20 file(s) with issues

🔴 apps/api/src/auth/hybrid-auth.guard.ts (HIGH Risk)

# Issue Risk Level
1 No HTTPS enforcement for BETTER_AUTH_URL — allows MITM and token forgery HIGH
2 Accepting BETTER_AUTH_URL from env/config allows attackers to control JWKS HIGH
3 Creating JWKS with cacheMaxAge=0 on retry enables heavy fetches (DoS) HIGH
4 No rate limiting on JWKS fetch/retry, can be abused to overload auth server HIGH
5 Potential SSRF if BETTER_AUTH_URL is attacker-controlled HIGH
6 Detailed error logs may leak internal endpoints, stack traces, or secrets HIGH
7 JWT payload fields (id/email) are used without schema/type validation HIGH
8 X-Organization-Id is taken directly from headers; header spoofing risk HIGH
9 Issuer and audience both set to the same URL may mask misconfigurations HIGH

Recommendations:

  1. Enforce and validate HTTPS for BETTER_AUTH_URL (reject non-https). Normalize and validate the URL at startup; prefer a configured whitelist of allowed auth domains rather than allowing arbitrary env overrides.
  2. Do not allow untrusted runtime overrides of BETTER_AUTH_URL. If necessary, restrict to a small set of approved domains (config or env per environment) and fail startup if the value is unexpected.
  3. Avoid creating JWKS instances with cacheMaxAge=0 and cooldownDuration=0 in production. Instead implement controlled cache/backoff: use a short but non-zero cache and exponential backoff for refetch attempts to limit burst fetches.
  4. Rate-limit JWKS refresh attempts and overall auth attempts per client IP and per token to mitigate amplification/DoS. Consider server-side caching of the JWKS fetched externally and refresh on a schedule rather than on-demand per failing request.
  5. Validate BETTER_AUTH_URL against an allowlist and ensure the JWKS fetch cannot be pointed at internal-only addresses (reject private IPs / loopback if not intended) to prevent SSRF. Use proper URL parsing and network egress controls.
  6. Sanitize and reduce log verbosity: avoid logging full error objects, stack traces, or internal URLs in production logs. Log only sanitized messages or correlation IDs. Use structured logging and a redaction policy for internal endpoints and secrets.
  7. Validate JWT payload fields with a schema/type checker (e.g., zod, joi, or explicit type guards) before using them. Explicitly validate types and shapes for id, email and any other claims used by the app.
  8. Don't blindly trust X-Organization-Id. Prefer deriving organization context from a claim in the verified token, or if an explicit header is required, canonicalize and validate it strictly and then enforce server-side authorization checks (which you already have). Consider requiring the org claim in the token and verifying it matches the header if both present.
  9. Clarify and harden issuer/audience checks to reflect your actual auth model. Use distinct expected issuer and audience values where appropriate and fail fast on misconfiguration. Document the expected values and validate them at startup.

🔴 apps/api/src/main.ts (HIGH Risk)

# Issue Risk Level
1 CORS allows any origin with credentials (origin: true, credentials: true) HIGH
2 Public Swagger UI with apiKey security and persistAuthorization enabled HIGH
3 OpenAPI JSON written to repository path in non-production HIGH

Recommendations:

  1. Restrict CORS origins: replace origin: true with an allowlist (function or array) that validates the Origin header and returns true only for trusted domains. If you must allow many origins, implement a per-request origin-checking function that only sets Access-Control-Allow-Origin to the incoming origin when it is on the allowlist.
  2. Avoid allowing credentials for all origins: set credentials: false unless cross-site cookies or credentials are strictly required. If credentials:true is required, ensure origin is validated per-request (see previous point) and never use origin:true.
  3. Protect Swagger in production: only enable Swagger UI in non-production or behind authentication/IP allowlist. Gate SwaggerModule.setup behind NODE_ENV !== 'production' or add an auth guard that requires admin credentials to access /api/docs.
  4. Disable persistAuthorization in public docs: set persistAuthorization: false to avoid storing real API keys in users' browsers. Consider removing apiKey examples from the docs or using placeholder/example keys only.
  5. Avoid writing sensitive OpenAPI artifacts to repository paths: either write to a secure artifact store, CI artifacts, or ensure written OpenAPI JSON never contains sensitive example values. Only write docs to repo when you have a safe process (e.g., scrub secrets, run in isolated environment) and ensure .gitignore/commit policies prevent accidental commits of secrets.

🔴 apps/app/src/actions/organization/invite-member.ts (HIGH Risk)

# Issue Risk Level
1 Returns raw error.message to client (information disclosure) HIGH
2 Logs potentially sensitive data (email) to console HIGH
3 No authorization check preventing invites to privileged roles HIGH
4 Allows assigning 'owner' role without restriction (privilege escalation) HIGH
5 No rate limiting or abuse protection for invites HIGH

Recommendations:

  1. Do not return raw error.message to the client. Return a generic error (e.g., "Failed to invite member") and log full details server-side with correlation IDs.
  2. Avoid logging PII. Remove email from logs or redact it before logging. Ensure thrown error objects logged server-side do not contain input values or sanitize them.
  3. Enforce server-side authorization checks: verify the inviter's permissions in ctx.session (or call an authorization service) and only allow roles that the inviter is permitted to assign.
  4. Disallow assigning highly privileged roles (like 'owner') unless the inviter has explicit entitlement and the action is audited/approved. Validate the requested role against an allowlist derived from inviter permissions or org policy before calling authClient.organization.inviteMember.
  5. Implement rate limiting/throttling for invite endpoints (per-inviter, per-IP, per-organization) and add abuse detection (CAPTCHA, email verification flow) to mitigate bulk/spam invites.
  6. Log structured events (without PII) and use monitoring/alerting for invite failures and unusual invite volumes. Consider auditing successful owner-role invites.

🟡 apps/app/src/actions/policies/publish-all.ts (MEDIUM Risk)

# Issue Risk Level
1 Role check uses substring includes('owner') — can be bypassed MEDIUM
2 No DB transaction — partial policy updates possible MEDIUM
3 Logs include error stacks and sensitive IDs MEDIUM
4 organizationId only string-validated (no UUID/format check) MEDIUM
5 Role 'contains' queries may match substrings leading to wrong members MEDIUM

Recommendations:

  1. Enforce strict role checks: use exact equality against an enum (e.g., member.role === Role.owner) or ensure the DB stores role as an enum/normalized field and query with equality rather than string includes(). Avoid substring matching in authorization checks.
  2. Wrap all policy updates in a database transaction (e.g., db.$transaction or equivalent) so updates are atomic. If you need to perform many writes, use a transaction or a two-phase approach so partial publishes cannot leave state inconsistent.
  3. Sanitize logs: do not log full error stacks or user/member/organization identifiers in production logs. Log minimal context (error code, non-PII markers) and send detailed diagnostics to a protected observability system with strict access controls.
  4. Validate organizationId format at the schema boundary (e.g., z.string().uuid() if IDs are UUIDs) before performing DB queries. This protects against malformed input and makes intent explicit.
  5. Avoid using 'contains' in DB role filters for authorization/role selection. Use exact enum comparisons (role: Role.employee) or store roles as a normalized relation/array and query using precise operators to prevent unintended substring matches.

🟡 apps/app/src/app/(app)/[orgId]/people/all/components/MemberRow.tsx (MEDIUM Risk)

# Issue Risk Level
1 Client-side-only authorization (canEdit) can be bypassed MEDIUM
2 No server-side validation of selected roles before onUpdateRole MEDIUM
3 Untrusted avatar URL used directly in image src MEDIUM
4 Member/org IDs inserted into URLs without validation MEDIUM
5 Inconsistent role parsing may allow unexpected role values MEDIUM

Recommendations:

  1. Enforce authorization on the server for all actions (update roles, remove member). Treat canEdit as UI-only and validate the current user's permissions in the API handlers before performing any changes.
  2. Validate and normalize role inputs server-side. Accept only allowed enum values (owner, admin, auditor, employee, contractor). Reject attempts to set or unset privileged roles (e.g., owner) unless the server-side policy permits it.
  3. Sanitize and validate avatar URLs before rendering. Disallow unsafe schemes (javascript:, data:, etc.) and either: (a) serve user-uploaded images from a safe CDN/origin under your control, or (b) use a proxy that verifies and rewrites external URLs. Consider using Next/Image or similar that performs built-in handling and validation.
  4. Validate and canonicalize orgId and memberId on the server. On the client, encode path components (encodeURIComponent(orgId), encodeURIComponent(memberId)) when building URLs to avoid accidental path injection. On the server, ensure IDs match expected formats (UUID, numeric, or known slug pattern).
  5. Normalize role parsing in a single canonical place (preferably server). Treat UI parsing as convenience only. Ensure the server rejects unknown/extra role strings and that role lists are stored in a consistent format (array of enums).

🟡 apps/app/src/app/(app)/[orgId]/people/all/components/MultiRoleCombobox.tsx (MEDIUM Risk)

# Issue Risk Level
1 Client-side enforcement of owner role change (bypassable) MEDIUM
2 LockedRoles enforced only in UI; can be circumvented MEDIUM
3 Comma-splitting of selectedRoles can introduce 'owner' from props MEDIUM
4 selectableRoles includes 'owner' despite comment to exclude it MEDIUM

Recommendations:

  1. Enforce all role changes and locking rules on the server-side. Never rely on client-side checks for authorization or role invariants.
  2. Treat props and client input as untrusted. On any API that updates roles, validate the entire payload server-side: validate types, allowed role values, disallow malformed/comma-separated strings, and reject unauthorized role changes (especially owner).
  3. Remove or hide 'owner' from the client-side selectable list unless the server authoritatively indicates the current user/context has owner privileges. Prefer server-provided available-role lists rather than hard-coding owner visibility logic in the client.
  4. Stop accepting comma-delimited role strings in props. Accept/serialize roles as a strict Role[] type at boundaries, or canonicalize/validate inputs immediately and reject malformed values. If you must parse strings, validate each parsed token against the allowed Role enum and reject unknown values.
  5. Ensure backend enforces lockedRoles and will not accept requests to remove locked roles; return appropriate HTTP error codes for attempts to modify protected roles.
  6. Add explicit input validation and canonicalization both client- and server-side (e.g., schema validation with zod/Joi/TypeScript runtime checks) to prevent strange inputs from propagating.
  7. Add tests for role change APIs and UI-to-API interactions that verify owner and locked-role invariants cannot be bypassed via crafted requests.
  8. Log and monitor attempts to change protected roles (owner/locked) so suspicious activity can be detected and investigated.

🟡 apps/app/src/app/(app)/[orgId]/policies/[policyId]/data/index.ts (MEDIUM Risk)

# Issue Risk Level
1 Unsanitized policyId used directly in DB queries MEDIUM
2 Multiple functions accept policyId without format validation MEDIUM
3 No granular authorization checks (role/permission enforcement) MEDIUM
4 Sensitive user data returned (email, image) in API responses MEDIUM
5 Session retrieved from headers without extra verification MEDIUM

Recommendations:

  1. Validate and canonicalize incoming IDs (e.g., enforce UUID v4 with a library such as validator.js or zod) before using them in DB queries. Add explicit type/length checks and reject/404 early for invalid IDs.
  2. Add per-endpoint authorization checks beyond verifying activeOrganizationId. Verify the session user is a member of the organization and has the appropriate role/permission to read the requested policy, comments, attachments, or audit logs.
  3. Minimize or redact sensitive user fields by default. Only return user.email and user.image when the caller is authorized to see them; otherwise return limited author metadata (e.g., display name and id). Consider explicit DTOs for public vs private responses.
  4. Rely on the ORM's parameterization but still perform input validation and canonicalization — do not assume ORM usage alone is sufficient for business-logic validation. Avoid building any raw queries with untrusted inputs.
  5. Harden session handling: ensure auth.api.getSession performs strong verification (token signature, expiry, revocation). Add explicit error handling when sessions are missing/invalid instead of returning broad defaults. Log and monitor suspicious session activity.
  6. Add explicit error handling and logging for DB operations (avoid returning internal errors to clients). Consider rate limiting and monitoring on endpoints that enumerate resources (logs, comments, attachments).

🔴 apps/app/src/app/(app)/[orgId]/risk/(overview)/page.tsx (HIGH Risk)

# Issue Risk Level
1 Global cache of getAssignees can leak assignees across sessions/orgs HIGH
2 Cached function calls headers() so per-request session may be reused HIGH

Recommendations:

  1. Remove the global React cache on getAssignees. Do not cache database queries that are scoped to a user/session/organization.
  2. If caching is required, scope the cache by a key that includes the organization ID or session identifier (e.g., make getAssignees accept orgId and cache by that orgId).
  3. Do not call next/headers() or auth.api.getSession() from inside an unkeyed cached function. Resolve the session/headers per-request and pass the orgId/session into any cached helper.
  4. Add explicit unit tests to ensure getAssignees returns the correct data for different orgIds and that subsequent requests do not receive stale/mismatched data.

🔴 apps/app/src/app/(app)/[orgId]/risk/[riskId]/page.tsx (HIGH Risk)

# Issue Risk Level
1 Cached session-dependent DB queries (getRisk, getAssignees) can leak other orgs' data HIGH
2 Using unsanitized riskId param directly in DB query (no validation) HIGH
3 headers() called inside cached functions causing cross-request cache pollution HIGH

Recommendations:

  1. Stop using react cache() for functions that depend on per-request/session data. Remove cache() from getAssignees and from getRisk (or ensure the cache key includes session-scoped values).
  2. If you must cache, include session/session.session.activeOrganizationId (or a per-session/per-org value) as an explicit function argument so the cache key is per-org (e.g., getAssignees(orgId) and getRisk(riskId, orgId)).
  3. Do not call headers() or other request-scoped APIs from inside cached functions. Read the session/headers in the request flow and pass required values into any cached function as arguments.
  4. Validate and sanitize riskId before using it (e.g., enforce UUID or expected format with a server-side check). Reject/return 400 for malformed IDs.
  5. Keep enforcing server-side authorization: ensure the DB query's where clause always ties the resource to session.session.activeOrganizationId and that the session read happens per-request (not from cache).
  6. Rely on your ORM's parameterized queries for SQL injection protection, but still validate inputs and avoid constructing raw SQL with user input. If raw queries are necessary, use parameter binding.
  7. Add logging and tests to ensure cache behavior does not return cross-organization data (unit/integration tests with multi-org scenarios).

🔴 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/actions/generate-suggestions.ts (HIGH Risk)

# Issue Risk Level
1 Direct use of organizationId in DB queries without auth/validation (IDOR/SQL risk) HIGH
2 No authorization check before accessing organization data (IDOR) HIGH
3 Sensitive vendor/context fields logged to console (data leakage) HIGH
4 taskDescription and AI-generated suggestions returned without sanitization (XSS/unsafe content) HIGH
5 No input schema/validation for function params (taskDescription, organizationId) HIGH

Recommendations:

  1. Enforce authorization: validate that the caller (session/user) is authorized to access the given organizationId before any DB calls. Return 403/deny access if not authorized.
  2. Validate and sanitize inputs: apply an explicit schema (e.g., zod) to taskDescription and organizationId at the API/controller boundary. Coerce/validate types and maximum lengths.
  3. Minimize data exposure in logs: avoid logging vendor or context content. If logging is required, redact or hash sensitive fields (names, websites, answers).
  4. Sanitize/filter AI outputs before returning to clients: perform content moderation, remove/escape HTML or scripts, and validate fields (title, prompt) against expected formats/lengths. Escape output on the client to prevent XSS.
  5. Limit what is sent to the AI provider: avoid sending full sensitive context or vendor PII to external services. If external calls are necessary, ensure data-minimization and explicit consent.
  6. Use least-privilege DB roles and rely on ORM parameterization. Still enforce application-level authorization checks to prevent IDOR even if the ORM protects against raw SQL injection.
  7. Add request-level safeguards: rate-limiting, auditing for AI responses, and monitoring for anomalous access patterns.

🟡 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/AutomationPageClient.tsx (MEDIUM Risk)

# Issue Risk Level
1 Unsanitized taskDescription sent to generateAutomationSuggestions MEDIUM
2 Unvalidated orgId/taskId/automationId used in API call MEDIUM
3 Potential XSS if suggestions are rendered without sanitization MEDIUM
4 No schema/shape validation for suggestions result MEDIUM
5 Console logs timing/errors may expose internal info MEDIUM

Recommendations:

  1. Validate and sanitize taskDescription before use
  2. Validate orgId/taskId/automationId inputs
  3. Sanitize/escape suggestion fields before rendering
  4. Remove/limit sensitive console logs in production
  5. Add schema validation and robust error handling for results

🔴 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/chat/EmptyState.tsx (HIGH Risk)

# Issue Risk Level
1 Hardcoded API token in image URLs (pk_AZatYxV5QDSfWpRDaBxzRQ) HIGH
2 Vendor website/name forwarded to external logo service (privacy leak) HIGH
3 No validation/encoding of vendor input when building logo URL (URL tampering) HIGH

Recommendations:

  1. Remove the hardcoded token from source code. Load it from configuration or environment variables (e.g., process.env or a secure runtime secret store). Do not commit secrets to the repo.
  2. Treat the exposed token as compromised: rotate the token immediately and restrict its permissions and allowed origins if the provider supports it.
  3. Avoid placing sensitive tokens in client-side code. If the token must be secret, proxy logo requests through a server-side endpoint that injects the token server-side so the client never sees it.
  4. If you must call the third-party service directly from the client, use a non-sensitive public key or a token with minimal scope, and prefer server-side signing where possible.
  5. Validate and whitelist vendor inputs (vendorWebsite, vendorName) before using them. Only allow known, expected domains or names from an allowlist.
  6. Parse vendorWebsite using a proper URL parser (new URL(...)) and explicitly extract hostname. Normalize/validate the hostname against a whitelist or pattern.
  7. Encode any dynamic path/query parts with encodeURIComponent before interpolation into the logo URL to prevent URL tampering or path injection.
  8. Limit fallback behaviour and ensure image URLs aren’t constructed from arbitrary user input. Consider mapping known vendor names to safe canonical domains rather than using raw input.
  9. Add server-side logging/monitoring for unexpected or malformed vendor inputs so you can detect abuse or scanning attempts.

🟡 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/chat/message-part/prompt-secret.tsx (MEDIUM Risk)

# Issue Risk Level
1 Unvalidated inputs sent to /api/secrets (name,value,description,organizationId) MEDIUM
2 No CSRF protection on POST /api/secrets (fetch may send cookies) MEDIUM
3 Secret value stored in React state and can persist in memory/devtools MEDIUM
4 Potential secret leakage via console.error or client-side logs MEDIUM
5 AI-provided secretName used read-only without explicit user confirmation MEDIUM

Recommendations:

  1. Validate and sanitize all inputs server-side (name, value, description, organizationId). Never trust client-side validation — validate types, allowed characters and lengths, and enforce authorization checks server-side before creating secrets.
  2. Harden /api/secrets against CSRF: require anti-CSRF tokens (double-submit cookie or server-generated token), use explicit Authorization (Bearer) headers for API calls, and ensure cookies are SameSite=strict/lax and use secure flags. Treat POST endpoints that change state as requiring CSRF protections.
  3. Minimize the lifetime of secrets in client memory: avoid keeping secret values in React state where possible; if needed, clear state immediately after submission and overwrite variables. Consider using in-memory only constructs that are zeroed after use and avoid exposing values to devtools (e.g., avoid storing on window or logging).
  4. Avoid logging errors that may contain sensitive values. Do not call console.error with raw error objects that could embed request/response bodies containing secrets. Sanitize or redact any fields that may contain secrets before logging.
  5. Require explicit user confirmation for AI-provided secret names before making them read-only or using them to create secrets. Show a clear UI affordance that the name was AI-generated and allow the user to accept/modify it before submission.

🟡 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/evaluation/EvaluationCriteriaCard.tsx (MEDIUM Risk)

# Issue Risk Level
1 Unsanitized user input sent to updateEvaluationCriteria MEDIUM
2 No client-side input validation or length limits on criteria MEDIUM
3 Potential stored XSS if backend stores criteria and renders unsafely MEDIUM
4 Server error messages displayed directly via toast.error MEDIUM
5 No CSRF token handling shown for state-changing action MEDIUM

Recommendations:

  1. Validate and sanitize criteria server-side before storage or execution
  2. Enforce client-side length and whitelist validation for input
  3. Escape or encode criteria when rendering anywhere as HTML
  4. Avoid echoing raw server errors to users; sanitize/log them
  5. Require CSRF protections or use same-site tokens for updates

🔴 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/page.tsx (HIGH Risk)

# Issue Risk Level
1 No authentication/authorization before DB task lookup HIGH
2 Route params used directly in DB query (no validation) HIGH
3 automationId used directly to load chat history (no validation) HIGH
4 User messages forwarded to client without sanitization (XSS) HIGH
5 Possible SQL injection if DB layer isn't parameterized HIGH

Recommendations:

  1. Enforce authentication and authorization before performing DB lookups: verify the current user is authenticated and is a member/owner of orgId and is allowed to view taskId. Implement middleware or server-side guard that checks session/token and org membership.
  2. Validate and type-check route params early (taskId, orgId, automationId). Use schemas (e.g., zod/Joi) or assert UUID/expected format and reject invalid values before DB/logic use.
  3. Do not trust automationId from the route. Validate it and enforce ACLs for accessing chat history. Limit what automationIds a user can access to those belonging to their org/user.
  4. Ensure the DB/ORM uses parameterized queries. If using a raw query API anywhere, convert to parameterized/prepared statements or use the ORM's safe query helpers (e.g., Prisma client methods) rather than string concatenation.
  5. Sanitize or escape chat messages before sending them to the client or ensure the client-side rendering never uses raw HTML insertion. Use a vetted HTML sanitizer (e.g., DOMPurify) or render messages as plain text. Enforce content policies and size/type limits on saved messages.
  6. Add logging and rate-limiting for access to these endpoints to detect and mitigate abuse or enumeration attempts.

🟡 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/hooks/use-task.ts (MEDIUM Risk)

# Issue Risk Level
1 Unvalidated orgId/taskId used in API request (server-side injection risk) MEDIUM
2 Propagates raw server error messages to client (info disclosure) MEDIUM
3 URL params used in SWR cache key may leak identifiers MEDIUM

Recommendations:

  1. Validate and sanitize orgId and taskId before use (both client and server). On the client, check format/length (e.g. UUID regex) and reject clearly invalid values before making requests.
  2. Enforce strict validation and authorization on the server side for orgId/taskId. Treat path params as untrusted, validate against expected patterns, and use them only in safe, parameterized operations (e.g., parameterized DB queries or ORM methods).
  3. Never rely solely on client-side validation for security — ensure the server performs full validation and authorization checks (owner/org membership) for the requested task.
  4. Avoid returning raw server error messages to the client. Map internal errors to safe, minimal messages (e.g. 'Task not found' or 'Internal error') and log detailed errors server-side.
  5. Avoid putting sensitive identifiers directly into client-side cache keys if those IDs are considered sensitive. Consider using opaque/hashed tokens or a less-identifying key (e.g., hashed(taskId) or only org-scoped keys) or limit exposure by scoping cache keys to non-sensitive values.
  6. If taskId/orgId are used in backend queries, ensure all database access uses parameterized queries/ORM protections to prevent injection.

🔴 apps/app/src/app/(app)/[orgId]/vendors/(overview)/data/queries.ts (HIGH Risk)

# Issue Risk Level
1 No authorization check for orgId access HIGH
2 No validation for page/perPage leading to div by zero or DoS HIGH
3 Unsanitized 'filters' may allow unsafe query construction HIGH
4 Exposes full assignee.user object, may leak sensitive fields HIGH
5 Caching without user scoping may leak org data across requests HIGH

Recommendations:

  1. Enforce authorization: verify the caller is allowed to access orgId before any DB call (e.g., check session/user membership and roles).
  2. Validate pagination params: ensure page and perPage are positive integers, enforce a max perPage, and handle perPage === 0 to avoid divide-by-zero.
  3. Handle filters safely: implement strict parsing of filters into allowed fields/operations, validate values, and avoid concatenating raw SQL or evaluating user input.
  4. Limit returned user fields: explicitly select only non-sensitive user attributes (e.g., id, name, email) and exclude sensitive fields like password hashes or secrets.
  5. Scope or avoid long-lived caches for sensitive data: include the appropriate scope in cache keys (orgId + user/role if responses vary by caller), use short TTLs, or avoid caching highly sensitive fields.

🔴 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/page.tsx (HIGH Risk)

# Issue Risk Level
1 Global caching (getAssignees) can expose other orgs' data across sessions HIGH
2 getVendor() cached only by vendorId ignores session/org context, risking data leakage HIGH
3 Route param vendorId used directly in DB query without validation HIGH

Recommendations:

  1. Remove caching from functions that depend on per-request session headers (getAssignees, getVendor), or include session/organizationId in the cache key so results are scoped to the active organization.
  2. Do not call headers() / resolve session inside a globally memoized/cached function. Resolve session and org context per-request and pass orgId/session identifier as an explicit function argument if you want to memoize safely.
  3. Validate route parameters before using them in DB queries (e.g., ensure vendorId is the expected type/format such as a UUID).
  4. Keep strict server-side authorization: always verify that the requested vendor belongs to the caller's activeOrganizationId before returning data.
  5. Audit any UI components that render database-derived strings (e.g., PageWithBreadcrumb) to ensure they do not use dangerouslySetInnerHTML or otherwise inject raw HTML. If raw HTML is required, sanitize it with a vetted sanitizer.
  6. Prefer relying on the ORM's parameterized queries (do not build raw query strings with user input).
  7. Add tests that exercise concurrent requests from different sessions to verify no cached cross-organization leakage occurs.

🔴 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/tasks/[taskId]/page.tsx (HIGH Risk)

# Issue Risk Level
1 Missing authorization: no check user belongs to organization or can access task HIGH
2 Unsanitized route params (orgId/taskId) used directly in DB queries HIGH
3 Excessive data exposure: member.findMany returns user data without access gating HIGH
4 No validation of orgId/taskId format or types before DB use HIGH

Recommendations:

  1. Add explicit authorization: after verifying session, confirm the session.user is a member of orgId and has permission to view/edit the specific task (e.g., check membership/role and task.organizationId or an ACL). Consider centralizing this in middleware or a reusable server-side guard.
  2. Validate route parameters early: ensure orgId and taskId conform to expected formats (e.g., UUID checks or DB id type). Reject invalid formats before querying the DB.
  3. Limit data returned from the DB: use explicit select projections instead of include: { user: true } to avoid overfetching sensitive user fields. Only return fields needed by the UI.
  4. Keep using parameterized ORM queries but do not rely on that alone: perform input validation and type-checking so malformed or unexpected values are rejected before DB access.
  5. Log and monitor authorization failures and suspicious access patterns; rate-limit or alert on repeated failures.

🔴 apps/app/src/app/(app)/[orgId]/vendors/backup-overview/layout.tsx (HIGH Risk)

# Issue Risk Level
1 Cached functions use headers()/session, risking cross-request session leakage HIGH
2 cache() used without request-specific keys can reuse another org's data HIGH
3 Session-derived orgId used in DB queries/URLs with minimal validation HIGH

Recommendations:

  1. Remove cache() from functions that call headers() / getServersideSession, or refactor so cached functions accept the request-scoped key (e.g., orgId) as an explicit parameter and are invoked per-request (e.g., const getVendorOverviewForOrg = cachedFn(orgId) ).
  2. If you keep caching, make cache keys explicit and include request/session identifiers (activeOrganizationId) so results are scoped to an organization. For React's cache, implement cached functions that take orgId as an argument, not ones that call headers() internally.
  3. Avoid calling headers() or other request-scoped APIs from top-level cached functions. Resolve request/session data in the request scope and pass only non-sensitive, validated parameters into cached helpers.
  4. Validate and normalize activeOrganizationId (type check, format check e.g., UUID) before using it in DB queries or building URLs. Fail closed if validation fails.
  5. Limit what you cache to non-sensitive or aggregate data when per-request scoping cannot be guaranteed. Consider short TTLs or per-org caches stored in a keyed cache store if needed.
  6. Ensure getServersideSession strictly enforces authentication/authorization and that session values (activeOrganizationId) cannot be forged or set by clients.
  7. Add instrumentation/tests that exercise multiple concurrent sessions/orgs to ensure cached results are isolated per org and no cross-tenant leakage occurs.

💡 Recommendations

View 3 recommendation(s)
  1. Upgrade the vulnerable dependency: bump package "ai" from 5.0.0 to >=5.0.52 in package.json and reinstall so GHSA-rwvc-j5jr-mgvh is patched.
  2. Remove the hardcoded token (pk_AZatYxV5QDSfWpRDaBxzRQ) in apps/app/src/app/(app)/[orgId]/tasks/.../chat/EmptyState.tsx. Replace with a runtime-config value (e.g., read from process.env) and ensure the client bundle does not contain the secret; if a client-accessible key is required, use a non-sensitive public token.
  3. Validate and canonicalize all route parameters before any DB call in the listed files (examples: apps/app/src/app/(app)/[orgId]/policies/[policyId]/data/index.ts, risk/[riskId]/page.tsx, vendors/, tasks/). Enforce explicit format checks (UUID regex or whitelist) and reject/404 malformed IDs; use only validated values in ORM queries to prevent injection/IDOR risks.

Powered by Comp AI - AI that handles compliance for you. Reviewed Nov 12, 2025

* feat(db): add deactivated column to member table

* feat(db): add contractor role

* feat(app): add contractor role

* fix(db): remove duplicated migration for contractor role

* fix(db): update date and time of migration for deactivated column

* fix(app): set deactivated when creating mock member

---------

Co-authored-by: chasprowebdev <chasgarciaprowebdev@gmail.com>
Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
* fix(api): improve env loading and JWKS retry handling

- Load .env manually before NestJS bootstrap
- Add automatic JWKS retry on key mismatch
- Remove redundant ConfigModule envFilePath

* fix(auth): add automatic token refresh on 401 errors

- Auto-refresh token and retry request on 401
- Add race condition protection and cooldown
- Fix useTask hook to wait for orgId from URL params

* feat(automation): add AI-generated suggestions for new automations

- Generate task-specific suggestions using GPT-4o-mini
- Load suggestions asynchronously for faster page load
- Add loading state for automation page

* feat(automation): improve suggestion prompts and error handling

- Ensure suggestions match exact task topic
- Exclude screenshots, require API integrations only
- Add fallback for broken vendor logo images

* feat(automation): add skeleton loaders for suggestion cards

- Show animated skeleton cards while AI suggestions are loading
- Match card structure and layout for smooth transition
- Load suggestions asynchronously without blocking page render

* chore(deps): update @trycompai/db to version 1.3.17 and add dotenv

* refactor(automation): remove reduced limits on vendor queries for clarity

* feat(automation): improve suggestion UI and add vendor diversity

- add flushSync for immediate UI updates after suggestions load
- change placeholder to generic text
- add vendor diversity requirement to AI prompts to avoid duplicate vendors

---------

Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
@Marfuen Marfuen merged commit ac10ba8 into release Nov 12, 2025
10 of 13 checks passed
@claudfuen
Copy link
Contributor

🎉 This PR is included in version 1.57.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants