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.

@comp-ai-code-review
Copy link

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

🔒 Comp AI - Security Review

🔴 Risk Level: HIGH

2 high CVEs in xlsx@0.18.5 and 1 low CVE in ai@5.0.0; missing org/auth checks and unvalidated IDs in getOrganizationControlProgress.ts and getTasks.ts.


📦 Dependency Vulnerabilities

🟠 NPM Packages (HIGH)

Risk Score: 8/10 | Summary: 2 high, 1 low CVEs found

Package Version CVE Severity CVSS Summary Fixed In
xlsx 0.18.5 GHSA-4r6h-8v6p-xvw6 HIGH N/A Prototype Pollution in sheetJS No fix yet
xlsx 0.18.5 GHSA-5pgg-2g8v-p4x9 HIGH N/A SheetJS Regular Expression Denial of Service (ReDoS) No fix yet
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 4 file(s) with issues

🔴 apps/api/Dockerfile (HIGH Risk)

# Issue Risk Level
1 Remote installer curl bash for bun allows remote code execution/supply-chain risk
2 Piping installer without verification prevents checksum/signature validation HIGH
3 COPY . . may embed secrets (env, keys) from build context into image HIGH
4 Copying host node_modules/@trycompai injects untrusted artifacts into image HIGH
5 bun install --production --ignore-scripts
6 npx prisma generate at build may require DB creds or leak schema or secrets HIGH
7 Running as root to install tools then switching may leave privileged leftovers HIGH

Recommendations:

  1. Do not pipe remote install scripts directly to a shell. Download the installer first, verify its checksum or signature, then execute locally. Prefer using a published release archive or distro package where integrity can be verified.
  2. Pin bun (and other tool) versions and verify integrity (checksums or GPG signatures) before executing. If the upstream provides signed releases, validate signatures.
  3. Add a .dockerignore that excludes sensitive files (e.g., .env, *.pem, .secrets, .aws/, .git/) to avoid embedding secrets via COPY . .
  4. Use a multi-stage build: perform installs and builds in a builder stage, copy only the minimal runtime artifacts (dist, node_modules for production, generated prisma client) into a slim runtime stage. This avoids copying the whole build context or host node_modules into the final image.
  5. Avoid copying host node_modules into the image. Rebuild production dependencies inside the image (or in the builder stage) so artifacts come from a controlled build environment, not the developer machine.
  6. Remove the '|| true' that masks bun install errors so the build fails on dependency install problems. Fail-fast prevents shipping images with partial or broken installs.
  7. If prisma generate is required in image build, ensure the schema and any .env used do not contain secrets or database credentials. Prefer generating the Prisma client in a build stage that has controlled access to secrets, or generate it as part of CI and copy the generated client into the image without including .env files.
  8. Limit root-duration: perform required root-level package installs in a dedicated build stage and then switch to a non-root user in the final image. Ensure file ownerships and permissions are corrected and remove unnecessary privileged artifacts after install.
  9. Add healthcheck tooling without installing extra remote tools where possible (use builtin node tooling), or ensure any extra tools are installed from verified packages.
  10. Consider reproducible builds and scanning the final image for secrets (use trufflehog, git-secrets, or similar) as part of CI prior to publishing images.

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

# Issue Risk Level
1 curl bash installer allows remote code execution (supply-chain risk)
2 Running dependency scripts (bun run/build) can execute untrusted code HIGH
3 Unquoted env var expansions risk word-splitting/command injection HIGH
4 Echoing environment variables may leak secrets in build logs HIGH
5 Inline build cache may leak image layer metadata HIGH
6 Cached node_modules and bun cache can persist sensitive files across builds HIGH
7 Copying prisma into image may expose schema/migrations or secrets HIGH

Recommendations:

  1. Replace curl | bash installs with packaged installers or verified artifacts: install bun from distro packages or download a checksum/signature-verified tarball and verify the checksum/signature before executing.
  2. Minimize running install/build scripts from untrusted sources: use frozen lockfiles (you already try this), run dependency installation in an isolated environment, generate and verify an SBOM, and run SCA (software composition analysis) to detect malicious packages. Where possible use --ignore-scripts for installs during build and run trusted build steps separately.
  3. Quote all shell variable expansions and use safe shell idioms to avoid word-splitting and globbing (e.g. "$ECR_REPOSITORY_URI:$IMAGE_TAG", "${VAR}" everywhere). Validate/whitelist environment variable content before passing it to commands.
  4. Stop printing environment variables or potentially sensitive values to build logs. Remove or redact echos that include env content (e.g. avoid echoing "$APP_NAME" if it can be sensitive). Use your CI's secret-masking features for any required debug outputs.
  5. Avoid enabling BUILDKIT_INLINE_CACHE unless necessary. If you must use it, ensure the target registry is private and you understand the metadata that may be exposed. Consider removing the build-arg or use other caching strategies that do not export layer metadata.
  6. Limit caching to safe artifacts and periodically rotate/clear caches. Do not cache node_modules or other runtime artifacts that may contain credentials or secrets uploaded inadvertently. Run a cache-purge step that removes any sensitive artifacts before saving caches.
  7. Do not copy application configuration or environment files into the image build context. Audit the prisma/ directory for any secrets, remove migrations/schema files that shouldn't be in production container, or mount runtime-only files at runtime. Use a .dockerignore and verify the Docker build context does not include sensitive files. Also review the Dockerfile for any added exposures.

🔴 apps/app/src/app/(app)/[orgId]/controls/[controlId]/data/getOrganizationControlProgress.ts (HIGH Risk)

# Issue Risk Level
1 Missing org ownership check: control accessible without verifying orgId HIGH
2 Unvalidated controlId used directly in DB query (possible injection/logic issue) HIGH

Recommendations:

  1. Enforce ownership at the DB query level: include orgId in the where clause, e.g. where: { id: controlId, orgId: orgId } so only controls belonging to the session's organization can be fetched.
  2. After fetching, explicitly verify control.orgId === orgId before returning any data (defense in depth). Return 403 or a generic 404 to avoid leaking existence.
  3. Validate the controlId format (e.g., ensure it's a UUID) before use to catch malformed IDs early and reduce attack surface.
  4. Rely on the ORM's parameterized queries to avoid SQL injection, but do not assume this removes authorization/IDOR risks — implement proper access checks.
  5. Return minimal error information for unauthorized or not-found cases (avoid revealing whether the control exists or belongs to another org).
  6. Add audit/logging for failed access attempts to detect potential enumeration or unauthorized access attempts.

🔴 apps/app/src/app/(app)/[orgId]/frameworks/lib/getTasks.ts (HIGH Risk)

# Issue Risk Level
1 Unvalidated organizationId used directly in DB query HIGH
2 No authorization checks before returning organization tasks HIGH
3 Full task objects returned may expose sensitive fields HIGH
4 Cached results could leak data between callers if keys insufficient HIGH

Recommendations:

  1. Validate and sanitize organizationId: enforce expected type/format (e.g., UUID regex), length checks, and whitelist where applicable before using it in queries.
  2. Enforce authorization: verify the caller/user has access to the requested organization (check auth context / session / user->organization membership) before loading or returning tasks.
  3. Return only necessary fields: use a projection/select on the DB query (e.g., select or selectMany) to avoid returning sensitive fields (audit logs, internal flags, PII).
  4. Make cache keys include auth context or per-user scoping: include caller identity or tenancy info in the cache key, or avoid caching data that varies by caller/authorization.
  5. Keep using parameterized ORM queries and avoid building raw SQL strings. If raw queries are needed, use the ORM/raw query parameter binding APIs.

💡 Recommendations

View 3 recommendation(s)
  1. Upgrade the vulnerable npm packages: update xlsx from 0.18.5 to a patched release and update ai to >=5.0.52 (adjust package.json and rebuild lockfile), then re-run the OSV/SCA scan to confirm remediation.
  2. In apps/app/src/app/(app)/[orgId]/controls/data/getOrganizationControlProgress.ts, validate controlId (e.g., ensure UUID format) and enforce ownership in the DB query: include orgId in the where clause (e.g., where: { id: controlId, orgId }) and return 403/404 when not authorized.
  3. In apps/app/src/app/(app)/[orgId]/frameworks/lib/getTasks.ts, validate/sanitize organizationId before use, enforce authorization before querying, and restrict the SELECT/projection to only the fields needed (avoid returning full task objects). Ensure any caching keys include tenancy/user scope.

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

@vercel
Copy link

vercel bot commented Nov 18, 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 Nov 18, 2025 4:22pm
portal (staging) Skipped Skipped Nov 18, 2025 4:22pm

…1770)

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

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

🔒 Comp AI - Security Review

🔴 Risk Level: HIGH

OSV: xlsx@0.18.5 has two HIGH issues (Prototype Pollution, ReDoS). ai@5.0.0 has a LOW filetype-whitelist bypass. Code: IDOR/validation issues in getOrganizationControlProgress, unsanitized orgId in getTasks, unencoded taskId in TasksByCategory.


📦 Dependency Vulnerabilities

🟠 NPM Packages (HIGH)

Risk Score: 8/10 | Summary: 2 high, 1 low CVEs found

Package Version CVE Severity CVSS Summary Fixed In
xlsx 0.18.5 GHSA-4r6h-8v6p-xvw6 HIGH N/A Prototype Pollution in sheetJS No fix yet
xlsx 0.18.5 GHSA-5pgg-2g8v-p4x9 HIGH N/A SheetJS Regular Expression Denial of Service (ReDoS) No fix yet
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 5 file(s) with issues

🔴 apps/api/Dockerfile (HIGH Risk)

# Issue Risk Level
1 Unverified remote installer: curl bash from https://bun.sh
2 Build-time remote code execution via npx prisma generate as root HIGH
3 Base image not pinned to a digest (node:20-alpine mutable) HIGH
4 Masking install failures with '
5 Copying host node_modules into image can introduce unverified code HIGH
6 Runtime image includes curl/wget/bash increasing attack surface HIGH

Recommendations:

  1. Avoid piping remote installers directly into a shell. Download the installer, verify checksums or signatures, and run the verified archive. Prefer distribution packages or vendor-provided verified installs.
  2. Pin the base image to an immutable digest (e.g., node:20-alpine@sha256:...) to prevent supply-chain changes from altering runtime contents.
  3. Do codegen (npx prisma generate) and any build/install steps in a separate build stage as a non-root user. Use a multi-stage build so generated artifacts are copied into a minimal runtime image and no build tools or root-time execs remain.
  4. Remove the '|| true' that masks install failures. Let builds fail on install errors so problems are visible and can be investigated.
  5. Avoid copying host node_modules into the image. Instead, build dependencies inside a controlled build stage using lockfiles (package-lock.json / bun.lockb) and verify integrity. If you must copy vendor packages, verify their provenance and integrity.
  6. Minimize runtime image attack surface: remove curl/wget/bash and other build utilities from the final image. Install only the packages required at runtime or use a separate final stage based on a smaller image.
  7. Run as non-root as early as possible (create and switch to a non-root user in the build stage where feasible) and ensure file ownerships are correct without giving unnecessary privileges.
  8. Fail the build on unexpected changes: enable reproducible installs via lockfiles and verify dependency integrity (e.g., use npm ci / bun with lock file validation).

🟡 apps/api/buildspec.yml (MEDIUM Risk)

# Issue Risk Level
1 Unverified remote install (curl bash from bun.sh): RCE / supply-chain risk
2 Build logs echo env vars and directory listings, leaking sensitive data MEDIUM
3 Cached paths (/root/.bun, node_modules) may store secrets in build cache MEDIUM
4 Copying package manifests and source into docker context can bake secrets into image MEDIUM
5 Installing dependencies from registry without pinning risks supply-chain tampering MEDIUM
6 Docker build cache/layers may retain secrets if not cleaned or multi-stage MEDIUM

Recommendations:

  1. Replace curl | bash installer with a verified installer: download the installer, verify a published checksum/signature, or use an official packaged binary from a trusted package manager. Prefer pinned, vendor-supplied binaries where possible.
  2. Avoid printing environment variables and directory listings in CI logs. Remove or redact lines like echo "APP_NAME is set to $APP_NAME" and ls -la output. Use CI log masking features for secrets.
  3. Exclude caches that can contain secrets where possible. Do not cache node_modules or tool caches that may contain credentials unless necessary; if caching, ensure caches are scoped, encrypted, and rotated. Clear caches that may hold ephemeral secrets between builds.
  4. Do not copy files that may contain secrets into the Docker build context (or ensure they contain no secrets). Use .dockerignore to exclude sensitive files. If runtime configuration needs secrets, inject them at runtime (ECS task secrets, AWS Secrets Manager, parameter store, or BuildKit secrets) rather than baking them into images.
  5. Enforce deterministic dependency resolution: ensure lockfiles are present and used (fail the build if lockfile is absent), pin to specific versions, and validate package integrity (checksums/SBOM). Run dependency scans (SCA) and enable reproducible builds.
  6. Use multi-stage Docker builds and BuildKit secrets to avoid leaving secrets in layers. Avoid RUN steps that echo secrets; remove sensitive files in the same layer they were created if they must be used temporarily, or better: never create them in image layers. Enable image scanning for secrets before push.
  7. Consider configuring the CI to run builds in ephemeral environments and to rotate credentials used during the build. Limit credential scope and lifetime for CI (least privilege).

🔴 apps/app/src/app/(app)/[orgId]/controls/[controlId]/data/getOrganizationControlProgress.ts (HIGH Risk)

# Issue Risk Level
1 IDOR: controlId isn't validated against session activeOrganizationId HIGH
2 Missing input validation: controlId not validated for format or type HIGH
3 Distinct errors ('Unauthorized' vs 'Control not found') enable resource enumeration HIGH

Recommendations:

  1. Enforce ownership in the DB query: include organizationId in the where clause (e.g., db.control.findFirst({ where: { id: controlId, organizationId: orgId } })) so only resources belonging to the active organization are returned.
  2. Validate controlId format before using it in a DB query (e.g., ensure it's a UUID if IDs are UUIDs, or otherwise matches expected pattern). Reject or normalize invalid input early.
  3. Use a single, non-revealing error behavior for unauthorized/not-found cases to avoid enumeration. Option A: return 404 for both 'not found' and 'not allowed' from the public API. Option B: return 403 for authenticated but unauthorized, but do not leak existence details to unauthenticated users. Choose consistent HTTP semantics and messaging.
  4. Authorize at business-logic level: explicitly verify session.session.activeOrganizationId and/or the user's membership/permissions on the organization before returning resource data.
  5. Log and monitor failed access attempts and mismatched organization access attempts for audit and detection of probing/IDOR attempts.
  6. If using an ORM (Prisma), prefer findFirst with both id and organizationId rather than findUnique(id) + separate check to avoid timing/response differences that can be used for enumeration.

🔴 apps/app/src/app/(app)/[orgId]/frameworks/lib/getTasks.ts (HIGH Risk)

# Issue Risk Level
1 Unsanitized orgId used directly in DB query (SQL injection risk) HIGH
2 No input validation for organizationId HIGH
3 No authorization check; returns org tasks without access control HIGH
4 Caching response without auth ties may leak org data across users HIGH
5 Returns full incompleteTasks objects; may expose sensitive fields HIGH

Recommendations:

  1. Validate organizationId early (type, format, allowed length). Prefer strict types (e.g., UUID regex) and reject malformed values.
  2. Enforce authorization: verify the caller's identity and that they have access to the requested organizationId before querying and returning tasks.
  3. Limit returned columns: use the ORM's select/projection to return only necessary fields (avoid returning full task objects that may contain sensitive data).
  4. Scope or avoid memoization for sensitive data: either include auth context (user id/roles) in the cache key or do not cache results that depend on caller permissions.
  5. Ensure queries are parameterized (most ORMs do this by default), but do not rely solely on ORM—validate input and use prepared statements / ORM parameter binding as appropriate.

🟡 apps/app/src/app/(app)/[orgId]/tasks/components/TasksByCategory.tsx (MEDIUM Risk)

# Issue Risk Level
1 Unvalidated taskId concatenated into router.push URL MEDIUM
2 Path segments not encoded; may cause unexpected routing MEDIUM
3 Potential exposure of member user data to client MEDIUM

Recommendations:

  1. Encode path segments when building routes: router.push(${pathname}/${encodeURIComponent(taskId)}) or otherwise validate/normalize IDs before navigation.
  2. Enforce allowed ID formats (e.g., UUID regex) for task IDs on the client and — critically — on the server. Do not rely solely on client-side checks.
  3. Perform server-side authorization checks for task routes and any data returned for a task (verify the requesting user is allowed to view the task).
  4. Filter sensitive fields from member/user objects on the server before sending data to the client. Only include the minimum required user fields (e.g., name, avatar) and omit internal identifiers or secrets.
  5. Add robust input validation where user-controlled values can affect navigation or rendering. Prefer canonicalization + whitelisting over blacklisting.

💡 Recommendations

View 3 recommendation(s)
  1. Upgrade vulnerable packages: update xlsx (0.18.5) to a patched release that addresses GHSA-4r6h-8v6p-xvw6 and GHSA-5pgg-2g8v-p4x9, and update ai to >= 5.0.52.
  2. Fix IDOR and input validation in apps/app/.../getOrganizationControlProgress.ts: validate controlId format server-side and include organizationId in the DB where clause (e.g., findFirst({ where: { id: controlId, organizationId: session.activeOrganizationId } })). Return a single non-revealing error for not-found/unauthorized.
  3. Prevent injection and routing issues in apps/app/.../frameworks/lib/getTasks.ts and apps/app/.../TasksByCategory.tsx: validate/whitelist orgId and taskId (e.g., UUID regex) before DB use, restrict DB selects to required fields, and encode path segments (encodeURIComponent) when composing router URLs.

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

@vercel vercel bot temporarily deployed to staging – portal November 18, 2025 15:53 Inactive
@CLAassistant
Copy link

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.

* chore(bun.lock): update package versions and add new dependencies
* chore(api): update buildspec and Dockerfile to copy pre-built workspace packages

* chore(bun.lock): update package versions and add new dependencies

* chore(api): update buildspec to remove UI and Utils package copying
@vercel vercel bot temporarily deployed to staging – portal November 18, 2025 16:13 Inactive
@vercel vercel bot temporarily deployed to staging – app November 18, 2025 16:13 Inactive
@vercel vercel bot temporarily deployed to staging – app November 18, 2025 16:22 Inactive
@vercel vercel bot temporarily deployed to staging – portal November 18, 2025 16:22 Inactive
@Marfuen Marfuen merged commit fb4efc5 into release Nov 18, 2025
10 of 11 checks passed
@claudfuen
Copy link
Contributor

🎉 This PR is included in version 1.59.2 🎉

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