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.

* refactor: dont crash trigger on cloud tests job

* chore: fix types
@vercel
Copy link

vercel bot commented Nov 10, 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 11, 2025 2:30pm
1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
portal (staging) Skipped Skipped Nov 11, 2025 2:30pm

@comp-ai-code-review
Copy link

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

🔒 Comp AI - Security Review

🔴 Risk Level: HIGH

OSV: GHSA-rwvc-j5jr-mgvh in ai@5.0.0; hardcoded token found in EmptyState.tsx; unsanitized organizationId used in run-integration-tests.ts (possible DB injection).


📦 Dependency Vulnerabilities

🟢 NPM Packages (LOW)

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

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

🛡️ Code Security Analysis

View 8 file(s) with issues

🟡 apps/app/src/app/(app)/[orgId]/cloud-tests/actions/connect-cloud.ts (MEDIUM Risk)

# Issue Risk Level
1 Potential sensitive data in error logs (console.error may include credentials) MEDIUM
2 Returning raw error.message to client leaks internal info MEDIUM
3 publicAccessToken cookie set without Secure/HttpOnly/SameSite attributes MEDIUM
4 Untrusted headers (referer/x-pathname) used directly in revalidatePath MEDIUM
5 No rate limiting on credential validation could enable brute force MEDIUM
6 Credentials passed plaintext to handler for validation may expose secrets to handler MEDIUM

Recommendations:

  1. Avoid logging raw error objects. Redact or scrub sensitive fields before logging. In particular, don't log entire error objects if upstream handlers might include credential values in thrown errors (replace console.error('Credential validation failed:', error) with structured logs that exclude sensitive fields).
  2. Do not return raw error.message to the client. Return a generic client-facing message (e.g., 'Invalid credentials' or 'Failed to connect cloud provider') and write detailed messages to server logs only.
  3. Set proper cookie attributes when storing tokens: Secure, HttpOnly, SameSite (Lax/Strict as appropriate), explicit path and maxAge/expires. Use the cookies API options to set these flags rather than calling cookies().set(name, value) without options.
  4. Never call revalidatePath with an unvalidated header-derived value. Parse and validate the path against a whitelist or canonicalize it (URL parse, ensure it is an internal path and matches expected routes) before calling revalidatePath. Reject or normalize suspicious inputs and strip protocol/host fragments.
  5. Add rate limiting and retry/backoff for credential validation attempts tied to user identity and/or IP address (e.g., per-organization and per-IP limits). Consider temporary lockouts or CAPTCHA after repeated failures.
  6. When sending credentials to integration handlers for validation, ensure the handler is trusted not to log credentials. If possible, minimize exposure (validate only necessary fields), avoid passing full plaintext to third-party code, or use transient encrypted channels and explicit no-logging contracts. If validation absolutely requires plaintext, document and mitigate logging/exfiltration risks and ensure handlers run in a trusted execution environment.

🟡 apps/app/src/app/(app)/[orgId]/cloud-tests/actions/create-trigger-token.ts (MEDIUM Risk)

# Issue Risk Level
1 No permission check before creating public token MEDIUM
2 Created token not tied to orgId or user context MEDIUM
3 Creates multiple-use public token (higher abuse risk) MEDIUM
4 Logs raw error to console, may leak sensitive info MEDIUM
5 No rate limiting or abuse controls for token creation MEDIUM

Recommendations:

  1. Perform an explicit authorization/role check before creating tokens (e.g., ensure session.user has a role/permission like 'org_admin' or 'create_tokens'). Do not rely solely on existence of a session.
  2. Scope tokens to the organization and user context. Include orgId and user id in the token metadata/claims and/or persist a mapping server-side so tokens can be validated and revoked per-org.
  3. Avoid multiple-use public tokens when possible. Prefer single-use tokens or reduce lifetime. If multiple-use is required, limit scope and duration and record usage for auditing.
  4. Do not log raw error objects to console in production. Log minimal, non-sensitive messages and sanitize or redact sensitive fields. Consider structured logging with severity and correlation identifiers instead.
  5. Add rate limiting/throttling on token creation endpoints and implement auditing (who created the token, when, and for which org). Consider additional protections like CAPTCHA or multi-factor for high-risk operations.

🟡 apps/app/src/app/(app)/[orgId]/cloud-tests/components/CloudConnectionCard.tsx (MEDIUM Risk)

# Issue Risk Level
1 Missing input masking for credentials (type='text' default) MEDIUM
2 Only checks non-empty; no format/strength validation MEDIUM
3 Credentials stored in React state unencrypted MEDIUM
4 console.error may expose sensitive data from errors MEDIUM
5 External logoUrl may leak user IP or load malicious content MEDIUM

Recommendations:

  1. Mark secret inputs explicitly and render them as type='password' (or use a secret flag on fields). Do not rely on a default 'text' type for credential fields.
  2. Add stronger client- and server-side validation for credential formats (e.g., key length, pattern checks) and server-side strength checks where applicable. Treat client-side validation as UX only; enforce on backend.
  3. Avoid persisting secrets in React state where possible. Use uncontrolled inputs or transient mechanisms, submit directly, then immediately clear references. If state must be used, minimize lifetime, zero-out values after use, and ensure they are not accidentally exposed (e.g., through debugging tools).
  4. Avoid logging full error objects to the console. Sanitize errors before logging (log only error codes/IDs) and ensure the backend does not echo secrets in error responses.
  5. Validate and restrict logoUrl values (allowlist hostnames) or proxy external images through your server. Add mitigations like referrerPolicy='no-referrer', Content-Security-Policy img-src restrictions, and consider using crossOrigin attributes or serving images from trusted sources to prevent IP/referrer leakage and reduce risk of malicious content.

🔴 apps/app/src/app/(app)/[orgId]/cloud-tests/components/EmptyState.tsx (HIGH Risk)

# Issue Risk Level
1 Hardcoded tokens in logoUrl (pk_AZatYxV5QDSfWpRDaBxzRQ) HIGH
2 Plaintext cloud credentials stored in client state HIGH
3 No validation of credential formats (e.g., GCP JSON) HIGH
4 Potential logging of errors may expose secrets via console.error HIGH

Recommendations:

  1. Remove hardcoded tokens from client-side assets. Move tokens to environment variables and resolve the image URL server-side or via a backend proxy so secrets/keys are not embedded in frontend code or the bundle.
  2. Avoid storing long-lived secrets in client-side state. If credentials must be collected in the browser, send them immediately over HTTPS to a trusted server endpoint and then clear them from React state (e.g., setCredentials({}) and overwrite memory-friendly structures). Consider using browser ephemeral/auth flows (OAuth, STS temporary creds) so raw secrets are not handled by the UI.
  3. Validate credential payload formats before transmitting: enforce JSON schema validation for GCP service account keys, format checks for AWS access keys and GUID formats for Azure IDs. Provide client-side validation to reduce accidental leaks/incorrect submissions, but perform authoritative validation server-side as well.
  4. Do not log raw error objects to the console that may include returned credentials or sensitive fields. Use structured logging with redaction, log only non-sensitive error identifiers or sanitized messages, and ensure server-side logs redact secrets.
  5. Transmit and store credentials only on the server side. Use HTTPS, limit credential lifetime (temporary tokens), and consider using provider-supported delegated auth (IAM roles, OAuth, Workload Identity) instead of direct key exchange.
  6. Clear/overwrite sensitive variables after use and minimize time they reside in memory. Use secure handling patterns and consider secure clipboard/wipe UX guidance for users pasting secrets.

🔴 apps/app/src/app/(app)/[orgId]/cloud-tests/components/TestsLayout.tsx (HIGH Risk)

# Issue Risk Level
1 Trigger token exposed to client-side (sensitive credential in browser) HIGH
2 orgId submitted without validation or authorization checks HIGH
3 Displaying raw run/error messages from backend in toasts HIGH

Recommendations:

  1. Move the triggerToken off the browser. Do not pass it into client components. Instead, create a server-side endpoint (e.g., POST /api/cloud-tests/run) that holds the trigger token in server-only configuration and calls the realtime task trigger from the server.
  2. Have the server endpoint validate and authorize the requesting user for the given orgId before submitting any scan. Enforce authorization on the server side (check session, ownership, roles, or organization membership).
  3. On the client, send only a minimal request (e.g., POST /api/cloud-tests/run with orgId) and let the server perform validation/authorization and submit the task using the server-side token.
  4. Avoid displaying raw backend error messages to users. Map internal errors to safe, user-friendly messages for toasts and log full details server-side. Redact sensitive information before returning any error text to the client.
  5. If client-side tokens are absolutely required, use short-lived, tightly scoped tokens with minimal privileges and rotate them frequently. Prefer server-mediated operations whenever possible.
  6. Add server-side rate limiting and auditing for task submissions to detect and mitigate abuse.
  7. Ensure all communication uses TLS and store sensitive tokens only in server-side environment variables or secure vaults (never embed in client JS or props).

🟡 apps/app/src/app/(app)/[orgId]/cloud-tests/page.tsx (MEDIUM Risk)

# Issue Risk Level
1 Public multi-use trigger token (multipleUse=true, 1hr expiry) can be abused MEDIUM
2 No validation/sanitization of orgId route param MEDIUM
3 Sensitive findings/remediation returned to client view MEDIUM
4 Request headers forwarded to auth.getSession without filtering MEDIUM

Recommendations:

  1. Create trigger tokens with the minimal scope and use single-use tokens where possible. If multi-use is necessary, reduce TTL significantly (minutes) and add usage limits and auditing.
  2. Validate and normalize orgId before use (e.g., ensure it matches expected format such as UUID or numeric ID). Reject or canonicalize unexpected values before using in queries or redirects.
  3. Avoid returning sensitive fields to the client. Remove or redact description/remediation from the initialFindings payload, or only return summary metadata and fetch full details on-demand to authorized users.
  4. Only forward the specific headers required by betterAuth.api.getSession (e.g., Cookie or Authorization). Do not pass the entire headers() object directly; build a whitelist of needed headers to avoid leaking or amplifying request headers.

🔴 apps/app/src/jobs/tasks/integration/run-integration-tests.ts (HIGH Risk)

# Issue Risk Level
1 Unsanitized organizationId used in DB query (possible injection depending on ORM) HIGH
2 No authorization check for organizationId; task may operate on any org HIGH
3 Sensitive settings/userSettings forwarded to external batch potentially leaking secrets HIGH
4 Detailed error messages and integration names logged/returned, risking information disclosure HIGH
5 forceFailure flag accepted from payload allowing attackers to trigger false failures HIGH

Recommendations:

  1. Validate and canonicalize organizationId: enforce a strict format (e.g., UUID v4), length checks, and reject unexpected input before using it in DB queries. Even when using an ORM that parameterizes queries, validate inputs at the boundary.
  2. Enforce authorization/ACL: verify the caller (or invoking service) is permitted to run tests for the specified organizationId. If this task is triggered from an API or UI, check the user/session token or service identity and ensure proper RBAC (e.g., only org admins or internal system accounts).
  3. Redact or omit secrets in settings/userSettings before sending to sendIntegrationResults.batchTriggerAndWait or logging. Implement a whitelist of non-sensitive fields, mask tokens/keys (e.g., replace with **** or only include metadata), or send only a reference ID rather than raw credentials.
  4. Reduce diagnostic leakage: avoid returning detailed internal errors and integration names to external callers. Log detailed info internally with restricted access, but return minimal, generic error messages to callers (e.g., 'Integration tests failed').
  5. Restrict forceFailure usage: remove it from publicly-controllable payloads or enforce that only internal/admin callers can set forceFailure. Consider removing this feature from production code or gate it behind an internal-only flag/service account.
  6. Harden error handling around batch triggers: sanitize run.error before logging or returning; do not assume error objects are safe to stringify. Consider structured error codes rather than raw messages.
  7. Audit and document data flows to external systems: treat sendIntegrationResults as an external boundary—ensure it is trusted, has proper access controls, and that secrets are not unintentionally propagated.
  8. Add monitoring/alerting for abnormal usage: detect unexpected mass invocations, repeated force-failures, or attempts to access many organizations from a single caller.

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

# Issue Risk Level
1 Download token placed in URL query parameter MEDIUM
2 Token can leak via Referer, browser history, or logs MEDIUM
3 POST /api/download-agent/token may be CSRFable from same-origin forms MEDIUM
4 No validation of token response before usage MEDIUM
5 Detected OS may be null leading to os=null in request MEDIUM

Recommendations:

  1. Do not place auth/download tokens in URL query parameters. Instead: return the file from a POST endpoint (authenticated), or fetch the file body via fetch() and create a blob URL for download so the token is only sent in request headers/body and not in history/Referer.
  2. Make download tokens short-lived and single-use server-side. Validate token usage (one-time consumption) and bind token to the requesting user/org and client IP/UA where feasible.
  3. Protect the token issuance endpoint (/api/download-agent/token) against CSRF. Require a per-session CSRF token or use SameSite=strict/strict-ish cookies and require an Authorization header (Bearer) for API requests so simple form POSTs cannot obtain tokens.
  4. Validate the tokenResponse payload before using it: check token existence and format, handle missing/invalid token cases and surface a clear error instead of constructing a URL with an undefined token.
  5. Validate detectedOS before building the download URL. Disable the download button until detectedOS is known or fall back to a safe default (or prompt user to choose). Server-side should also validate the os parameter and not rely on client-supplied values.
  6. When triggering browser download via a temporary anchor, avoid relying on a.download to set filename for authenticated endpoints. Prefer Content-Disposition on the file response (server) and streaming the response via fetch to create a blob URL client-side.
  7. Mitigate Referer leakage: set an appropriate Referrer-Policy on pages or ensure the download endpoint uses POST/Authorization to avoid token in URL being sent in Referer header to third parties.
  8. Log minimal sensitive data on server. Ensure server access logs do not persist tokens (reject/ignore tokens in querystring or rotate them quickly).

💡 Recommendations

View 3 recommendation(s)
  1. Upgrade the vulnerable dependency: update package.json to use ai@>=5.0.52 and regenerate the lockfile (yarn.lock/package-lock.json) so the fixed version is installed.
  2. Remove the hardcoded token (pk_AZatYxV5QDSfWpRDaBxzRQ) from apps/app/src/app/(app)/[orgId]/cloud-tests/components/EmptyState.tsx. Instead, do not embed secrets in client bundles — read the value from a server-controlled source or an environment-derived value that is not shipped to the browser, and ensure the frontend receives only non-secret URLs.
  3. Sanitize and validate organizationId before using it in apps/app/src/jobs/tasks/integration/run-integration-tests.ts. Enforce a strict format (e.g., UUID regex or numeric checks) at the entry point and use parameterized/ORM-bound queries so raw orgId values are never interpolated into DB queries.

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

* chore: add forced fail prop for testing

---------

Signed-off-by: Mariano Fuentes <marfuen98@gmail.com>
github-actions bot and others added 2 commits November 10, 2025 18:53
* chore: fix types

---------

Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
* feat(portal): add MDM policy on portal

* fix(portal): show MDM policy only on macOS

* fix(portal): update tooltip content for MDM policy

---------

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

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

🔒 Comp AI - Security Review

🔴 Risk Level: HIGH

OSV: ai@5.0.0 has GHSA-rwvc-j5jr-mgvh (low). Code findings: hardcoded tokens and scanAccessToken exposed to client; token placed in download URL; payload.organizationId used directly in a DB task file (injection risk).


📦 Dependency Vulnerabilities

🟢 NPM Packages (LOW)

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

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

🛡️ Code Security Analysis

View 8 file(s) with issues

🟡 .cursor/mcp.json (MEDIUM Risk)

# Issue Risk Level
1 Executing unpinned package via npx (trigger.dev@latest) MEDIUM
2 Runtime remote-code-execution / supply-chain risk from npx MEDIUM
3 Config uses --dev-only flag that may be ignored in prod MEDIUM

Recommendations:

  1. Pin the package to an exact, audited version (e.g., trigger.dev@1.2.3) or use an integrity-checked tarball to avoid fetching latest at runtime.
  2. Avoid runtime npx fetches in production. Install dependencies at build time (npm ci / yarn install) and use a lockfile or vendored binaries/artifacts.
  3. Use reproducible, signed releases or a package registry with checksum verification (or enable npm/yarn package-integrity checks) to reduce supply-chain risk.
  4. Treat runtime-executed tooling as untrusted: run in least-privilege containers, CI isolation, or ephemeral VMs and restrict network/credentials available to them.
  5. Remove or ensure dev-only flags are not referenced by production deployment configs. Validate that --dev-only cannot be ignored by your deployment process.
  6. Implement auditing/approval for scripts that execute remote code (code review, SBOM, dependency scanning, maintainers review) and block unpinned npx usage via CI policy.

🔴 apps/app/src/app/(app)/[orgId]/cloud-tests/actions/connect-cloud.ts (HIGH Risk)

# Issue Risk Level
1 Sensitive credentials may be logged via console.error HIGH
2 Unencrypted credentials are used/sent during validation/fetch HIGH
3 Auth token cookie set without HttpOnly/Secure/SameSite flags HIGH
4 revalidatePath called using unsanitized header-derived path HIGH
5 No rate limiting on credential validation (brute-force risk) HIGH
6 Arbitrary credential keys are stored directly in DB userSettings HIGH
7 Error messages returned to client may leak internal details HIGH

Recommendations:

  1. Avoid logging raw error objects that may contain sensitive data. Redact sensitive fields (credential names/values) before logging or replace console.error with a structured logger that strips secrets.
  2. Do not transmit raw credentials unnecessarily. Wherever possible, validate using ephemeral or limited-scope tokens or use a secure server-side vault/agent to perform validation. If credentials must be used for validation, ensure they are handled only in memory and never persisted or logged in plain text.
  3. Set cookie attributes explicitly when creating cookies: HttpOnly: true, Secure: true (for HTTPS), and SameSite: 'lax' or 'strict' as appropriate. Use a short expiration and consider storing only non-sensitive tokens in cookies, or use server-side sessions.
  4. Sanitize and whitelist revalidation targets before calling revalidatePath. Do not use raw header values. Derive the path from trusted server-side routing context when possible. If header-based fallback is necessary, validate against an allowlist of routes and normalize the path strictly.
  5. Add rate limiting/throttling on this action (per user/IP/organization) to prevent brute-force or credential stuffing attempts. Consider exponential backoff and lockouts on repeated failures.
  6. Restrict allowed credential keys (use an allowlist per provider) and validate key names and value formats before storing. Avoid storing arbitrary JSON keys supplied by user input directly into userSettings.
  7. Return generic error messages to callers and log detailed errors internally. Do not echo raw error.message contents to the client. Map internal errors to safe, user-friendly messages.

🟡 apps/app/src/app/(app)/[orgId]/cloud-tests/components/CloudConnectionCard.tsx (MEDIUM Risk)

# Issue Risk Level
1 Unvalidated guideUrl href may allow javascript: URLs (XSS/JS execution) MEDIUM
2 Credential inputs default to text, exposing secrets in UI and screenshots MEDIUM
3 Only non-empty validation; no format or semantic checks on inputs MEDIUM
4 Potential sensitive data exposure via console.error and toast messages MEDIUM
5 Credentials stored in client state and transmitted from browser MEDIUM
6 No client-side rate limiting; could enable brute-force attempts MEDIUM

Recommendations:

  1. Sanitize and validate guideUrl before rendering: allow only http(s) schemes and/or validate against a whitelist of permitted hosts/origins. Reject or normalize any javascript:, data: or other unsafe URI schemes. Keep rel="noopener noreferrer" but do not rely on it for URL sanitization.
  2. Treat secret fields as secrets in the UI: use type="password" (or a masked textarea pattern with a reveal toggle) for credentials, add autocomplete="new-password"/"current-password" as appropriate, and avoid showing sensitive values by default.
  3. Improve client- and server-side validation: enforce format/semantics for credential fields (e.g., ARN, key id length, JSON service account structure) and surface specific, non-sensitive validation errors to the user. Do not rely solely on non-empty checks.
  4. Avoid logging or displaying raw error objects and avoid including request/credential data in logs or toast messages. Sanitize error objects before logging (or log only safe metadata/error codes). Consider a central error-handling utility that redacts sensitive fields.
  5. Minimize client-side lifetime of secrets: keep credentials only in memory, clear them immediately after use (already partially done), and never persist to localStorage/sessionStorage. Ensure connectCloudAction uses secure transport (HTTPS) and that the receiving API validates and stores secrets securely (encryption-at-rest, access controls).
  6. Implement server-side rate limiting and brute-force protections (throttling, IP-based limits, exponential backoff). Do not rely on client-side rate limiting for security. Add monitoring/alerting on repeated failed connection attempts.
  7. Consider UX safeguards: show a confirmation and clear guidance before sending credentials, and surface safe progress/status messages rather than raw error payloads.

🟡 apps/app/src/app/(app)/[orgId]/cloud-tests/components/EmptyState.tsx (MEDIUM Risk)

# Issue Risk Level
1 Hardcoded token(s) in external logoUrl strings MEDIUM
2 External image URLs with embedded tokens can leak secrets MEDIUM
3 Cloud credentials kept in client state (credentials object) MEDIUM
4 Credentials sent to server actions without input sanitization MEDIUM
5 Insufficient input validation (no format checks for keys) MEDIUM
6 UI toasts may echo raw server errors exposing sensitive info MEDIUM
7 console.error may log sensitive server responses MEDIUM

Recommendations:

  1. Remove hardcoded tokens from client code. Do not embed API keys/tokens in front-end sources. If the token is required to fetch assets, proxy the request through your server or fetch the URL server-side and return a token-less asset URL.
  2. Avoid using external image URLs that include tokens. Serve logos from a trusted CDN or from your own server, or obtain any required tokens at runtime from a secure server endpoint (not baked into client code).
  3. Minimize lifetime and exposure of sensitive credentials in the browser: only keep them in memory briefly, clear state immediately after use (e.g., setCredentials({}) right after a successful send), and never persist them to localStorage/indexedDB. Consider using a secure server-side flow where credentials are entered only in a secure UI that posts directly to a server endpoint which handles secrets.
  4. Enforce strong server-side validation and sanitization of all credentials and input (do not rely on client-side checks). Ensure server actions validate formats, length, and allowed characters and apply rate limiting and logging controls to avoid leaking secrets in logs.
  5. Add format checks and client-side validation to improve UX (e.g., validate AWS Access Key ID format, UUID format for Azure IDs) but treat client validation as convenience only — the server must enforce correctness and reject malformed/unauthorized credentials.
  6. Do not display raw server error messages to end users. Sanitize or map server errors to safe, generic messages (e.g., 'Failed to validate credentials' instead of echoing server error text). Log full details server-side with controlled access for debugging.
  7. Avoid logging sensitive responses to the browser console. Remove or limit console.error calls that may include server responses or secrets. If you must log, ensure sensitive fields are redacted before logging.
  8. Use HTTPS for all requests and ensure server actions are authenticated and authorized. Apply the principle of least privilege for any credentials being used (scoped, minimal permissions). Consider using temporary/sts credentials or delegated authorization flows instead of long-lived secrets.

🔴 apps/app/src/app/(app)/[orgId]/cloud-tests/components/ResultsView.tsx (HIGH Risk)

# Issue Risk Level
1 Exposes scanAccessToken to client-side code HIGH

Recommendations:

  1. Move all uses of scanAccessToken (and any other sensitive tokens/keys) to server-side code. Perform API calls to cloud providers from the server or a trusted backend service so secrets are never shipped to the browser.
  2. If a client-side token is absolutely required, use a short-lived, narrow-scope token issued by the server (least privilege) and rotate/expire it quickly.
  3. Audit where scanAccessToken is created and ensure it is not persisted in client storage (localStorage/sessionStorage) or logged to client-side telemetry.
  4. Log full/raw error details only server-side. For the UI, show safe, minimal summaries (e.g., 'Integration X returned an error') and optionally a truncated error id/slug the user can reference when contacting support.
  5. Although React escapes interpolated strings (reducing XSS risk), still validate/sanitize/normalize external error objects server-side and truncate long messages before sending to the client to avoid large payloads or accidental disclosure of sensitive data.

🟡 apps/app/src/app/(app)/[orgId]/cloud-tests/components/TestsLayout.tsx (MEDIUM Risk)

# Issue Risk Level
1 Unescaped server-run error/output messages shown in toasts (XSS risk) MEDIUM
2 Public access token stored in client state (exposed to JS/XSS) MEDIUM
3 Trigger/taskId and token values accepted without strict validation MEDIUM

Recommendations:

  1. Sanitize and/or encode all server-sent strings before rendering in the UI. Treat runOutput.errors[], failedIntegrations[].error and scanRun.error.message as untrusted input. Use a proven HTML-encoder or escape function (or ensure the toast library renders text-only) before passing to toast.* APIs.
  2. Avoid storing sensitive tokens in JS-accessible storage (state, localStorage). Use httpOnly, Secure cookies or keep the token server-side and proxy calls through the server when possible. If a client-side token is unavoidable, make it short-lived, scope-limited, and rotateable.
  3. Validate formats for taskId and publicAccessToken before accepting/using them (e.g., strict regex, length limits, allowed characters). Reject or ignore malformed values and log suspicious attempts server-side.
  4. Suppress detailed internal error strings in user-facing UI. Show generic error notices e.g. "Scan failed" and provide a reference id for support; surface detailed error text only in safe admin logs or behind authenticated server endpoints.
  5. Harden XSS protections site-wide: Content-Security-Policy (CSP) with no-inline scripts, HTTPOnly cookies, input/output encoding, and audit use of any libraries that can render HTML from strings.
  6. When integrating realtime/run access tokens, enforce server-side validation and authorization checks that the token/taskId pair is valid for the current user/org before starting or subscribing to runs.

🔴 apps/app/src/jobs/tasks/integration/run-integration-tests.ts (HIGH Risk)

# Issue Risk Level
1 No authorization check for payload.organizationId HIGH
2 organizationId used directly in DB query (possible injection) HIGH
3 No input validation for payload fields (organizationId, forceFailure) HIGH
4 Integration settings/userSettings sent to batch may leak secrets HIGH
5 Raw errors and organizationId logged/returned, risking info disclosure HIGH
6 No protection against unauthorized or mass task triggering HIGH

Recommendations:

  1. Enforce authorization: verify the caller is permitted to run tests for payload.organizationId. Ensure the task runner checks the caller's identity/roles and that organizationId belongs to them before running the job.
  2. Validate and sanitize payload fields: require organizationId to match an expected format (UUID or DB id), reject invalid values, and validate forceFailure is a boolean. Use a central validation schema for task payloads.
  3. Defend DB access: continue using parameterized ORM queries (avoid constructing raw SQL). Additionally, validate organizationId before passing to the query and enforce least-privilege DB roles for the worker.
  4. Redact secrets from settings/userSettings before sending to the batch: identify sensitive keys (API keys, tokens, private keys) and remove or redact them. Send only the minimum necessary metadata. Consider using a sanitized view object or a allowlist of safe fields.
  5. Limit logging and returned data: avoid logging full organization IDs or raw error stacks. Log minimal identifiers (hashed or truncated IDs) and return non-sensitive error codes/messages to callers. Store detailed errors in a secure audit log accessible to authorized users only.
  6. Implement rate limiting, authentication, and audit trails for task triggers: ensure only authorized services/users can trigger this task, throttle requests to prevent mass triggering, and log who triggered what for later review.
  7. Handle errors safely: normalize and map internal errors to safe user-facing messages. When logging exceptions for debugging, ensure logs are access-controlled and scrub secrets.
  8. Avoid forceFailure exposure: require elevated privileges or a special environment flag to run forced failures (used for UI tests). Do not allow arbitrary callers to set forceFailure=true.
  9. Consider schema-level redaction/encryption: for particularly sensitive settings, store them encrypted and only decrypt/select required non-sensitive attributes for this job.

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

# Issue Risk Level
1 Token in download URL (leaks via Referer/logs; replayable/cached) MEDIUM
2 Displaying raw API error messages in UI (information leak) MEDIUM
3 Token-request endpoint may be callable without CSRF/auth checks MEDIUM

Recommendations:

  1. Do not put sensitive tokens in a URL query parameter. Instead: request the file via fetch with credentials (e.g., fetch('/api/download-agent?os=...') with the Authorization cookie/session automatically sent), receive the file as a blob, and create an object URL (URL.createObjectURL) or stream it to the client. This avoids token leakage via Referer headers, browser history, and logs.
  2. If a downloadable token must be used, make it single-use, short-lived (very small TTL), bound to the authenticated session and the requesting client (e.g., tie to session ID, IP fingerprint, or a nonce stored server-side), and mark it as consumed on first access.
  3. Avoid embedding raw server error text in client-facing toasts. Return a generic error message to the client (e.g., 'Failed to prepare download') and log the full error details server-side for debugging.
  4. Ensure the /api/download-agent/token endpoint enforces authentication and anti-CSRF protections. Require a valid session, verify the caller's identity (server-side), and validate CSRF tokens or use same-site cookies + stateful session checks to prevent cross-site requests from obtaining tokens.
  5. Serve files through authenticated streaming routes (server reads file and sets Content-Disposition attachment header) rather than redirecting to a URL that encodes secrets. This also allows the server to enforce authorization per-request.
  6. Consider adding a Referrer-Policy header (e.g., no-referrer or same-origin) to reduce accidental token leakage to third parties, and set appropriate cache-control headers to prevent intermediate caching of download responses that could include tokens.
  7. If you must use a client-side link, avoid placing secrets in the href. Use a POST-download flow or an ephemeral client-side fetch that returns the artifact as a blob and triggers a download.
  8. Validate and sanitize any inputs sent to the token endpoint (orgId/employeeId) server-side and do not rely solely on client-supplied values for authorization decisions.

💡 Recommendations

View 3 recommendation(s)
  1. Upgrade the vulnerable dependency: update ai to >=5.0.52 in package.json and regenerate the lockfile so the fixed version is installed (GHSA-rwvc-j5jr-mgvh).
  2. Remove hardcoded tokens from frontend sources (e.g., EmptyState.tsx) and stop sending sensitive tokens to the browser (e.g., scanAccessToken in ResultsView.tsx). Avoid placing tokens in href/query params (DeviceAgentAccordionItem.tsx); perform token operations on the server and return non-sensitive artifacts to the client.
  3. Sanitize and validate payload.organizationId in apps/jobs/tasks/integration/run-integration-tests.ts before use: enforce strict format (UUID or database id regex), reject invalid values, and supply the validated value to parameterized ORM queries (do not concatenate user input into query strings).

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

@vercel vercel bot temporarily deployed to staging – app November 10, 2025 23:55 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.

* refactor: dont crash trigger on cloud tests job

* chore: fix types

* chore: add forced fail prop for testing

* chore: fix types

* refactor(cloud-tests): integrate trigger token creation and update session handling

* refactor(cloud-tests): remove debug console logs from TestsLayout

* chore: remove leftover code

---------

Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
@vercel vercel bot temporarily deployed to staging – portal November 11, 2025 14:26 Inactive
@Marfuen Marfuen merged commit 9007411 into release Nov 11, 2025
10 of 11 checks passed
@claudfuen
Copy link
Contributor

🎉 This PR is included in version 1.57.0 🎉

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