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 3 commits November 18, 2025 17:11
* refactor(integrations): replace OpenAI with Groq for faster task generation

* refactor(automation): replace OpenAI with Groq for faster suggestion generation

* feat(policies): implement policy tailoring status and enhance onboarding tracker

* feat(risk): enhance risk onboarding with new context and status tracking

* chore(risk): add loading animation and assessment progress calculation

* feat(vendors): implement onboarding loading animation and context for vendor assessments

* feat(onboarding): enhance onboarding process with loading states and status tracking for vendors and risks

* chore(risk): fix build errors

* chore(onboarding): increase concurrency limits for onboarding queues

---------

Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
Co-authored-by: Daniel Fu <itsnotaka@gmail.com>
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 - Code Vulnerability Scan

Analysis in progress...

Reviewing 30 file(s). This may take a few moments.


Powered by Comp AI - AI that handles compliance for you | Reviewed Nov 19, 2025, 03:37 PM

@vercel
Copy link

vercel bot commented Nov 18, 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 19, 2025 6:48pm
portal (staging) Ready Ready Preview Comment Nov 19, 2025 6:48pm

@CLAassistant
Copy link

CLAassistant commented Nov 18, 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.

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

…1780)

* fix(api): update windows device agent api to download .exe file instead of zip

* fix(api): remove unused params from downloadWindowsAgent function

---------

Co-authored-by: chasprowebdev <chasgarciaprowebdev@gmail.com>
@comp-ai-code-review
Copy link

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

🔒 Comp AI - Security Review

🔴 Risk Level: HIGH

2 high CVEs in xlsx (prototype-pollution & ReDoS) and 1 low CVE in ai; code contains filename/HTTP-header injection, unsanitized email URLs, and prototype-pollution risk from untrusted object keys.


📦 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 17 file(s) with issues

🔴 apps/api/Dockerfile (HIGH Risk)

# Issue Risk Level
1 Remote curl bash installer executed as root
2 No checksum/signature verification for installer HIGH
3 Copying host node_modules into image (supply-chain risk) HIGH
4 Installing APK packages without version pinning HIGH

Recommendations:

  1. Avoid piping remote scripts to shell as root. Use an official bun base image or download a pinned bun release artifact and verify it before extracting. Perform installer steps in a non-root build stage (multi-stage build) and drop privileges before runtime.
  2. Verify downloaded installers with strong checksums or signatures (e.g., compare SHA256 or verify GPG signatures) before executing. Do not run unverified installer output.
  3. Do not COPY host node_modules into the image. Reinstall dependencies inside a controlled build stage (e.g., bun install/npm ci/yarn --frozen-lockfile) so builds are reproducible and do not inherit host-specific artifacts. Use lockfiles (bun.lockb/package-lock.json) and off-line/cache approaches for reproducible installs.
  4. Pin APK package versions (package=version) or use a known-good base image with required packages already provisioned. After building, scan the final image with a vulnerability scanner (Trivy, Clair) and remove unnecessary packages.
  5. Use a multi-stage Dockerfile: do installs and build as root in a builder stage, switch to a non-root user in the final runtime stage, and only copy necessary build artifacts into the runtime image.

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

# Issue Risk Level
1 Remote install via curl bash (bun.sh) — arbitrary code execution
2 Installer not verified (no checksum or pinned version) HIGH
3 Copying host node_modules into image may bake secrets HIGH
4 Copying .prisma and @prisma may include DB artifacts/credentials HIGH
5 Build logs echo env and dir info — potential sensitive leaks HIGH
6 Unquoted env vars in shell commands — command injection risk HIGH
7 Caching node_modules and bun cache may persist secrets across builds HIGH
8 No image secret scanning before push to ECR HIGH

Recommendations:

  1. Replace curl | bash installer with a pinned, verified installer or use an official package/distribution image. If you must fetch remotely, download a specific version artifact and verify its checksum/signature before executing.
  2. Pin bun to a specific, audited version (do not use the latest/unpinned installer). Store expected checksums in the repo or CI secrets and verify after download.
  3. Avoid copying host/node_modules into the docker build context. Use Docker multi-stage builds: install dependencies inside the image in a controlled environment (npm/ci or bun install inside the build stage) so host artifacts and local secrets are not baked in.
  4. Do not copy local prisma artifacts that might contain generated credentials or environment-specific artifacts. Ensure prisma/schema and generated clients do not contain hardcoded connection info. Rebuild Prisma client inside the image as part of the build stage.
  5. Remove or limit logging of environment variables and directory listings. Do not echo or print env vars that may contain secrets. Replace verbose ls/echo statements with conditional debug logging gated by a non-production flag.
  6. Always quote environment variables in shell expressions where values could include spaces or special characters (e.g., use "$ECR_REPOSITORY_URI:$IMAGE_TAG"). Validate and sanitize any env inputs used in shell contexts. Consider using parameterized commands or CI/CD features to pass arguments safely.
  7. Restrict caching to safe, deterministic artifacts. Avoid caching node_modules or other directories that may contain secrets or local config files. If caching is needed, prune sensitive files before caching or use isolated build containers per run.
  8. Integrate image scanning and secret detection into the pipeline (e.g., Trivy, Clair, Snyk, AWS ECR image scanning) before pushing to ECR. Block deployments if high/critical secrets or vulnerabilities are found.

🔴 apps/api/src/device-agent/device-agent.controller.ts (HIGH Risk)

# Issue Risk Level
1 HTTP header injection via filename in /device-agent/mac and /device-agent/windows HIGH
2 Unvalidated Content-Type header from service may be attacker-controlled HIGH
3 OrganizationId/authContext not enforced before serving agent binaries HIGH

Recommendations:

  1. Sanitize filenames: strip CRLF, quotes and other unsafe chars before use
  2. Avoid raw filename in Content-Disposition; use only filename* with encoded value
  3. Validate contentType against an allowlist of allowed MIME types
  4. Enforce authorization: validate organizationId/authContext before serving files
  5. Add access logging and rate limiting for download endpoints

🔴 apps/api/src/email/resend.ts (HIGH Risk)

# Issue Risk Level
1 Missing validation: unvalidated 'to','cc','subject','react','scheduledAt' inputs HIGH
2 Potential info leak: logging full error objects to console HIGH
3 API key exposure if this module is bundled to client HIGH
4 Unrestricted email sending: no auth or rate limiting allows abuse/spam HIGH
5 Unsanitized React email content may enable XSS/phishing in recipients HIGH

Recommendations:

  1. Validate and sanitize all inputs before sending: ensure 'to' and 'cc' are valid email addresses (and limit number of recipients), enforce subject length/character restrictions, validate 'scheduledAt' as an allowed ISO timestamp or block scheduling, and enforce typing/size limits on 'react' content.
  2. Don’t log full error objects. Redact sensitive fields before logging (e.g., mask tokens, API responses that contain headers or secrets). Log only necessary error codes/messages and use structured logging with scrubbing.
  3. Treat RESEND_API_KEY as server-only: do not export or re-export the resend client to any code that could be bundled to the browser. Ensure this module is never imported by client-side bundles and keep secrets in server-only environment variables.
  4. Require authentication and authorization on any API endpoint that calls sendEmail. Add rate limiting, per-account quotas, and abuse detection (e.g., throttle by IP, account, or API key). Consider approval flows for high-volume sends.
  5. Sanitize or constrain email content: prefer safe template rendering (server-side templates with escaping) instead of raw React nodes from untrusted sources. If React content is necessary, validate and sanitize links and disallow dangerous attributes/scripts; consider rendering to plain text and sanitized HTML.
  6. Perform input length checks and enforce limits (subject/body size, number of CC recipients). Validate CC types (string vs array) before passing to the SDK.
  7. Avoid returning or logging SDK error objects to clients. Propagate only minimal, non-sensitive error messages to callers.

🟡 apps/api/src/email/templates/access-granted.tsx (MEDIUM Risk)

# Issue Risk Level
1 Unsanitized portalUrl used in href — phishing, JS URI or open-redirect risk MEDIUM

Recommendations:

  1. Validate portalUrl on the server before rendering: enforce allowed schemes (https:, http:), disallow javascript:, data:, vbscript:, and other dangerous schemes.
  2. Whitelist hosts (or use an allowlist) if links should only go to known domains. Reject or rewrite any URLs not on the allowlist.
  3. Where external links are necessary, consider routing links through an internal redirector/URL shortener that validates/records destination (e.g., https://example.com/r?dest=) so raw user-provided URLs are never embedded directly.
  4. Apply canonicalization and URL parsing (e.g., new URL(portalUrl)) to detect obfuscated javascript: variants and ensure the origin/scheme checks are robust.
  5. Defence-in-depth: continue to treat names/org strings as untrusted and HTML-escape/encode them server-side before passing to templates, even though React escapes JSX by default.
  6. Log and monitor emails containing external links and consider warning text within the email when linking to third-party domains (e.g., “You are being redirected to an external site”).

🟡 apps/api/src/email/templates/access-reclaim.tsx (MEDIUM Risk)

# Issue Risk Level
1 Unsanitized props (toName, organizationName, accessLink) used in email MEDIUM

Recommendations:

  1. Validate and sanitize toName and organizationName on input (server-side). Enforce a whitelist of allowed characters/length (e.g., letters, digits, common punctuation) or HTML-escape them before rendering. Although React escapes JSX text nodes by default, explicit server-side validation/normalization prevents stored malicious values and attack surface for other render paths.
  2. Strictly validate accessLink server-side: parse the URL and allow only http and https schemes; reject javascript:, data:, vbscript: and other dangerous or non-web schemes. Use a vetted URL parsing library (new URL(...) in Node.js) and reject malformed URLs.
  3. If your flow involves third-party-provided URLs, convert to internal short/opaque tokens (e.g., https://yourapp.example/reclaim/) that map to the real resource on the server. Validate tokens and enforce server-side expiry, single-use, rate-limiting and logging.
  4. When rendering links, ensure the href value is a validated URL and consider normalizing (e.g., encodeURI) to prevent attribute injection. Avoid rendering untrusted HTML or using dangerouslySetInnerHTML.
  5. Add telemetry/alerts for suspicious link-generation patterns and consider scanning user-supplied organization names for homograph/phishing-risk characters (Unicode confusables) if relevant.
  6. Document and enforce link expiry and revocation server-side; do not rely solely on the client-side text saying it's expired.

🟡 apps/api/src/email/templates/nda-signing.tsx (MEDIUM Risk)

# Issue Risk Level
1 Unvalidated ndaSigningLink used in href and shown to user MEDIUM
2 Possible javascript: or data: URL injection via ndaSigningLink MEDIUM
3 User-controlled toName/orgName inserted without validation MEDIUM

Recommendations:

  1. Validate and canonicalize ndaSigningLink server-side before passing to the template. Use the URL constructor (or a robust URL parser) to allow only https: and http: schemes and optionally restrict to a set of allowed hosts or domains.
  2. Reject or rewrite unsafe schemes (javascript:, data:, vbscript:, file:, etc.). If the link is invalid, render a safe fallback (e.g., no href and a note to contact the organization) rather than rendering the raw input.
  3. URL-encode or escape the displayed link text. Prefer showing a canonicalized, human-readable URL (or just the domain) instead of directly echoing the full user-supplied URL.
  4. For outbound links, add rel="noopener noreferrer" and target="_blank" where appropriate (recognizing email client support varies) so that even if the link is external it minimizes window/tab exploitation.
  5. Sanitize and validate toName and organizationName on the server side (length limits, allowed character set). Although React escapes text nodes by default, validating prevents unexpected content and social engineering attacks in email previews/subjects.
  6. Use signed, single-use tokens for the ndaSigningLink and enforce expiry server-side. Do not rely on client-side expiry; validate token, usage count, and expiry on the server before allowing access.
  7. Log and monitor suspicious link generation and clicks. If possible, render a short explanation in the email that the link is safe and the domain it will go to (helps users detect phishing).

🟡 apps/api/src/trust-portal/email.service.ts (MEDIUM Risk)

# Issue Risk Level
1 No input validation for toEmail, toName, organizationName, or links MEDIUM
2 User-supplied values used directly in email subject/body (XSS/HTML injection) MEDIUM
3 Unvalidated links included in emails (phishing/open-redirect risk) MEDIUM
4 Recipient email addresses logged in plaintext (PII exposure) MEDIUM
5 No rate limiting or access controls on sending (mass-email abuse risk) MEDIUM

Recommendations:

  1. Validate and sanitize emails, names, and URLs before use
  2. Escape or sanitize values in templates to prevent HTML injection
  3. Validate or whitelist link targets; add warnings for external links
  4. Avoid logging raw recipient emails; mask or redact PII
  5. Enforce auth, rate limits and sending quotas in sendEmail path

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

# Issue Risk Level
1 Prototype pollution via untrusted IDs used as object keys (e.g., vendor.id -> vendorsStatus) MEDIUM
2 Unvalidated run.metadata can cause type confusion or runtime issues MEDIUM
3 Unencoded organizationId used in router.push (could lead to unexpected navigation) MEDIUM

Recommendations:

  1. Protect against prototype pollution when using untrusted IDs as object keys: create the status containers with Object.create(null) (e.g., const vendorsStatus = Object.create(null);) or use a Map instead of a plain object, and/or validate IDs against an allowlist/regex (e.g., /^[A-Za-z0-9-_]+$/) before using them as keys.
  2. Treat run.metadata as untrusted input. Validate/parse its schema at runtime (server-side and client-side) with a schema validator (Zod, io-ts, yup, etc.) before using values. Use strict type guards and fallback values and avoid unchecked casts (the many as number / as string casts). Consider normalizing metadata on the server and signing/authorizing it so clients can trust it.
  3. Encode path segments and query parameters before navigation. Use encodeURIComponent for organizationId when constructing URLs (e.g., router.push(/onboarding/${encodeURIComponent(organizationId)}?retry=1)) or use next/navigation route helper APIs that accept params to avoid malformed URLs.
  4. When iterating metadata keys to build dynamic objects, avoid directly trusting keys from metadata. Explicitly parse expected arrays (vendorsInfo, risksInfo, policiesInfo) and validate each entry (id/name), ignoring or logging unexpected entries.
  5. Where possible, keep sensitive logic (auth, critical integrity checks) server-side. If metadata originates from an external system, ensure it is validated and signed server-side before being consumed by client code.

🟡 apps/app/src/app/(app)/[orgId]/integrations/actions/get-relevant-tasks.ts (MEDIUM Risk)

# Issue Risk Level
1 Missing validation for integrationName and integrationDescription MEDIUM
2 Missing validation for taskTemplates items (id/name/description) MEDIUM
3 Accepting model output with minimal post-validation MEDIUM
4 Parsing error.text fallback without schema validation MEDIUM

Recommendations:

  1. Validate and sanitize all inputs (integrationName, integrationDescription) before use. e.g., use zod to enforce max length, allowed chars, and strip control characters/newlines that could bloat prompts or inject formatting.
  2. Validate taskTemplates array and each item (id, name, description) before formatting. Enforce maximum counts (e.g., max 50 items) and per-field length limits, and normalize/truncate fields consistently.
  3. Treat model output as untrusted. After generateObject returns, run RelevantTasksSchema.safeParse (or .parse with try/catch) on the final object before using/returning it. Reject or sanitize any fields that don't match exactly (types/lengths/characters).
  4. For the fallback NoObjectGeneratedError path, do NOT directly JSON.parse and return unchecked. Use RelevantTasksSchema.safeParse on parsed data and only accept values that validate. If validation fails, discard and return an empty array or a safe default.
  5. Sanitize the 'prompt' field returned by the model before it is acted on elsewhere — remove or escape dangerous shell/meta sequences if downstream may execute or interpolate it, and enforce length and allowed-character policies.
  6. Add operational limits: cap prompt size, enforce rate limits and timeouts on generateObject calls, and limit token usage to prevent resource exhaustion or abuse.
  7. Add logging and monitoring for anomalous inputs (very large strings, high frequency calls) and failed validations to detect abuse or injection attempts.

🟡 apps/app/src/app/(app)/[orgId]/policies/all/components/policies-table.tsx (MEDIUM Risk)

# Issue Risk Level
1 IDOR: onboardingRunId used directly to subscribe to runs MEDIUM
2 Unauthorized log access: getLogsForPolicy called client-side without auth checks MEDIUM
3 Unvalidated run.metadata used to set policy statuses/progress MEDIUM
4 Unvalidated orgId from useParams used in paths and columns MEDIUM

Recommendations:

  1. Verify onboardingRunId ownership server-side before exposing it to the client. Do not rely on a client-side subscription alone for access control. Ensure any Realtime/WS subscription endpoint checks that the requesting user is authorized to subscribe to that run ID.
  2. Move policy log retrieval to an authenticated server API route (or ensure the existing API enforces auth+authorization). The client should call a server endpoint that fetches logs after verifying the caller has access to the policy/org. Avoid calling data-fetch helpers directly from client code unless they enforce auth server-side.
  3. Validate and sanitize run.metadata before treating it as authoritative: use runtime schema validation (e.g., zod/joi/io-ts) to check expected fields/types (policiesInfo array, policiesTotal/policiesCompleted numbers, status strings). Handle missing/invalid fields safely and fail closed (e.g., ignore invalid entries).
  4. Validate orgId from useParams before using it to build links or pass to other modules. Enforce that the current user is a member of that organization on the server before returning organization-specific data to the client. Consider validating format (e.g., UUID) and checking membership via a server-side check.
  5. Make handleDownloadAll robust: wrap async work in try/catch/finally to ensure isDownloadingAll is reset on errors. Example: setIsDownloadingAll(true); try { await fetchAllLogs(); downloadAllPolicies(...); } catch (e) { /* report/log */ } finally { setIsDownloadingAll(false); }
  6. When fetching logs for many policies, limit concurrency (e.g., p-limit/p-map) and add timeouts/retries to avoid DoS or long-running client requests. Provide clear error handling if some policy logs cannot be retrieved.
  7. Audit getPolicyColumns and any other functions that accept orgId to ensure they do not perform insecure server calls based solely on a client-controlled orgId—server-side enforcement of org membership is required for any sensitive operation.

🟡 apps/app/src/app/(app)/[orgId]/policies/all/page.tsx (MEDIUM Risk)

# Issue Risk Level
1 Unvalidated orgId used in DB query (possible injection or ID tampering) MEDIUM
2 Missing authorization check to confirm requester may access orgId MEDIUM
3 Search filters passed to getPolicies may be used unsafely in DB queries MEDIUM

Recommendations:

  1. Validate and sanitize orgId before using in DB queries
  2. Enforce authorization: verify requester owns or can access orgId
  3. Ensure getPolicies builds queries safely (parameterized/ORM)
  4. Whitelist and strict-validate search filters and parameters
  5. Add server-side logging and error handling for DB access

🟡 apps/app/src/app/(app)/[orgId]/risk/(overview)/RisksTable.tsx (MEDIUM Risk)

# Issue Risk Level
1 URL query params passed directly to getRisksAction MEDIUM
2 Unvalidated sort/filters from URL may enable injection MEDIUM
3 lastUpdated date array coerced from URL may be malformed MEDIUM
4 1s polling during onboarding can be abused for DoS MEDIUM
5 SWR key includes raw JSON of user input (cache poisoning risk) MEDIUM

Recommendations:

  1. Validate and sanitize all search params server-side
  2. Apply strict Zod schema validation in getRisksAction
  3. Limit input sizes and filter complexity
  4. Rate-limit polling and add exponential backoff
  5. Normalize/limit SWR key length; avoid raw user JSON

🟡 apps/app/src/app/(app)/[orgId]/risk/(overview)/actions/get-risks-action.ts (MEDIUM Risk)

# Issue Risk Level
1 Input forwarded to getRisks without runtime validation MEDIUM

Recommendations:

  1. Add explicit runtime validation in getRisksAction (or inside getRisks) before using input. For example call the runtime parser (searchParamsCache.parse) or a zod/validator parse on the incoming data to guarantee values and types at runtime.
  2. Whitelist and validate filter/sort field names and operators before using them (e.g., ensure filter.id and sort.id are allowed column names), and coerce/validate page/perPage/joinOperator values.
  3. If this server action can be invoked from clients directly, enforce server-side validation even if other call sites perform parsing. Do not rely solely on caller-side parsing.
  4. Keep using the ORM (Prisma) and avoid raw SQL or string concatenation. If any raw queries are required, use Prisma parameterized/raw bindings rather than interpolating user input.
  5. Consider adding unit/integration tests that exercise server action call paths with malformed inputs to ensure unexpected values are handled safely.

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

# Issue Risk Level
1 OrgId used in DB query without authorization HIGH
2 Onboarding triggerJobId exposed to client without authorization HIGH
3 No validation of route orgId format or ownership HIGH

Recommendations:

  1. Authorize/validate the route orgId before any DB query that uses it. Ensure the requesting user's session (activeOrganizationId) matches the orgId route param, otherwise return 403/empty.
  2. Replace the direct db.onboarding.findFirst({ where: { organizationId: orgId } }) with a lookup that uses the session's activeOrganizationId or explicitly verify the user's access to orgId prior to querying. Do not trust route params for authorization decisions.
  3. Avoid returning internal identifiers (triggerJobId) to clients unless the client is authorized for that organization. Consider redacting, hashing, or requiring explicit permission checks before including such fields in the rendered response.
  4. Centralize session/auth checks for server components that perform DB access (e.g., a helper that validates session + org ownership) so all queries on the page consistently enforce the same access control.
  5. Add validation for the orgId route param format (UUID or expected shape) and verify ownership/permission. Fail fast if the format is invalid to reduce unnecessary DB hits.

🟡 apps/app/src/app/(app)/[orgId]/risk/[riskId]/actions/regenerate-risk-mitigation.ts (MEDIUM Risk)

# Issue Risk Level
1 Missing ownership check for riskId before triggering task MEDIUM
2 No permission check ensuring user can regenerate this risk MEDIUM
3 Unvalidated DB policy descriptions sent to external task MEDIUM
4 No size limits on payload sent to tasks.trigger MEDIUM

Recommendations:

  1. Verify riskId belongs to session.activeOrganizationId before triggering the task (query the risk record and confirm organizationId matches).
  2. Enforce fine-grained authorization: check that the current user (from session) has permission to regenerate mitigations for the specified risk/organization.
  3. Sanitize and validate policy fields (especially description) before sending to tasks.trigger. Consider length limits, stripping/escaping unexpected control characters, and validating content schema.
  4. Enforce payload size limits: limit number of policies included, cap string lengths, and reject/trim overly large payloads before calling tasks.trigger.
  5. Add audit logging for regenerate actions (who, when, riskId, organizationId) and rate limiting to reduce abuse.
  6. Review the generateRiskMitigation task implementation to ensure it safely handles untrusted inputs (e.g., avoid directly using policy descriptions in prompts or code without sanitization).

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

# Issue Risk Level
1 Missing validation for taskDescription and organizationId HIGH
2 No authorization check before querying organization data HIGH
3 Unvalidated AI error-recovery JSON parsed and returned HIGH

Recommendations:

  1. Validate and sanitize inputs: add zod (or similar) schemas for taskDescription and organizationId at the function boundary. Enforce types/lengths (e.g., ensure organizationId is a valid UUID if applicable) and limit taskDescription size to a reasonable maximum.
  2. Add authorization checks: ensure the caller is authorized to access data for the given organizationId before performing any DB queries or returning suggestions. Prefer middleware or explicit guards that validate the caller's membership/permissions.
  3. Validate AI-recovered JSON before use: when parsing error.text and extracting parsed.suggestions, validate the parsed result against SuggestionsSchema (e.g., SuggestionsSchema.parse or safeParse) before returning it. Reject or sanitize any malformed entries.
  4. Harden logging: avoid logging sensitive values and minimize high-precision timing information in production. Consider redacting or aggregating timing logs and omitting raw vendor/context contents from logs.
  5. Ensure DB usage remains parameterized: while the current code uses ORM-style findMany with a where object (which normally produces parameterized queries), continue to avoid raw SQL concatenation and review any future usage that might use raw/unsafe queries.

💡 Recommendations

View 3 recommendation(s)
  1. Remediate the OSV findings: upgrade xlsx to a version that patches GHSA-4r6h-8v6p-xvw6 and GHSA-5pgg-2g8v-p4x9, and upgrade ai to >= 5.0.52 (the advisory lists 5.0.52 as fixed).
  2. Fix header/filename injection in apps/api/src/device-agent/device-agent.controller.ts: strip CR/LF and unsafe chars from any filename used in Content-Disposition, use RFC5987 (filename*) encoding or a server-side generated filename, and validate the Content-Type against a strict allowlist before returning binaries.
  3. Sanitize and validate URLs and untrusted keys in templates and UI code: canonicalize and allowlist link schemes/hosts before embedding (block javascript:, data:, vbscript:), HTML-escape displayed values, and avoid using untrusted IDs as plain object keys (use Object.create(null) or a Map and validate IDs against a tight regex).

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

)

Co-authored-by: Daniel Fu <itsnotaka@gmail.com>
Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
)

* refactor(api): remove unused email templates and update buildspec

* chore(api): update @trycompai/db dependency version in package.json

* fix(api): update Dockerfile to remove error handling in bun install

---------

Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
@vercel vercel bot temporarily deployed to staging – app November 19, 2025 18:11 Inactive
@vercel vercel bot temporarily deployed to staging – portal November 19, 2025 18:11 Inactive
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