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.

* chore(automation): set default title and handle empty integrations in workflow visualizer

* chore: add ability to support multiple automations per task

* chore(automation): add update and delete functionality for task automations

* refactor(tasks): simplify task fetching and remove unused members logic

* chore(automation): implement automated evidence collection and related schema

* chore(docs): add fraud to risk category enum in openapi schema

* refactor(automation): remove organizationId from automation methods

* chore: cleanup and add automations

* feat(automation): enhance automation overview with latest runs and details

* chore: cleanup chat

* feat: added chat history

* refactor(chat): use ref for automationId to improve state management

* chore(automation): implement versioning for automation scripts with API endpoints

* chore: update bun lock

* chore: update UI

* chore(automation): update integrationsUsed type in UnifiedWorkflowCard

* chore(deps): add better-auth package and update TypeScript target

---------

Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
@comp-ai-code-review
Copy link

comp-ai-code-review bot commented Oct 14, 2025

🔒 Comp AI - Security Review

🔴 Risk Level: HIGH

No OSV CVEs found; code-level injection/IDOR issues observed: unsanitized IDs in DB queries/versioning, and unscoped storage/Redis key construction.


📦 Dependency Vulnerabilities

✅ No known vulnerabilities detected in dependencies.


🛡️ Code Security Analysis

View 13 file(s) with issues

🔴 ENTERPRISE_API_AUTOMATION_VERSIONING.md (HIGH Risk)

# Issue Risk Level
1 Missing enforced authentication on endpoints HIGH
2 Missing authorization checks for org/task/automation access HIGH
3 Unsanitized orgId/taskId/automationId used to build S3 keys HIGH
4 Unsanitized inputs used in DB query for next version (SQL injection) HIGH
5 Race condition when computing next version (no transaction/lock) HIGH
6 S3 key manipulation can overwrite other orgs' objects HIGH
7 Using automationId directly to access Redis can expose other chats HIGH
8 No validation of 'version' input (type/range) before use HIGH
9 Storing arbitrary scripts without validation (malicious code risk) HIGH
10 Detailed errors may leak internal S3/DB state or paths HIGH

Recommendations:

  1. Enforce authentication on these endpoints (API keys/session) and verify user identity before any operations.
  2. Add fine-grained authorization checks: ensure the authenticated user has access to the specified orgId/taskId/automationId before performing S3/DB/Redis operations.
  3. Validate and strictly sanitize orgId, taskId, automationId and version inputs. Enforce an allowlist pattern (e.g., ^org_[A-Za-z0-9_-]+$) and reject unexpected characters.
  4. Use parameterized queries or an ORM for all DB access. Never interpolate request fields into SQL. When determining the next version, perform the increment within a DB transaction or use an atomic DB-side sequence/counter to avoid race conditions.
  5. Protect against race conditions when computing the next version: use a DB transaction with row-level locking (SELECT ... FOR UPDATE), an atomic increment, or a dedicated version-sequence table/column.
  6. Constrain S3 operations to an authenticated org-scoped prefix server-side (derive the S3 key from server-validated orgId and do not accept full keys from clients). Apply least-privilege IAM policies so the service can only modify keys within allowed prefixes.
  7. For Redis keys, namespace them by org and verify access before reading/writing (e.g., redis key automation:{orgId}:{automationId}:chat). Do not trust raw automationId from clients to directly access chat history.
  8. Validate the 'version' parameter type and allowed range (positive integer, within existing version bounds) before using it to construct S3 keys or DB queries.
  9. Treat uploaded/stored scripts as untrusted: scan for malicious content, restrict upload size, store as data (not executed) unless run in a strict sandbox, and perform static analysis or opt-in code review before allowing execution.
  10. Return minimal error details to clients (avoid exposing S3 keys, stack traces, DB errors). Log full errors internally with correlation IDs for debugging.
  11. Add server-side rate limiting and auditing for publish/restore operations to detect abuse.
  12. Use robust logging and monitoring for S3/DB/Redis errors and unauthorized access attempts.
  13. Document and test error codes (404/400/500) and test the edge cases: missing draft, missing version, invalid ids, concurrent publishes.

🔴 apps/api/Dockerfile (HIGH Risk)

# Issue Risk Level
1 Remote code execution: curl bash from https://bun.sh/install
2 Unverified installer: no checksum/signature verification HIGH
3 Running npx prisma generate as root may execute arbitrary scripts HIGH
4 Installing tools (bash,curl,openssl) increases attack surface HIGH
5 COPY . . after deps install can overwrite files and cause inconsistencies HIGH

Recommendations:

  1. Stop piping remote scripts directly to a shell. Download the installer first, verify integrity (checksum/signature) and inspect before executing. Prefer vendor-signed releases or packages distributed via trusted package managers.
  2. Pin and verify installer artifacts: use a pinned bun release (hash) or package repository and validate signatures/checksums before install.
  3. Move build steps that run package tooling (bun install, npx prisma generate) into a non-root build stage (multi-stage build). Create a dedicated builder stage that runs as root only when necessary, then chown artifacts and switch to an unprivileged user in the final stage. Ensure prisma generate runs as a non-root user or inside the builder stage.
  4. Use a multi-stage Docker build: install/build in a builder stage and copy only the minimal runtime artifacts into the final image to reduce installed tooling and attack surface.
  5. Avoid installing unnecessary packages in the runtime image (e.g., bash, curl, openssl) — if required for build or healthchecks, keep them confined to the builder stage or use static alternatives. Consider using a lightweight healthcheck approach (curl/wget only in builder or use an external healthcheck).
  6. Ensure package lockfiles (bun.lockb / package-lock.json / pnpm-lock.yaml) are present and used to pin dependency versions, and use reproducible installs (pin bun/node versions).
  7. Avoid COPY . . after installing deps that rely on repo files. Instead: copy only necessary manifest files first, install, then copy built artifacts (or use builder stage) to prevent overwriting installed artifacts or introducing inconsistent state.
  8. Where possible, run riskier commands under a dedicated non-root user and set appropriate file ownership (chown) before switching USER in the final image.

🔴 apps/api/buildspec.yml (HIGH Risk)

# Issue Risk Level
1 Unverified remote install: curl https://bun.sh/install bash
2 No checksum/signature verification for bun installer HIGH
3 Caching node_modules/bun cache may persist malicious packages HIGH
4 BUILDKIT_INLINE_CACHE may leak build layers or secrets into images HIGH
5 Environment values (APP_NAME, ECR vars) used without sanitization HIGH
6 Potential sensitive files copied into Docker context (dist/, prisma) HIGH

Recommendations:

  1. Stop piping remote install scripts directly. Download the installer to disk first, verify its checksum/signature, then execute. Prefer distribution packages or pinned releases instead of running an unaudited remote script.
  2. Pin the bun installer to a specific version and verify cryptographic signatures or SHA256 checksums. If possible, use an official package repository or vendor the runtime in your build image.
  3. Limit caching of dependency caches in CI or ensure caches are scanned and immutably versioned. Invalidate caches on suspicious changes and run regular supply-chain scans of cached packages (SBOM, SCA tooling).
  4. Avoid exporting BUILD cache metadata into final images. Do not enable BUILDKIT_INLINE_CACHE unless you understand and control who can pull the images. Use BuildKit secrets and --secret to pass sensitive data during build and ensure multi-stage builds do not leave secrets in intermediate layers.
  5. Sanitize and validate all environment variables used in shell commands, filenames, docker tags and aws commands. Enforce strict allow-lists/regexes for values used in image names, tags, file paths and CLI args to prevent injection or unexpected characters.
  6. Exclude sensitive files from the Docker context via .dockerignore (e.g., .env, local configs, credentials). Use multi-stage builds to ensure only runtime artifacts are copied into final image and avoid copying any files that may contain secrets (local prisma/.env, credentials).
  7. Scan built images and CI caches with vulnerabilities scanners and generate SBOMs. Use automated secret-detection during CI and enforce least-privilege for CI credentials (ECR, AWS). Rotate any secrets that might have been exposed and restrict access to build artifacts.

🔴 apps/api/src/tasks/automations/automations.controller.ts (HIGH Risk)

# Issue Risk Level
1 Missing ownership check for automationId (IDOR risk) HIGH
2 No DTO validation enforced in controller (unvalidated body) HIGH
3 Path params (taskId, automationId) not validated or sanitized HIGH
4 Query params (limit, offset) parsed without bounds or validation HIGH
5 User input passed directly to service methods — possible injection if services unsafe HIGH
6 Optional X-Organization-Id may allow operations without clear org context HIGH

Recommendations:

  1. Verify automation belongs to the given task before read/update/delete
  2. Enable request validation (Nest ValidationPipe + class-validator DTOs)
  3. Validate and sanitize path params and enforce formats/constraints
  4. Validate/limit pagination params (min/max) and handle parse errors
  5. Ensure org context enforced for API-key auth and restrict cross-org access

🔴 apps/api/src/tasks/automations/automations.service.ts (HIGH Risk)

# Issue Risk Level
1 Missing org ownership checks on findById, update, delete, listVersions HIGH
2 findByTaskId lacks org verification and may leak other orgs' automations HIGH
3 Mass-assignment: update uses updateAutomationDto directly allowing privileged fields change HIGH
4 Missing input validation for IDs and pagination params before DB use HIGH

Recommendations:

  1. Enforce organizationId ownership in all DB queries
  2. Require organizationId from auth context or params to scope queries
  3. Validate and sanitize DTOs; whitelist allowed update fields
  4. Validate ID formats (UUID) and limit/offset ranges before DB use
  5. Add authorization guards to verify user access per organization

🔴 apps/api/src/tasks/tasks.controller.ts (HIGH Risk)

# Issue Risk Level
1 Missing per-task authorization (getTask) — potential IDOR HIGH
2 taskId and organizationId forwarded to services without validation HIGH
3 Potential SQL injection if services use raw IDs in queries HIGH
4 Trusting X-Organization-Id header enables organization spoofing HIGH
5 No validation/sanitization of uploaded file metadata (name/type/content) HIGH
6 Returning raw signed download URLs may leak credentials HIGH

Recommendations:

  1. Enforce per-resource authorization: call tasksService.verifyTaskAccess (or equivalent) in the getTask endpoint before returning the task to prevent IDOR.
  2. Apply strict input validation for organizationId and taskId at the controller boundary (e.g., NestJS ValidationPipe + DTOs or regex/UUID checks). Reject or normalize invalid IDs early.
  3. Ensure all DB access in services uses parameterized queries / ORM query bindings. Do not interpolate raw req.params/req.body values into SQL.
  4. Do not rely solely on the X-Organization-Id header for authorizing the caller. Derive organization from the authenticated token/session or validate the header against the session's organization to prevent spoofing.
  5. Validate and sanitize uploaded file metadata: enforce allowed content-types, maximum file size, normalize/sanitize filenames (remove path chars, control chars), perform virus scanning and content-type verification (magic bytes).
  6. Avoid returning raw long-lived signed URLs. Generate short-lived signed URLs, embed expiration metadata, and consider streaming/proxying downloads through the backend when sensitive credentials might be exposed.
  7. Add centralized input validation and sanitization utilities used by services, and log and monitor invalid input attempts for anomaly detection.
  8. Review service implementations (TasksService, AttachmentsService) to confirm they do not execute raw SQL/OS commands with user input. If they do, refactor to safe APIs and add tests to cover injection attempts.

🟡 apps/api/src/tasks/tasks.service.ts (MEDIUM Risk)

# Issue Risk Level
1 Missing input validation for organizationId and taskId before DB queries MEDIUM
2 Unsanitized parameters used directly in db.find* queries (potential injection) MEDIUM
3 Insufficient authorization: no user identity check; only orgId is validated MEDIUM
4 getTask returns full DB entity including assignee, may expose sensitive fields MEDIUM
5 Error logs with console.error may leak sensitive info MEDIUM

Recommendations:

  1. Validate and enforce types for organizationId and taskId at the entrypoint (e.g., use class-validator DTOs and validate UUID format) before calling service methods.
  2. Even when using an ORM, validate input shape/length and whitelist allowed characters/IDs; avoid passing unchecked user-supplied IDs directly into DB lookups. Add explicit parsing/normalization and reject invalid IDs early.
  3. Enforce authorization tied to the authenticated user: derive organizationId from the authenticated user/session or additionally verify the requester belongs to the organization (e.g., check user.organizationId or membership table). Do not rely solely on a caller-supplied organizationId parameter.
  4. Map DB results to explicit DTOs before returning (as done in getTasks). For getTask, return a DTO that omits sensitive assignee fields or explicitly select only the allowed fields in the DB query (use select with explicit columns rather than include *).
  5. Avoid logging raw error objects or stack traces in production. Use structured logging at appropriate levels and redact sensitive information. Replace console.error calls with a logger that supports redaction and environment-based verbosity.
  6. Add unit/integration tests to ensure unauthorized users cannot access tasks belonging to other organizations, and to assert that returned objects do not contain unexpected fields.

🟡 apps/app/next.config.ts (MEDIUM Risk)

# Issue Risk Level
1 Images remotePatterns allow any hostname (hostname '**') MEDIUM
2 assetPrefix trusts STATIC_ASSETS_URL env var without validation MEDIUM
3 serverActions.allowedOrigins can be undefined or misconfigured via env MEDIUM
4 Rewrites proxy /ingest/* to PostHog, risking unintended data exfiltration MEDIUM

Recommendations:

  1. Images remotePatterns: replace hostname '**' with an explicit allowlist of trusted image hostnames or use stricter matching (e.g., specific domains or subdomain patterns). Review how Next.js image proxying is used server-side to determine SSRF risk and add network egress controls where appropriate.
  2. assetPrefix: validate and canonicalize STATIC_ASSETS_URL at startup (ensure allowed scheme, host, and no embedded credentials). Prefer storing a pre-validated canonical URL in deployment config rather than using raw env input. Add Content Security Policy (CSP) rules limiting where assets can be loaded from.
  3. serverActions.allowedOrigins: set an explicit, non-empty allowlist in production and define a safe default in non-production (do not rely on undefined meaning 'safe'). Validate NEXT_PUBLIC_PORTAL_URL at startup and fail-fast on invalid or unexpected values.
  4. Rewrites to PostHog: audit the proxied endpoints to ensure only intended data is forwarded. Limit which routes/HTTP methods are proxied, remove any endpoints that could forward sensitive user data, add logging and rate-limiting, and verify GDPR/PII compliance for forwarded payloads.

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

# Issue Risk Level
1 Unvalidated orgId used directly in DB queries HIGH
2 Missing authorization: member not enforced before data fetch HIGH
3 getControlTasks cached globally while reading request headers HIGH
4 Cached tasks can leak one user's data to others HIGH

Recommendations:

  1. Validate and sanitize orgId (e.g., require and assert UUID format) before using it in DB queries. Use a validation library (zod, Joi, or validator.isUUID) and fail early if invalid.
  2. Enforce authorization before fetching org-scoped data: verify session.user is a member of organizationId (and has required role/permissions) and refuse/redirect if not. Move the member check higher and gate all org queries on it.
  3. Avoid using react's cache() for functions that read request-scoped data (headers/session). Either remove cache() or make the cached function accept organizationId/session as an explicit parameter and include that in the cache key.
  4. Do not call headers()/session inside a globally cached function. Instead, pass the validated organizationId (or session user id) into getControlTasks so cached results are scoped to the user/org.
  5. Scope DB queries by both organizationId and user/role where appropriate (least privilege). For example, when fetching frameworks or tasks, include checks that the requesting user is permitted to view them.
  6. Consider centralizing auth/authorization (middleware or server-side guard) so route params are validated and membership enforced before any data access occurs.

🔴 apps/app/src/app/(app)/[orgId]/people/[employeeId]/page.tsx (HIGH Risk)

# Issue Risk Level
1 Missing validation of route params (employeeId, orgId) HIGH
2 Inconsistent org scoping between route param and session org HIGH
3 IDOR: training videos fetched without verifying member org HIGH
4 Authorization check uses route orgId for canEditMembers HIGH
5 Logs include member email/ID (PII exposure) HIGH
6 Error logs may leak internal error details HIGH
7 Fleet label used in URL without sanitization HIGH

Recommendations:

  1. Validate and sanitize route params (employeeId, orgId) at the boundary. Ensure they match expected formats (UUIDs or numeric IDs) before use.
  2. Use a single source of truth for organization scoping. Compare route orgId to session?.session.activeOrganizationId and reject or canonicalize if they do not match, or derive orgId exclusively from the session.
  3. When querying data tied to a member (e.g., employeeTrainingVideoCompletion), include organization scoping (join or filter by member.organizationId/session org) so a user cannot fetch another organization's member data by changing the employeeId.
  4. Compute authorization (canEditMembers) using the session-scoped organization (or verify the route orgId belongs to the session org) rather than trusting the route param.
  5. Remove or redact PII from logs. Avoid logging member.email and full member IDs; use truncated IDs or internal non-PII identifiers when logging.
  6. Avoid logging raw error objects. Log structured errors with safe fields and a reference/error id for debugging; capture full errors in secure internal logs only.
  7. Sanitize values inserted into external request URLs (e.g., fleetDmLabelId) and validate the value shape before interpolation. Treat DB-sourced fields that may be controlled or modified indirectly as untrusted input.
  8. Add automated tests that attempt cross-organization access (IDOR scenarios) for key endpoints and UI flows.

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

# Issue Risk Level
1 No server-side auth check for removeMember/revokeInvitation actions MEDIUM
2 Exposes full user objects to client (potential data leakage) MEDIUM
3 Role parsing from comma string without validation or normalization MEDIUM

Recommendations:

  1. Enforce authorization inside removeMember and revokeInvitation actions
  2. Return only non-sensitive user fields to the client
  3. Validate/normalize roles or use typed enums for role checks
  4. Verify organizationId belongs to session user before queries
  5. Add server-side input validation and logging for critical actions

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

# Issue Risk Level
1 No caller authentication on server actions (privilege escalation risk) HIGH
2 RevalidatePath uses untrusted headers (x-pathname/referer) enabling path injection HIGH
3 Logs full request URL (console.log) may leak sensitive info HIGH
4 NEXT_PUBLIC_ENTERPRISE_API_URL used for internal API URL (exposed clientside) HIGH
5 No input validation for uploaded scripts or params (stored XSS or RCE downstream) HIGH
6 getAutomationRunStatus uses literal '${runId}' (template bug, wrong endpoint) HIGH
7 Enterprise API error messages returned to clients (information disclosure) HIGH
8 No fetch timeouts or rate limiting (DoS/resource exhaustion) HIGH

Recommendations:

  1. Add per-request authentication and authorization checks in each server action (verify user session, org membership and permissions for the requested orgId/taskId/automationId). Do not assume server-only actions are implicitly authorized.
  2. Sanitize and validate values used for revalidatePath. Do not rely on client-controllable headers (x-pathname or Referer). Restrict to an allowlist of known routes or derive the path server-side from route params.
  3. Remove or redact logging of full request URLs. Avoid logging query strings or any secrets. If logging is required, mask sensitive query params before emitting logs.
  4. Do not use NEXT_PUBLIC_* env vars for internal endpoints. Use server-only env vars (no NEXT_PUBLIC prefix) for internal API URLs so they are not exposed to client bundles.
  5. Validate and sanitize uploaded script content and all parameters before sending to downstream systems. Apply content scanning, size limits, and enforce an allowlist of safe characters or AST-level validation where appropriate. Consider sandboxing script execution downstream and applying CSP for any script content rendered to users.
  6. Fix the endpoint string in getAutomationRunStatus to interpolate runId correctly (use template literal: /api/tasks-automations/runs/${runId}) or pass the runId as part of the path-building logic in callEnterpriseApi.
  7. Do not return raw upstream error messages to clients. Log full errors server-side but return generic, user-friendly messages to callers. Consider mapping upstream HTTP status codes to sanitized messages and only expose safe details to authorized admin users.
  8. Apply timeouts to fetch calls (use AbortController or a fetch with timeout) and implement rate limiting / concurrency limits for these server actions to mitigate DoS and resource exhaustion risks.

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

# Issue Risk Level
1 Unsanitized user input sent to sendMessage/validateAndSubmitMessage MEDIUM
2 Unvalidated IDs (orgId/taskId/automationId) passed to handlers/components MEDIUM

Recommendations:

  1. Treat all chat input as untrusted. Perform server-side validation and sanitization of message content before any processing, storage, or forwarding. Enforce length limits, reject disallowed control characters, and normalize whitespace.
  2. Ensure output encoding/escaping on render. Audit the Message component and any downstream renderers to confirm they do not use dangerouslySetInnerHTML or otherwise insert raw HTML. Use React escaping or a vetted sanitizer (e.g., DOMPurify) if rich content must be allowed.
  3. Verify the implementation of validateAndSubmitMessage and sendMessage to ensure they do not evaluate or execute user-provided content (no eval, no shell/command execution, no template evaluation).
  4. Enforce server-side authorization checks on orgId, taskId, and automationId. Do not rely solely on client-provided IDs — validate that the authenticated user has access to the referenced org/task/automation before returning or mutating data.
  5. Apply input validation on IDs (format, allowed character set, length) both client- and server-side to reduce risk of injection or misuse. Prefer opaque identifiers (UUIDs) and verify them server-side.
  6. Add rate limiting and logging for message submissions to detect abuse and mitigate automated attacks or flooding.
  7. Add Content Security Policy (CSP) headers and other output-hardening (e.g., HTTP-only secure cookies, sameSite) to limit impact of any XSS that might exist.
  8. Perform a code audit of related hooks and components (useChatHandlers, Message, useChat/sendMessage, and any server endpoints they call) to confirm where sanitization/validation occurs and whether it is sufficient.

💡 Recommendations

View 3 recommendation(s)
  1. Eliminate SQL injection and race in versioning: stop interpolating request fields into SQL. Use parameterized queries or Prisma/ORM bindings and compute next version inside a DB transaction or with an atomic DB-side sequence/SELECT ... FOR UPDATE to avoid race conditions.
  2. Validate and sanitize all IDs at the controller boundary (orgId, taskId, automationId, version). Enforce strict types/regex (e.g. UUID checks) via DTOs + Nest ValidationPipe so only normalized values reach services, and reject malformed input early.
  3. Namespace and derive storage/Redis keys server-side from validated orgId/automationId (e.g. org:{orgId}:automation:{automationId}:...). Do not accept full keys from clients or use raw IDs directly when reading/writing keys; validate key components before use.

Powered by Comp AI - AI that handles compliance for you. Reviewed Oct 15, 2025

@CLAassistant
Copy link

CLAassistant commented Oct 14, 2025

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ Marfuen
❌ github-actions[bot]
You have signed the CLA already but the status is still pending? Let us recheck it.

@vercel
Copy link

vercel bot commented Oct 14, 2025

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

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
app (staging) Skipped Skipped Oct 15, 2025 3:52pm
portal (staging) Skipped Skipped Oct 15, 2025 3:52pm

@vercel vercel bot temporarily deployed to staging – portal October 14, 2025 14:48 Inactive
@vercel vercel bot temporarily deployed to staging – app October 14, 2025 14:48 Inactive
* chore: fix api script

* chore(api): update bun install command to handle installation failures
@vercel vercel bot temporarily deployed to staging – portal October 14, 2025 17:22 Inactive
@vercel vercel bot temporarily deployed to staging – app October 14, 2025 17:22 Inactive
@vercel vercel bot temporarily deployed to staging – app October 14, 2025 17:29 Inactive
@vercel vercel bot temporarily deployed to staging – portal October 14, 2025 17:29 Inactive
… DTOs (#1655)

Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
* chore(api): update Dockerfile to install production dependencies inside image
@vercel vercel bot temporarily deployed to staging – portal October 14, 2025 20:14 Inactive
@vercel vercel bot temporarily deployed to staging – app October 14, 2025 20:14 Inactive
@vercel vercel bot temporarily deployed to staging – portal October 14, 2025 20:19 Inactive
@comp-ai-code-review
Copy link

comp-ai-code-review bot commented Oct 14, 2025

🔒 Comp AI - Security Review

🔴 Risk Level: HIGH

No OSV CVEs found in npm scan. Code contains injection/IDOR issues: unsanitized route/query params, DB queries lacking org ownership checks, and unvalidated keys used for Redis/S3/URLs.


📦 Dependency Vulnerabilities

✅ No known vulnerabilities detected in dependencies.


🛡️ Code Security Analysis

View 12 file(s) with issues

🔴 ENTERPRISE_API_AUTOMATION_VERSIONING.md (HIGH Risk)

# Issue Risk Level
1 Missing input validation for orgId/taskId/automationId HIGH
2 Unvalidated S3 keys enable object access/overwrite across orgs HIGH
3 Potential SQL injection if DB queries use raw inputs HIGH
4 Missing authorization checks may allow cross-org IDOR HIGH
5 Version parameter not validated (non-integer or out of range) HIGH
6 Race condition when generating next version causing duplicate versions HIGH
7 Unsanitized automationId used in Redis key can leak chat data HIGH

Recommendations:

  1. Perform strict server-side validation and canonicalization of orgId, taskId, automationId and version. Reject malformed IDs (use regex/UUID checks) and coerce/sanitize version to an integer with range checks.
  2. Enforce authorization/ownership checks on every request: ensure the authenticated principal has rights to the org/task/automation before any S3, DB, or Redis operations.
  3. When querying the DB, use parameterized queries or an ORM; avoid concatenating raw request values. Add a UNIQUE constraint on (automationId, version) and perform version creation inside a transaction or use a DB-side sequence to avoid races.
  4. Mitigate S3 risks by validating source/destination key prefixes server-side, restricting copy operations to expected prefixes, and using least-privilege IAM roles scoped to approved prefixes. Never allow client-supplied keys to be used verbatim.
  5. Validate and canonicalize Redis keys server-side. Namespace keys by org and enforce access checks before returning or modifying chat data. Avoid using raw IDs directly in keys without validation.
  6. Add server-side checks for the publish flow: compute next version server-side (never accept from client), and use DB transaction/locking or optimistic concurrency control to prevent duplicate versions. Consider returning 409 on version conflict.
  7. Add comprehensive logging, monitoring, and alerts for S3 copy failures, unauthorized access attempts, and versioning conflicts. Include tests for negative cases (invalid IDs, no draft present, out-of-range version).
  8. Return appropriate HTTP status codes (400, 401/403, 404, 409, 500) and avoid leaking implementation details in error messages. Rate-limit endpoints to reduce abuse.

🔴 apps/api/Dockerfile (HIGH Risk)

# Issue Risk Level
1 Remote install script piped to bash (curl bash)
2 Dependencies installed without lockfile present HIGH
3 COPY . after install may overwrite installed deps (node_modules) HIGH

Recommendations:

  1. Avoid piping remote install scripts directly into a shell. Download the installer, verify its signature/checksum, inspect the contents, then run locally or use an officially published versioned installer binary. Prefer pinned installer versions.
  2. Include and COPY the package manager lockfile(s) into the image before running dependency installation (e.g., COPY bun.lockb ./ or package-lock.json ./) and use the package manager's frozen/lockfile-only install option so builds are reproducible.
  3. Add a .dockerignore in the same build context as the Dockerfile (apps/api/.dockerignore) to exclude node_modules and other large/sensitive files, or ensure you run docker build with the repository root as context so the existing root .dockerignore is applied.
  4. Consider building dependencies and the application in CI or a separate builder stage (multi-stage Docker build) and copying only the production artifacts into the final image to avoid installing third-party tools at runtime.
  5. If you must run remote installers in the Dockerfile, pin the installer URL to a specific, versioned release and verify checksums. For bun specifically, prefer using a fixed bun release or a preinstalled bun in your base image.

🔴 apps/api/src/tasks/automations/automations.controller.ts (HIGH Risk)

# Issue Risk Level
1 IDOR: automationId not verified against taskId HIGH
2 Route params passed to services without sanitization HIGH
3 Limit/offset query params parsed but not validated HIGH
4 createAutomation ignores request body DTO HIGH
5 No controller-level enforcement of DTO validation HIGH

Recommendations:

  1. Verify automation belongs to taskId before read/update/delete
  2. Sanitize and validate route params before passing to services
  3. Use ValidationPipe and class-validator for DTOs
  4. Validate limit/offset as positive ints with sensible max
  5. Enforce organization ownership checks when loading automation records

🔴 apps/api/src/tasks/automations/automations.service.ts (HIGH Risk)

# Issue Risk Level
1 IDOR: endpoints (findById, update, delete, listVersions, findByTaskId) lack organization ownership checks and can exp... HIGH

Recommendations:

  1. Require organizationId from authenticated user context and include it in WHERE clauses for every query that returns or modifies a resource (e.g., where: { id: automationId, task: { organizationId } } or where: { id: automationId, organizationId }).
  2. Add authorization guards/middlewares that verify the authenticated user's membership/role in the organization before allowing access to automations or versions.
  3. For endpoints that take taskId/automationId, validate the resource belongs to the requester’s organization before returning or modifying data (use db lookups that include organizationId in the predicate).
  4. Whitelist updatable fields in update() and do not pass the DTO directly to the DB update. Map allowed fields explicitly: data: { name: dto.name, description: dto.description }.
  5. Add DTO validation (class-validator) to ensure IDs, limit, offset, and other params meet expected formats and bounds, and enforce sensible pagination limits (max limit).
  6. Treat numeric pagination params carefully: coerce/validate limit and offset before using them in take/skip (avoid passing undefined/invalid values).
  7. Log authorization failures and return 403 when a user is authenticated but not authorized to access a resource.

🔴 apps/api/src/tasks/tasks.controller.ts (HIGH Risk)

# Issue Risk Level
1 No input validation on taskId route params HIGH
2 Missing access check on getTasks/getTask endpoints HIGH
3 OrganizationId header can be spoofed if not verified HIGH
4 Upload endpoint lacks file type/size/content validation HIGH
5 Potential SQL injection if services use unsanitized inputs HIGH
6 Truncated uploadTaskAttachment may break auth/logic handling HIGH
7 No explicit file virus scanning or content inspection HIGH

Recommendations:

  1. Validate and sanitize route params with DTOs/class-validator
  2. Enforce verifyTaskAccess for all task read endpoints
  3. Bind OrganizationId to authenticated context; don't trust header alone
  4. Validate MIME, size, and scan uploads for malware
  5. Use parameterized queries/ORM and avoid concatenated SQL

🟡 apps/api/src/tasks/tasks.service.ts (MEDIUM Risk)

# Issue Risk Level
1 Missing input validation: organizationId/taskId used directly in DB queries MEDIUM
2 Direct user inputs in DB queries (ORM mitigates SQLi but inputs unvalidated) MEDIUM
3 Potential auth bypass if orgId comes from client-controlled input MEDIUM
4 getTask returns raw task including assignee — may leak sensitive fields MEDIUM
5 Error logging prints raw error details to console (info leak) MEDIUM
6 No pagination on getTasks allows large data retrieval MEDIUM

Recommendations:

  1. Validate and sanitize organizationId and taskId at the API boundary (e.g., require UUID format, length checks). Use validation libraries (class-validator / Joi / zod) for controller DTOs so only valid IDs reach the service.
  2. Enforce server-side authorization using the authenticated user context (derive organizationId from the logged-in user's session/claims or check membership) instead of trusting client-supplied orgId.
  3. Never return raw ORM entities directly. Map entities to response DTOs and explicitly select/omit fields. For getTask, explicitly select assignee fields needed (e.g., id, name) rather than include: true, or use a TaskResponseDto.
  4. Avoid logging full error objects to console in production. Log minimal contextual info and use structured logging/centralized error reporting (Sentry, Datadog) with sensitive-data redaction.
  5. Add pagination parameters (limit/offset or cursor-based) and enforce maximum page sizes for getTasks. Apply rate limiting on list endpoints to mitigate large data extraction.
  6. Ensure DB queries use parameterized/ORM APIs (they do here) but do not rely on ORM alone — combine with input validation and access checks.
  7. Add unit/integration tests covering authorization (attempt access with an orgId the user does not belong to) and input validation failure cases.

🟡 apps/app/next.config.ts (MEDIUM Risk)

# Issue Risk Level
1 Open image host pattern: images.remotePatterns hostname='**' MEDIUM
2 .md files imported as raw without sanitization -> XSS risk MEDIUM
3 serverActions.allowedOrigins undefined in non-production -> unrestricted origins MEDIUM
4 Rewrites proxy to PostHog may leak sensitive data to external analytics MEDIUM

Recommendations:

  1. Restrict images.remotePatterns to a short allowlist of trusted hostnames (or remove wildcard '**'). If dynamic hosts are required, validate/whitelist them at runtime before use. Consider disabling remote image optimization for untrusted domains.
  2. Treat imported .md/raw content as untrusted. Before rendering markdown, pass it through a sanitizer (e.g., rehype-sanitize, DOMPurify) or render with a markdown pipeline that explicitly strips/escapes dangerous HTML. Avoid using raw HTML injection (dangerouslySetInnerHTML) without sanitization.
  3. Set explicit serverActions.allowedOrigins for non-production environments as well, or deny by default. Do not rely on undefined to restrict origins — make the policy explicit (empty array to deny, or a concrete allowlist) to avoid accidental open origins in staging/dev environments.
  4. Audit what user data is proxied to PostHog via the /ingest rewrites. Strip or hash PII and sensitive fields before forwarding. Consider self-hosting analytics or proxying only non-sensitive telemetry, and document the data flows and retention/consent behavior.
  5. Validate environment-provided URLs (STATIC_ASSETS_URL, NEXT_PUBLIC_PORTAL_URL, etc.) before using them (ensure protocol, hostname, no embedded credentials). Consider runtime checks and logging for unexpected values.

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

# Issue Risk Level
1 No validation of orgId param before database queries HIGH
2 No authorization check to ensure session user is member of org HIGH
3 getControlTasks uses react cache without request key HIGH
4 Cached getControlTasks reads headers/session leading to data leak HIGH
5 Session-scoped data (activeOrganizationId) used in global cache HIGH

Recommendations:

  1. Validate and sanitize the orgId param before using it in DB queries (e.g., enforce UUID format or allowed ID pattern). Return 400 on invalid IDs.
  2. Enforce authorization: after loading session, verify the session.user is a member (and has appropriate role/permissions) of organizationId. If not authorized, return 403 or redirect and log the attempt.
  3. Do not use react cache() for request-scoped/session-scoped lookups that call headers(). Either remove cache() or make the cached function accept an explicit organizationId/session identifier and include that as the cache key.
  4. Refactor getControlTasks to accept organizationId as an argument (derived from the validated/authorized session) instead of calling headers()/auth inside the cached function. This prevents cross-request/session data leakage.
  5. If caching per-organization is desired, ensure the cache key is derived from organizationId (and/or user) so cached entries cannot be shared across organizations or users.
  6. Add logging and monitoring for unauthorized access attempts and anomalous cache hits to detect potential data leaks.

🟡 apps/app/src/app/(app)/[orgId]/people/[employeeId]/page.tsx (MEDIUM Risk)

# Issue Risk Level
1 No validation of route params (employeeId, orgId) before DB use MEDIUM
2 Role check uses .includes without null check; may throw runtime error MEDIUM
3 Role check uses substring .includes allowing privilege escalation MEDIUM
4 Detailed fleet API errors and stack traces are logged MEDIUM
5 Logging user email to console (PII exposure) MEDIUM

Recommendations:

  1. Validate and canonicalize route params (employeeId, orgId) before using them in DB queries. Enforce expected shapes/types (e.g., UUID checks or numeric IDs) and return 400/404 for invalid values. Example: use Zod or Joi at the entry point (or Next.js route handlers) to parse params.
  2. Null-check the role before calling methods on it. Prefer safe lookups like: const role = currentUserMember?.role ?? null; if (role) { ... }
  3. Avoid substring matching for authorization. Normalize roles as a discrete enum/union (e.g., 'owner' | 'admin' | 'member') and use exact equality or membership in a canonical list: const canEditMembers = ['owner','admin'].includes(role); If the DB stores multiple roles in a string, use a well-defined structure (array) instead.
  4. Do not log full error objects or stack traces to console in production. Log minimal, non-sensitive context (e.g., error ID) and capture full details in a controlled error-tracking system (Sentry) with restricted access. For the fleet API call, log only that the call failed and an internal error id or sanitized message.
  5. Remove or redact PII (emails, full names) from logs. If you must log user identifiers, use internal IDs or hashed/anonymized values. Example: console.log(No fleet label for member id=${member.id}) instead of logging member.user?.email.
  6. Add defensive checks and early returns: ensure orgId/employeeId exist and belong to the current session's organization before performing sensitive operations. Where redirect() is used, validate the params first.
  7. Consider centralizing auth/role checks into a helper so role semantics are enforced consistently and audited easily.
  8. If using an ORM (e.g., Prisma), continue to rely on parameterized queries for SQL injection protection but still validate inputs for type and business logic correctness.

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

# Issue Risk Level
1 Client-side auth only; remove/revoke actions exposed to client MEDIUM

Recommendations:

  1. Enforce server-side authorization and permission checks inside removeMember and revokeInvitation actions (do not rely on client-side canManageMembers). Return 403/401 when the caller is not authorized.
  2. Ensure removeMember/revokeInvitation validate the caller's session, organizationId, and membership/role before performing DB mutations, and fail closed if session is missing or malformed.
  3. Add server-side logging/auditing for member removals and invitation revocations (who performed the action, target, timestamp) for forensic and non-repudiation purposes.
  4. Do not assume that hiding UI controls (canManageMembers) prevents calls — treat any action reaching server as potentially coming from a malicious client and validate/authorize accordingly.
  5. Consider limiting which server actions are serialized to the client; if an action must be used only by admins, perform a server-side gate before returning any callable reference.

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

# Issue Risk Level
1 No per-request authorization before forwarding calls to enterprise API HIGH
2 User inputs forwarded to enterprise API without validation or sanitization HIGH
3 Logging URLs may leak sensitive query params to logs HIGH
4 Referer/x-pathname header used unvalidated in revalidatePath HIGH
5 Enterprise API error messages are returned to callers exposing internals HIGH
6 Insecure default API URL (http localhost) and public NEXT_PUBLIC env usage HIGH

Recommendations:

  1. Enforce per-request authentication and authorization (RBAC) before calling the enterprise API. Verify the current user/org/task/automation context server-side (e.g., validate session, check membership/permissions) for every server action that forwards requests.
  2. Validate and sanitize all inputs before forwarding to the enterprise API. Apply schema validation (e.g., zod/joi/ts-validators) for params and bodies (orgId, taskId, automationId, runId, script content, messages) and reject or canonicalize unexpected values.
  3. Remove or redact sensitive data from logs. Replace console.log('url', url.toString()) with logging that omits query params or redacts known secrets/keys, and avoid logging full request payloads in production.
  4. Do not use untrusted headers directly for revalidatePath. Parse and validate the header value, ensure it is a relative path within allowed routes (starts with '/', no protocol/host), and canonicalize it. Prefer deriving the path server-side from trusted context rather than client-sent headers.
  5. Do not return raw enterprise API error messages to callers. Return generic client-facing errors and log full details server-side. Strip stack traces and internal messages from responses sent to clients.
  6. Require a secure enterprise API configuration: remove insecure defaults (do not default to http://localhost:3006 in production), require HTTPS endpoints, and avoid using NEXT_PUBLIC_* for sensitive endpoints or secrets. Use server-only env variables (no NEXT_PUBLIC) for secrets and internal URLs.
  7. Add strict error handling around callEnterpriseApi responses: validate response shape before trusting result.success/data, and ensure the code never treats untrusted data as a success indicator without checks.
  8. Fix minor implementation issues that increase risk: e.g., the getAutomationRunStatus endpoint uses a non-interpolated string '/api/tasks-automations/runs/${runId}' — ensure proper URL building and that path params are passed safely (prefer URL constructor with query or path segments validated).

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

# Issue Risk Level
1 Possible XSS: messages may be rendered unsanitized MEDIUM
2 User input may be forwarded to AI SDK without server-side validation MEDIUM
3 Sensitive secrets could be included in messages and leaked MEDIUM
4 Ephemeral 'new' automationId handled client-side without auth checks MEDIUM
5 No client-side abuse/rate-limiting for sendMessage MEDIUM

Recommendations:

  1. Escape or sanitize message content before rendering
  2. Validate and sanitize inputs on the server/API
  3. Detect and redact secrets from messages before sending
  4. Verify automationId and enforce server-side auth checks
  5. Implement rate limiting and abuse protection on the server

💡 Recommendations

View 3 recommendation(s)
  1. Validate and canonicalize all incoming identifiers at the controller boundary (orgId, taskId, automationId, runId, version, limit/offset). Reject malformed values (e.g., enforce UUID/regex or integer coercion) before any DB/Redis/S3 usage.
  2. Enforce organization ownership in every DB operation: include organizationId in WHERE predicates for reads/updates/deletes and map update payloads to an explicit whitelist of fields (do not pass DTOs directly to the ORM). Use parameterized/ORM queries and DB constraints (unique keys) to prevent injection and race-origin duplicates.
  3. Sanitize and namespace external keys (Redis, S3, URLs) server-side. Never compose keys/paths directly from raw request IDs — validate input, then construct keys using a safe canonical form (e.g., org:{orgId}:automation:{automationId}:chat) and validate any URL/path segments before use.

Powered by Comp AI - AI that handles compliance for you. Reviewed Oct 14, 2025

@vercel vercel bot temporarily deployed to staging – app October 14, 2025 20:19 Inactive
@vercel vercel bot temporarily deployed to staging – app October 14, 2025 20:35 Inactive
@vercel vercel bot temporarily deployed to staging – portal October 14, 2025 20:35 Inactive
* chore(api): generate Prisma client during Docker image build

* chore(api): update Dockerfile to set BUN_INSTALL environment variable
@vercel vercel bot temporarily deployed to staging – portal October 14, 2025 20:39 Inactive
@vercel vercel bot temporarily deployed to staging – app October 14, 2025 20:39 Inactive
* chore(api): replace bunx with npx for Prisma client generation
@vercel vercel bot temporarily deployed to staging – portal October 14, 2025 20:43 Inactive
@vercel vercel bot temporarily deployed to staging – app October 14, 2025 20:43 Inactive
* fix(automation): handle undefined createdAt in automation overview

* fix(chat): adjust padding in EmptyState and remove console log in AutomationOverview

* fix(automation): improve ephemeral state handling and update automation ID usage

* chore(automation): add success callback to automation settings dialogs

* fix(automation): update automation ID handling and improve message deduplication

---------

Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
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.

3 participants