Skip to content

Conversation

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented Nov 4, 2025

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

github-actions bot and others added 2 commits October 31, 2025 17:24
* fix(portal): download relevant device agent per macOS chip on portal

* fix(portal): fix portal build issue

* fix(portal): add log for testing

* fix(portal): add log for testing

---------

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

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

🔒 Comp AI - Security Review

🔴 Risk Level: HIGH

No OSV/NPM CVEs detected. Code contains a hardcoded client API token and multiple input-sanitization/injection issues (unsanitized automationId in runs route; S3 key extraction/path traversal).


📦 Dependency Vulnerabilities

✅ No known vulnerabilities detected in dependencies.


🛡️ Code Security Analysis

View 18 file(s) with issues

🟡 .github/workflows/trigger-tasks-deploy-main.yml (MEDIUM Risk)

# Issue Risk Level
1 Secrets may be exposed in logs due to --log-level debug MEDIUM
2 Secrets passed as env may be printed by tools or actions MEDIUM
3 Third-party actions use tag refs instead of pinned SHAs MEDIUM
4 Running bunx executes package code during deploy MEDIUM
5 No explicit minimal permissions set for GITHUB_TOKEN MEDIUM

Recommendations:

  1. Remove the --log-level debug flag in CI deploy runs. Avoid enabling verbose or debug logging when executing deployments that have secrets available in the environment.
  2. Never print or echo secrets in workflows. Ensure third-party tools invoked (bunx, trigger.dev CLI, etc.) are configured not to output secrets in logs. If debug-level output is needed for troubleshooting, run in a private environment and rotate any secrets afterwards.
  3. Pin actions to immutable commit SHAs instead of major/minor tags (e.g., actions/checkout@ and actions/setup-node@). Do the same for oven-sh/setup-bun and any other external actions.
  4. Audit any third-party CLI/packages executed in the workflow (bunx trigger.dev@4.0.6 deploy and bunx invocation) to ensure they are trusted and to understand what information they may log. Consider running builds in an environment that limits access to secrets or use verified/pinned package releases. Prefer using pre-built, vetted artifacts or container images where possible.
  5. Explicitly set minimal GITHUB_TOKEN permissions in the workflow (permissions:) to only what the job needs (e.g., contents: read) and avoid giving write permissions unless required. Prefer using GitHub OIDC or short-lived provider tokens for cloud services (Vercel, Trigger.dev) instead of long-lived secrets when supported.
  6. If secret exposure is suspected or debug logs were enabled previously, rotate affected secrets (TRIGGER_ACCESS_TOKEN, SECRET_KEY, VERCEL_ACCESS_TOKEN, etc.) immediately.

🔴 .github/workflows/trigger-tasks-deploy-release.yml (HIGH Risk)

# Issue Risk Level
1 Secrets passed as env to bunx may be leaked in logs HIGH
2 bunx trigger.dev@4.0.6 executes remote package code with secrets HIGH
3 Uses action tags (e.g. actions/setup-node@v4) instead of pinned SHAs HIGH
4 Custom runner 'warp-ubuntu-latest-arm64-4x' may expose secrets to operators HIGH
5 No environment protection or required approvals for release deploys HIGH

Recommendations:

  1. Do not pass sensitive secrets directly to unvetted third-party code runs. Where possible, use short-lived tokens, OIDC-issued tokens, or intermediate deploy tokens with least privilege instead of long-lived/secrets env vars.
  2. Avoid executing remote package code that you do not control with secrets in the environment. Vendor or pin the exact package version and audit it, or run untrusted package operations in an isolated environment without secrets.
  3. Pin GitHub actions and remote packages to exact commit SHAs (or verifiable checksums) instead of mutable tags to prevent supply-chain upgrades that introduce malicious code.
  4. Use GitHub Environments for production deployments, require reviewers/approvals for the release environment, and enable environment protection rules so critical secrets are only exposed after human approval.
  5. Restrict workflow permissions to the minimum required (use permissions: { } block), and scope tokens (VERCEL, TRIGGER) to the least privilege needed for deployment; rotate credentials frequently.
  6. If using self-hosted or custom runners, harden them: limit operator access, enable runner isolation, audit and monitor runner activity, and avoid exposing secrets to runners that are not fully trusted.
  7. Ensure CI logs do not leak secrets: avoid printing env variables, enable secret masking, and catch/handle errors that might include secret values in stack traces.

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

# Issue Risk Level
1 Console logs full request URL (may leak sensitive query params) HIGH
2 Returning enterprise API error messages to clients (info disclosure) HIGH
3 RevalidateCurrentPath uses untrusted headers (path injection) HIGH
4 Shared server-side enterprise API key for all requests (privilege escalation) HIGH
5 No input validation for uploaded scripts/messages (malicious content/storage risk) HIGH
6 Console.error prints entire error objects to logs (sensitive data leak) HIGH
7 runId sent as query param due to template bug (ID leakage in URL/logs) HIGH

Recommendations:

  1. Remove or redact URL logging: remove console.log('url', url.toString()) or sanitize url before logging. Ensure query parameters that may contain secrets/IDs (e.g., key, runId) are redacted before being logged.
  2. Do not return raw enterprise API error messages to clients. Return generic messages (e.g., 'Internal error') while logging full details server-side with access controls for debugging.
  3. Validate and sanitize values used in revalidatePath. Do not use untrusted headers directly. Maintain a whitelist of allowed internal paths or parse and normalize the pathname strictly before calling revalidatePath.
  4. Enforce authorization checks per user/org before performing actions that use the server-side enterprise API key. Consider using per-org tokens or include server-side validation of the caller's permissions to avoid privilege escalation from any authenticated user.
  5. Add input validation and limits for uploaded scripts and chat messages: enforce type checks, size limits, content scanning (e.g., disallow binary or extremely large uploads), and rate limiting. Sanitize or escape any content written into your DB or passed to other subsystems.
  6. Avoid logging entire Error objects to console in production. Use structured logging with PII-sensitive fields redacted and ensure logs are restricted and rotated. Log stack traces only where necessary in secure logging environments.
  7. Fix the template string bug in getAutomationRunStatus: either embed runId into the path properly using backticks (/api/.../runs/${runId}) if the API expects a path param, or intentionally keep it as a param but be aware it will appear in the query string. In either case, avoid logging the full URL with sensitive IDs.

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

# Issue Risk Level
1 Unsanitized changelog passed to publishAutomation (user input to server) MEDIUM
2 Unsanitized URL params (orgId, taskId) sent to server actions MEDIUM
3 User-controlled automationId passed to executeAutomationScript MEDIUM
4 No input validation or length limits on changelog MEDIUM
5 Raw error.message shown to user via toast (information disclosure) MEDIUM
6 No client-side auth checks before invoking publish/run MEDIUM

Recommendations:

  1. Enforce server-side validation and sanitization for all inputs received from the client (changelog, orgId, taskId, automationId). The client cannot be trusted; validate types, formats (e.g., UUIDs or numeric IDs), allowed characters, and lengths on the server.
  2. Apply length limits and content validation both client- and server-side for the changelog (e.g., max length, disallow control chars). Reject or truncate overly large payloads server-side to avoid DoS/resource exhaustion.
  3. Treat IDs as opaque typed values and validate them strictly (e.g., regex or UUID parse). Reject requests with unexpected characters or lengths before using them in downstream calls/queries.
  4. Ensure server actions (publishAutomation, executeAutomationScript) use safe data handling (parameterized DB queries/ORM; avoid concatenating inputs into command strings). Review server code paths for SQL/command injection or unsafe eval usage.
  5. Do not surface raw error.message to end users. Return a generic error message to the UI and log full details securely server-side (with correlation IDs) for debugging.
  6. Enforce authentication and authorization server-side for publish/run actions. On the client, conditionally render controls based on the authenticated user's permissions to reduce accidental misuse, but do not rely on client checks for security.
  7. Add rate limiting and request size limits on endpoints that accept free-form text to mitigate abuse.
  8. When displaying user-supplied text (changelog) in the UI, ensure proper encoding/escaping to prevent XSS. Sanitize or escape when rendering HTML contexts.

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

# Issue Risk Level
1 Missing validation of message.parts and props (XSS/injection risk) MEDIUM
2 Dynamic content passed to MessagePart without sanitization MEDIUM

Recommendations:

  1. Validate incoming message shape with a strict schema (e.g., zod, ajv) on the server and re-validate on the client before rendering.
  2. Sanitize or escape any user-controlled text that may be injected as HTML. Avoid using dangerouslySetInnerHTML; if you must, sanitize with a well-audited library (e.g., DOMPurify) on the server or before use.
  3. Audit the MessagePart implementation: ensure it does not use dangerouslySetInnerHTML or other raw HTML insertion for untrusted content.
  4. Remove or reduce unchecked 'any' casts; use precise TypeScript types for message parts and states so untrusted fields are explicit and validated.
  5. Validate orgId and other props server-side where they affect data access or storage. Treat callbacks (onSecretAdded/onInfoProvided) as trusted only after validating inputs they receive.
  6. Log and monitor unusual content (e.g., HTML tags in message text) so you can detect attempted XSS payloads in messages.

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

# Issue Risk Level
1 Unvalidated user input sent to updateEvaluationCriteria; may enable server-side injection MEDIUM

Recommendations:

  1. Treat this as untrusted input on the server. Validate and sanitize the criteria server-side before any use.
  2. Enforce authorization in the server-side implementation of updateEvaluationCriteria so only permitted users can update criteria.
  3. Apply strict input validation: enforce maximum length, allowed character set, and a clear format (or a strict schema) for criteria strings.
  4. Never construct SQL/OS/command/eval strings from this input. Use parameterized queries/ORM APIs for any DB operations; do not concat user input into queries or commands.
  5. If the criteria are parsed/interpreted on the server (e.g., as mini-language), use a safe parser (no eval) and a whitelist of operations; sandbox parsing if possible.
  6. When rendering stored criteria back to clients, ensure proper escaping or use safe rendering libraries to avoid XSS. Prefer React/JSX escaping and avoid dangerouslySetInnerHTML.
  7. Add server-side logging/monitoring and input rate limits to detect abuse or injection attempts.
  8. Add client-side limits and validation as a convenience, but do not rely on it for security — enforce rules on the server.

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

# Issue Risk Level
1 Hardcoded API token in image URL query string HIGH
2 Unvalidated integration.link used to build external image URL HIGH

Recommendations:

  1. Remove the hardcoded token from client code. Never embed secrets (API keys, tokens, private credentials) in frontend code or checked-in source.
  2. Move logo fetching through a server-side endpoint (proxy) that injects any required secrets or signs requests. The server can store tokens in env vars and rotate them securely.
  3. Use short-lived signed URLs or require authorization headers (set by the server) instead of putting tokens in URL query parameters.
  4. Validate and/or allowlist integration.link values before using them to build URLs. Only accept known provider identifiers (e.g., from a server-side whitelist) or canonicalized values.
  5. Sanitize and encode dynamic path segments (e.g., using encodeURIComponent) before inserting into a URL to prevent path manipulation. Ensure the domain is fixed and not controllable by user input.
  6. If Next/Image optimization is needed, use a server-side loader with controlled domain allowlist so the server, not the client, fetches external images if secrets are required. If unoptimized is used, be aware the token will be exposed in client-side network requests and logs.

🟡 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/workflow/workflow-visualizer-simple.tsx (MEDIUM Risk)

# Issue Risk Level
1 Missing validation of orgId/taskId/automationId before API actions MEDIUM
2 Unsanitized execution data and logs sent to AI via sendMessage MEDIUM
3 Client lacks explicit auth/permission checks before destructive actions MEDIUM
4 Detailed internal error messages shown to users via toasts MEDIUM

Recommendations:

  1. Validate and normalize orgId/taskId/automationId on the client before calling APIs (e.g., ensure non-empty, correct format). More importantly, enforce strict server-side validation and authorization for all endpoints used (restoreVersion, execute, etc.) so malicious/forged requests are rejected.
  2. Sanitize or redact sensitive fields from executionResult.data and logs before including them in messages sent to external AI services. Replace secrets, tokens, PII with placeholders. Consider server-side redaction/logging if sensitive data may appear.
  3. Require server-side permission checks for destructive actions (restore/overwrite). On the client, conditionally hide/disable destructive UI for unauthorized users based on securely obtained permission claims (but do not rely on this alone).
  4. Show generic error messages to end users (e.g., "Action failed, please try again") and log full error details only to internal logs with restricted access. Avoid passing raw error.message to toast in production.
  5. Add defensive client-side type checks/guard clauses before calling actions (ensure automationIdRef.current !== 'new', orgId/taskId are set, confirm version exists). Use centralized validation helpers where possible.
  6. Audit sendMessage usage to external models: add consent/notice if user data is sent to third-party AI models and limit the scope of data forwarded. Consider routing AI-related requests through a server-side proxy that can enforce redaction and rate limits.

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

# Issue Risk Level
1 Missing validation: URL params used directly in API path MEDIUM
2 Console logs may leak sensitive server data to client MEDIUM

Recommendations:

  1. Validate and sanitize orgId, taskId, and automationId on the client before using them (e.g., enforce expected patterns/lengths/characters).
  2. Encode path segments when building URLs: use encodeURIComponent(taskId) and encodeURIComponent(automationId) when interpolating into the path.
  3. Ensure server-side validation and authorization checks are in place and do not rely on client-side validation alone. The backend must validate that the authenticated principal can access the requested organization/task/automation.
  4. Remove or guard console.log statements that print server responses or errors. If logs are needed for debugging, gate them behind an environment flag and never log raw server error payloads in production.
  5. Return sanitized/generic error messages to the client instead of propagating raw backend error text; keep detailed errors in server logs (not client console).
  6. Handle unexpected path content safely (e.g., strip or reject path separators, control characters) so crafted params cannot change the intended URL structure.

🟡 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automations/[automationId]/overview/components/AutomationOverview.tsx (MEDIUM Risk)

# Issue Risk Level
1 Unsanitized URL params (orgId/taskId/automationId) used in API/actions MEDIUM
2 User-supplied description sent to PATCH without validation/sanitization MEDIUM
3 Client triggers server-side script execution with unvalidated inputs MEDIUM
4 No client-side authorization checks before toggle/test/delete actions MEDIUM

Recommendations:

  1. Enforce server-side validation and sanitization for orgId, taskId, automationId (treat them as untrusted). Validate format (UUID/numeric/whitelisted slugs) and ensure they map to resources owned by the requesting principal.
  2. Perform server-side validation of description: enforce length limits, strip/encode dangerous characters or use a safe HTML sanitizer if rendering as HTML. Implement server-side validation rules rather than relying on client checks.
  3. Whitelist/validate version values server-side (ensure version is an expected integer and belongs to the specified automation). Reject or coerce anything outside the valid set. Never execute scripts based solely on client-supplied values.
  4. Always enforce authorization and permission checks server-side for toggle, test, delete, and execute actions. The client may hide UI, but server must verify the caller has rights to perform the action on the given org/task/automation.
  5. Harden server-side action handlers that perform script execution: validate inputs, run in a sandboxed context, apply timeouts/resource limits, and log audit events.
  6. Avoid returning internal error details to clients. Return safe, generic error messages and log detailed errors server-side with correlation IDs.
  7. Add CSRF protections / require authenticated API tokens for mutation endpoints, and consider rate-limiting sensitive operations.
  8. On the client, add defensive checks (e.g., ensure selectedVersion is numeric before sending) to improve UX, but do not rely on them for security.

🟡 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automations/[automationId]/overview/hooks/use-automation-runs.ts (MEDIUM Risk)

# Issue Risk Level
1 Unvalidated automationId in API request (IDOR risk) MEDIUM

Recommendations:

  1. Enforce server-side authorization on GET /api/automations/:id/runs to ensure the requesting user is allowed to view runs for the specified automation (prevent IDOR). Never rely solely on client-side checks.
  2. Validate and strictly type automationId on the server (e.g., require UUID format or numeric ID and reject invalid values). Client-side validation is optional UX only.
  3. Escape/encode path segments on the client: use encodeURIComponent(automationId) when building the URL to avoid malformed requests and injection of special characters.
  4. Check the HTTP response status before calling res.json(): if (!res.ok) { handle error } to avoid parsing unexpected responses and leaking sensitive UI behavior.
  5. Add rate-limiting and exponential backoff for the polling mechanism to reduce potential abuse (e.g., increase interval on errors or use a capped backoff strategy).
  6. Log and monitor suspicious access patterns server-side (requests for many different automationId values) to detect potential enumeration or abuse.

🔴 apps/app/src/app/(app)/setup/actions/create-organization-minimal.ts (HIGH Risk)

# Issue Risk Level
1 Revalidation path taken from untrusted headers HIGH
2 Auto-enable hasAccess for non-prod or @trycomp.ai emails HIGH
3 Raw error.message returned to client (information leak) HIGH
4 Organization name and context.answer not sanitized (stored XSS risk) HIGH
5 frameworkIds not validated against allowed IDs HIGH
6 No rate limiting or duplicate-org checks (resource exhaustion) HIGH

Recommendations:

  1. Validate and sanitize header-derived path before calling revalidatePath. Allow only a whitelist of known internal routes or canonicalize paths using server-side routing logic. Do not trust user-supplied Referer or custom headers for control-flow decisions.
  2. Remove automatic hasAccess enabling or require stronger checks: ensure email ownership (email verification) and/or require admin approval. Never auto-grant elevated access based solely on an email suffix or non-production environment.
  3. Do not return raw error.message to clients. Return a generic error to the client (e.g., 'Failed to create organization') and log the full error and stack trace server-side with structured logging and monitoring.
  4. Sanitize or escape free-text fields before persisting if they will ever be rendered in HTML (server-side or client-side). Better: enforce safe encoding on output (escape on render) and/or sanitize inputs with a vetted library (or apply a whitelist of allowed characters).
  5. Validate frameworkIds against a server-side allowlist / existing frameworks table before using them to initialize organization structure. Reject unknown IDs or coerce to a known canonical form.
  6. Add server-side rate limiting and anti-automation controls on this action. Add duplicate-org checks (e.g., same owner + organization name or domain) to avoid mass creation. Consider CAPTCHA or other anti-abuse measures for public endpoints.

🟡 apps/app/src/app/(app)/setup/actions/create-organization.ts (MEDIUM Risk)

# Issue Risk Level
1 Exposes publicAccessToken in response and stores in non-HttpOnly cookie MEDIUM
2 Returns internal error.message to clients (information leak) MEDIUM
3 Writes user input directly to DB without sanitization MEDIUM
4 Auto-enables hasAccess for non-prod env or @trycomp.ai emails MEDIUM
5 Potential CSRF: state-changing action may lack anti-CSRF protections MEDIUM

Recommendations:

  1. Remove publicAccessToken from API responses; don't expose tokens
  2. Set cookie with HttpOnly, Secure and SameSite flags; avoid client JS access
  3. Return generic errors to clients; log detailed errors server-side
  4. Validate and sanitize parsedInput before DB writes; enforce input schema
  5. Restrict auto-enable logic; use feature flags and strict env checks

🔴 apps/app/src/app/api/automations/[automationId]/runs/route.ts (HIGH Risk)

# Issue Risk Level
1 No authentication/authorization for GET runs HIGH
2 automationId used directly in DB query without validation HIGH
3 Potential SQL injection via unsanitized automationId input HIGH
4 Detailed error logging may expose sensitive info in logs HIGH

Recommendations:

  1. Enforce authentication and authorization on this route. Verify the caller is authenticated and authorized to access the specified automationId (e.g., ensure the automation belongs to the requesting user or team). Use Next.js middleware or a centralized auth layer.
  2. Validate and constrain automationId before using it in the DB query. Require a specific format (e.g., UUID or numeric ID), check length, and reject/return 400 for invalid values. Use a validation library (zod, yup, Joi) or built-in checks.
  3. Confirm that your ORM (Prisma) is used with parameterized queries and avoid any use of raw SQL (db.$queryRaw) with user input. Although ORMs typically parameterize values, still validate inputs and never interpolate user input into raw SQL.
  4. Avoid logging full error objects or stack traces to logs that may be accessible to less-privileged systems. Log sanitized, minimal messages and/or an error ID for support. Use structured logging with redaction for sensitive fields.
  5. Return appropriate status codes (403 for unauthorized, 404 for not found) instead of generic 500 when applicable, to avoid leaking information about resource existence to unauthorized callers.
  6. Implement rate-limiting and monitoring to reduce risk of ID enumeration and brute-force discovery of automationIds.
  7. Add unit/integration tests that cover invalid/malicious automationId values to ensure validation and auth checks are enforced.

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

# Issue Risk Level
1 Download token exposed in URL query string (logs/referrer/history) MEDIUM
2 Missing validation: member IDs and os param sent to token/download endpoints MEDIUM
3 Client trusts member props to request token without server-side auth checks MEDIUM
4 Potential CSRF risk on POST /api/download-agent/token if server relies on cookies MEDIUM

Recommendations:

  1. Do not place sensitive tokens in URL query parameters. Instead, deliver the file in the POST response (stream/file attachment) or use a one-time short-lived server-side download endpoint that does not expose the token in the URL.
  2. Bind issued download tokens to the authenticated server-side session/user (e.g., user ID from server session, IP, user-agent) and make them single-use and very short-lived (seconds to minutes).
  3. Validate all inputs server-side: verify the orgId/employeeId provided in the POST body actually belong to the authenticated user and validate/whitelist the os parameter before issuing any token or download.
  4. Require strong server-side authentication for token issuance (Authorization header or server session verification) and avoid relying solely on cookies unless proper CSRF protections are in place.
  5. Add CSRF protections on the /api/download-agent/token endpoint (CSRF tokens, SameSite=strict cookies, or require an Authorization header) and apply rate limiting and logging/monitoring for abuse.
  6. When offering a download link, consider returning a server-generated ephemeral path (not a query token) or streaming the file directly so the browser history/referrer cannot leak the token.

🔴 apps/portal/src/app/api/download-agent/route.ts (HIGH Risk)

# Issue Risk Level
1 Download token passed in URL query (referrer/history/log exposure) HIGH
2 Unvalidated 'os' param used in Content-Disposition header (CRLF/header injection) HIGH
3 Unvalidated 'os' used to pick filenames/scripts (path/header risks) HIGH
4 Untrusted orgId/employeeId injected into generated script (client-side injection) HIGH
5 No rate limiting or brute-force protection on token retrieval HIGH
6 Token deleted immediately after KV read even if download fails (can cause DoS) HIGH
7 Streaming archive creation from remote streams may allow resource exhaustion (DoS) HIGH

Recommendations:

  1. Avoid placing one-time tokens in URL query parameters. Use an Authorization header or POST body for single-use tokens, and ensure short TTLs. If query tokens must remain, mark them for one-time use and ensure consumers understand referrer leakage risk.
  2. Whitelist and strictly validate the 'os' parameter against known values (e.g., 'macos', 'macos-intel', 'windows'). Reject any unknown values. Additionally, sanitize/encode the value before embedding in headers or filenames and strip/deny CRLF characters to prevent header injection.
  3. Do not rely on a TypeScript cast to validate 'os'. Make getScriptFilename/getPackageFilename/getReadmeContent accept only validated enum values. Use a server-side mapping from validated os -> allowed filenames/content instead of interpolating raw input.
  4. Treat orgId and employeeId as untrusted when embedding them into generated scripts. Escape/encode them appropriately for the target script language (PowerShell/Batch). Consider generating signed parameters the agent can verify rather than directly embedding arbitrary identifiers.
  5. Add rate limiting and brute-force protections on the token endpoint (per-IP and per-account limits), logging and monitoring for repeated failed attempts, and optional progressive delays or temporary bans for suspicious activity.
  6. Do not delete the token from KV before a successful delivery. Consider a two-state approach: mark token as 'in-use' and only remove it after the response has been successfully streamed/completed, or provide short re-use windows and atomic status updates so failed deliveries can be retried.
  7. Harden streaming and archive logic: enforce maximum file sizes, validate S3 object sizes before streaming, apply streaming timeouts, backpressure limits and memory caps. Use a maximum archive size and fail fast if inputs exceed quotas. Consider generating presigned S3 URLs for direct client download for large files instead of proxying through your server.
  8. Sanitize any values written to logs to avoid leaking tokens or sensitive identifiers. Ensure S3 access is limited by least privilege and consider presigned URL usage to avoid serving large binaries through the app server.

🟡 apps/portal/src/app/api/download-agent/utils.ts (MEDIUM Risk)

# Issue Risk Level
1 Missing input validation: userId and orgId used directly in DB queries MEDIUM
2 Information disclosure via logs: userId/orgId are logged in clear MEDIUM
3 Distinct responses allow user/org enumeration via error messages MEDIUM

Recommendations:

  1. Validate and sanitize userId and orgId early (e.g., enforce expected type/format such as UUID v4 with a strict regex or a schema validator like zod/joi). Fail fast with a generic error if invalid.
  2. Do not rely solely on ORM behavior for application-layer checks. Although ORMs typically parameterize queries (mitigating SQL injection), still validate inputs to avoid logic bugs and unexpected behavior.
  3. Redact or omit sensitive identifiers from logs. If logging is required, mask parts of the ID (e.g., show only last 4 chars) and mark logs as sensitive.
  4. Return generic error messages to callers (e.g., "resource not found" or "unauthorized") instead of distinct messages that reveal whether a member or organization exists.
  5. Perform proper authorization/permission checks after lookup: ensure the requesting principal is allowed to access the member/org resource (roles, scopes, tenant checks).
  6. Consider rate-limiting and monitoring for enumeration attempts and add audit logging (with redaction) for suspicious activity.

🔴 apps/portal/src/utils/s3.ts (HIGH Risk)

# Issue Risk Level
1 Path traversal bypass via double-encoded sequences in extractS3KeyFromUrl HIGH
2 Presigned URL functions allow arbitrary bucket/key without authorization checks HIGH
3 expiresIn parameter not validated, enabling long-lived presigned URLs HIGH
4 Long-lived static AWS credentials from env; no IAM role or STS usage HIGH
5 Exported s3Client exposes broad credentials and can be misused internally HIGH

Recommendations:

  1. Normalize and fully decode input in extractS3KeyFromUrl (apply repeated percent-decoding or reject percent-encoded reserved sequences). After decoding, canonicalize the path (e.g., resolve '.' and '..') and then run traversal checks. Alternatively, use a strict whitelist of allowed key prefixes/patterns rather than generic traversal checks.
  2. Restrict getPresignedDownloadUrl and getPresignedUploadUrl with authorization checks. Validate that the calling user/service is allowed to request presigned URLs for the requested bucket/key. Enforce a server-side bucket whitelist and key-prefix whitelist to prevent signing arbitrary buckets/keys.
  3. Enforce a maximum expiresIn value (e.g., <= 3600) and validate the input is numeric and within allowed bounds. Do not rely on the client to set expiry. Consider removing the expiresIn parameter from callers and using a server-configured constant.
  4. Avoid embedding long-lived AWS credentials in environment variables for production. Prefer IAM roles (EC2/ECS/Lambda task roles) or STS temporary credentials with least privilege. Rotate keys and ensure the credentials in env have minimal permissions (scoped to necessary buckets and operations).
  5. Do not export the raw S3 client for general use. Provide a narrow wrapper API that implements least privilege operations (signed URLs, fetch agent artifact) and enforces authorization and input validation. If the client must be exported, restrict its permission scope via IAM and audit its usage.

💡 Recommendations

View 3 recommendation(s)
  1. Remove the hardcoded token in apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/workflow/components/UnifiedWorkflowCard.tsx. Do not embed secrets in frontend code: fetch images via a server-side endpoint that validates the requester and returns a signed URL or proxies the image so tokens are not exposed in client code or URLs.
  2. Harden apps/app/src/app/api/automations/[automationId]/runs/route.ts by validating automationId (e.g., require UUID or numeric ID with strict checks) and rejecting invalid values. Ensure all DB access uses parameterized ORM methods (no string interpolation into raw SQL) so user-supplied IDs cannot alter queries.
  3. Fix apps/portal/src/utils/s3.ts (extractS3KeyFromUrl) to fully percent-decode and canonicalize the path before use, then reject any path containing '..' or other traversal segments. Enforce a server-side allowlist of permitted key prefixes/buckets when generating presigned URLs and validate inputs tightly.

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

@vercel
Copy link

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

@CLAassistant
Copy link

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

Co-authored-by: chasprowebdev <chasgarciaprowebdev@gmail.com>
github-actions bot and others added 2 commits November 6, 2025 15:10
* fix: auto enable automation when publishing

* fix: show success criteria on first render

* fix(TestResultsPanel): use actual evaluation criteria for rendering

* fix(TestResultsPanel): use shared chat context for automation ID

* feat(automation): add file writing activity component and version handling

* feat(automation): enhance publish dialog with post-publish options and version testing

* fix(automation): update SWR type for automation runs data

---------

Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
* fix(portal): download relevant device agent per macOS chip on portal

* fix(portal): fix portal build issue

* fix(portal): add log for testing

* fix(portal): add log for testing

* fix(portal): put a dropdown to allow users to select macOS chip type for downloading agent

* style(portal): fix prettier lint errors

---------

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 6, 2025

🔒 Comp AI - Security Review

🔴 Risk Level: HIGH

No OSV CVEs found. Scan reports high‑risk code issues: a hardcoded API token in UnifiedWorkflowCard.tsx and multiple injection vectors (script/embed, SQL/path, stored XSS) in download-agent and automation run routes.


📦 Dependency Vulnerabilities

✅ No known vulnerabilities detected in dependencies.


🛡️ Code Security Analysis

View 14 file(s) with issues

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

# Issue Risk Level
1 Unvalidated header used in revalidatePath allows arbitrary path revalidation HIGH
2 Console.log of full URL may leak internal endpoints or query params HIGH
3 API error messages returned to clients may leak sensitive info HIGH
4 No validation/sanitization of uploaded script content (uploadAutomationScript) HIGH
5 No validation of scriptContent sent to analyzeAutomationWorkflow HIGH
6 No validation/sanitization of messages saved (saveChatHistory) — stored data injection/XSS risk HIGH
7 User-supplied params appended directly to URL without validation HIGH
8 NEXT_PUBLIC_ENTERPRISE_API_URL exposes API URL to client bundles HIGH

Recommendations:

  1. Validate and sanitize header-derived paths before calling revalidatePath. Only allow a whitelist of known paths or enforce that the path belongs to the same application origin and pattern (e.g., startsWith('/app/') and no ../ sequences). Do not trust Referer or custom headers for authorization or control flow.
  2. Remove or redact server-side logging of full URLs that include query parameters or secrets. Log only non-sensitive metadata (e.g., endpoint path without query string) or a request id. Ensure server logs are access-controlled.
  3. Do not return raw backend/third-party error messages directly to clients. Return generic client-friendly errors and log the detailed error (stack, response body, status) server-side for debugging.
  4. Validate and sanitize uploaded script content: enforce size limits, allowed content types/character sets, scanning for malicious payloads, and limit what can be executed downstream. Consider storing raw scripts in a safe storage and only allowing execution in a hardened sandbox.
  5. Validate scriptContent before sending to analysis endpoint: enforce size/length, reject binary data, and if analysis triggers execution, ensure sandboxing and resource limits are applied by the enterprise API.
  6. Sanitize and validate chat messages before persisting or re-rendering to prevent stored XSS. Escape output on render, enforce maximum message sizes, strip/encode HTML, and consider an allow-list of permitted formatting.
  7. Validate and canonicalize any user-provided params before appending to outbound URLs (e.g., runId, orgId, automationId, key). Enforce expected formats (UUID, numeric, safe string) and reject unexpected values to avoid request-smuggling/parameter pollution or unintended API behaviour.
  8. Use a server-only environment variable for internal API URL and secrets (avoid NEXT_PUBLIC_ prefix). Ensure enterprise API URL and secret are not exposed to client bundles. Restrict enterprise API secret to server runtime only.
  9. Add input length checks and rate limiting on endpoints that accept large payloads (scripts, messages) to mitigate DoS or resource exhaustion.
  10. Ensure the enterprise API trust boundary is well-defined. Consider mutual TLS, IP allowlisting, or internal networking so that crafted params can’t be leveraged to access unintended resources.
  11. When calling external/internal APIs, validate responses before using them. Avoid reflecting third-party response content directly into application state or error messages.

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

# Issue Risk Level
1 Unsanitized inputs (changelog, orgId, taskId, automationId) sent to server actions MEDIUM
2 Changelog has no length or content validation MEDIUM
3 Automatic post-publish run may execute unvalidated automation code MEDIUM
4 Detailed exception messages shown to users (possible info leak) MEDIUM

Recommendations:

  1. Sanitize and validate changelog and route params server-side
  2. Enforce length/content limits for changelog client and server
  3. Require server-side auth/authorization checks for publish/run actions
  4. Avoid auto-running published versions; require explicit user confirmation
  5. Show generic errors to users; log detailed errors server-side

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

# Issue Risk Level
1 Unsanitized user content (message.parts) may enable XSS MEDIUM
2 message prop and parts are used without runtime validation MEDIUM
3 Unvalidated orgId is forwarded to MessagePart (possible IDOR/privilege risk) MEDIUM
4 Extensive use of any hides type/runtime checks, enabling malformed input MEDIUM

Recommendations:

  1. Sanitize/escape all user-generated content before rendering. Verify MessagePart does not use dangerouslySetInnerHTML or insert raw HTML. If you need to render HTML, run it through a sanitizer (e.g., DOMPurify) on the client or sanitize on the server.
  2. Add runtime validation/type guards for the message object and its parts (e.g., zod/io-ts/run-time checks) before using fields. Fail safely when shapes don't match.
  3. Treat orgId as an untrusted value on the client. Enforce authorization on the server for any org-scoped operations and validate the orgId server-side; do not rely on client-side checks.
  4. Reduce use of any. Replace with precise TypeScript types and add runtime checks where necessary so malformed/malicious input cannot bypass expected structure. Audit code paths that consume parts for assumptions about shape/state.
  5. Audit MessagePart and downstream components for unsafe rendering patterns (innerHTML, eval, new Function) and sanitize any data used in such contexts.
  6. Log/monitor unexpected part types/states and fail-closed on malformed streaming state to avoid logic mistakes that could expose sensitive info.

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

# Issue Risk Level
1 No input validation before sending criteria to server MEDIUM
2 Potential stored XSS if server renders criteria unsanitized MEDIUM

Recommendations:

  1. Validate and sanitize criteria client-side before submit
  2. Enforce server-side validation and encode user content
  3. Escape or render user content as text when displaying
  4. Add input length limits and rate limiting on saves
  5. Apply CSP headers to mitigate injected scripts

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

# Issue Risk Level
1 Hardcoded API token in image URLs HIGH
2 Unvalidated external image URL from integrationsUsed HIGH

Recommendations:

  1. Remove the hardcoded token from client code. Do not embed any secret or scoped token in frontend bundles. Move token usage to a server-side component or API route that signs or proxies requests.
  2. Proxy or fetch external logos server-side (for example, via an API route) and serve them without exposing backend tokens to the client. This lets you keep tokens in server environment variables (process.env) and control caching/TTL.
  3. If the image provider supports publishable/public keys only, confirm the key is truly safe for public usage; otherwise rotate and revoke the exposed token immediately.
  4. Avoid placing tokens in query parameters; use Authorization headers or server-side signed short-lived URLs instead.
  5. Whitelist and validate integration.link values before inserting into an URL. Prefer mapping integration identifiers to known provider domains on the server rather than accepting arbitrary strings from clients or databases.
  6. Sanitize and validate all props coming from external/untrusted sources (integration.link, title, steps[].description) before rendering. Use encodeURIComponent if you must build client-side URLs, but prefer server-side validation and proxying.

🟡 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/workflow/workflow-visualizer-simple.tsx (MEDIUM Risk)

# Issue Risk Level
1 URL params used directly in restoreVersion and sendMessage MEDIUM
2 Execution data/logs sent to external AI without sanitization MEDIUM

Recommendations:

  1. Validate and sanitize orgId/taskId/automationId on the client and (critically) on the server. Treat route params as untrusted input and enforce strict schemas (e.g., UUID or numeric checks) with a library like zod or joi.
  2. Ensure server-side authorization checks for restoreVersion and other server actions: verify the calling user has access to the orgId and taskId and that the automationId belongs to that org/task before performing any restore or modification.
  3. In server-side actions (e.g., restoreVersion implementation), avoid using unvalidated params in downstream queries or API calls. Use parameterized queries / ORM methods and explicit allowlists of resources a user may access.
  4. Before sending execution results/logs to an external AI model, implement a redaction/filtering step to remove secrets and PII (tokens, credentials, email addresses, long hex strings). Use regex-based detectors and a denylist of common secret patterns (Authorization, api_key, secret, token, password) and redact values.
  5. Limit the amount of data sent to the AI: truncate long logs, remove binary/large payloads, and only include structured, minimal context necessary for debugging.
  6. Add explicit user consent / UI warning when sending potentially sensitive execution data to an external model and keep an audit log of all payloads sent to AI (including who triggered it and when).
  7. Add server-side rate limiting and monitoring for actions that call external APIs or mutate critical state (restore/publish), and keep an immutable audit trail for restores/overwrites.
  8. Where possible, avoid sending raw JSON objects directly to the model. Instead, map the object to a sanitized diagnostic summary (fields, types, small sample values).
  9. If enterprise API calls are performed, ensure endpoints do not leak internal secrets in logs and that URL/search params are properly encoded and validated.

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

# Issue Risk Level
1 Unsanitized route params may enable SQL/command injection on backend MEDIUM
2 Missing validation: orgId/taskId/automationId used directly in API URL MEDIUM
3 Console.log response may leak sensitive data in client console MEDIUM
4 Propagating raw backend error messages exposes internals to client MEDIUM
5 Retry logic relies on error.message.includes('404'), fragile and insecure MEDIUM

Recommendations:

  1. Validate and sanitize route parameters both client-side and server-side. Treat orgId, taskId, and automationId as untrusted input and validate format/allowed characters before use.
  2. Do not rely solely on client-side checks. Enforce strict server-side validation and use parameterized queries/ORMs to avoid SQL injection or command injection on the backend.
  3. Avoid logging full responses or raw error objects to the browser console. Redact or remove sensitive fields before logging (e.g., user identifiers, tokens, stack traces).
  4. Map backend errors to safe, generic client messages. Log detailed errors server-side (with correlation IDs) and return only minimal, non-sensitive error information to the client.
  5. Use structured error information (HTTP status codes or explicit error codes) instead of substring matching on message text for retry decisions. For example, check the response status (=== 404) or an explicit error code property to decide retries.

🟡 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automations/[automationId]/overview/components/AutomationOverview.tsx (MEDIUM Risk)

# Issue Risk Level
1 URL path params used directly in API calls (orgId/taskId/automationId) MEDIUM
2 Client-supplied description sent to API without validation/sanitization MEDIUM
3 Selected version passed to executeAutomationScript without validation MEDIUM
4 Links and params can be tampered leading to unauthorized API access MEDIUM

Recommendations:

  1. Enforce server-side authorization checks for orgId, taskId and automationId on every API endpoint. Do not rely on client-side routing/guards for access control.
  2. Validate and normalize all path/URL parameters server-side (e.g., ensure taskId/automationId are valid UUIDs or numeric IDs, and return 4xx for invalid values).
  3. Validate the 'version' parameter on the server to ensure it is numeric, within an allowed set/range, and that the caller is authorized to execute that version. Reject unexpected/unauthorized versions.
  4. Sanitize and/or validate user-supplied description on the server (limit length, strip/encode dangerous markup) and escape when rendering in the UI to prevent stored XSS.
  5. Perform input validation on the backend for all fields (types, lengths, allowed characters). Use a central validation schema for API inputs.
  6. Ensure API calls require proper authentication tokens and enforce CSRF protections as applicable (e.g., require Authorization header/CSRF token for state-changing requests).
  7. Log and rate-limit sensitive actions (e.g., executing automation scripts, toggling enabled state, deletion) and alert on suspicious activity.
  8. Harden executeAutomationScript server-side: avoid eval/exec with untrusted inputs; use safe execution contexts, sandboxing, or queue an authorized worker that validates requests before running scripts.

🟡 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automations/[automationId]/overview/hooks/use-automation-runs.ts (MEDIUM Risk)

# Issue Risk Level
1 Unvalidated automationId used directly in API URL MEDIUM
2 AutomationId may enable server-side SQL or path injection MEDIUM

Recommendations:

  1. Encode the path/URL segment on the client: use encodeURIComponent(automationId) when building the fetch URL to avoid malformed requests or accidental characters affecting routing.
  2. Enforce strict server-side validation of the automationId parameter (e.g., UUID regex or a whitelist of allowed formats) and return 400 on invalid values.
  3. On the server, never concatenate parameters into SQL statements — always use parameterized queries/ORM bound parameters to prevent SQL injection.
  4. Ensure the API route implements proper authorization checks so the caller can only access runs for automations they are allowed to see.
  5. Sanitize and normalize path parameters on the server (reject path traversal characters like ../ or unexpected slashes) before using them in filesystem or routing logic.
  6. Consider adding rate limiting or increasing poll interval (or use websockets/Server-Sent Events) to reduce abuse from frequent polling.

🟡 apps/app/src/app/api/automations/[automationId]/runs/route.ts (MEDIUM Risk)

# Issue Risk Level
1 No auth/authorization: anyone can fetch automation runs MEDIUM
2 Unvalidated automationId used directly in DB query MEDIUM
3 Possible SQL injection risk from unsanitized param in query MEDIUM
4 No input type check (e.g., UUID) for automationId MEDIUM
5 Potential exposure of sensitive run data without access checks MEDIUM

Recommendations:

  1. Enforce authentication and authorization: verify the caller is authenticated and authorized to access the automation identified by automationId (e.g., check user ownership/ACLs).
  2. Validate automationId server-side (e.g., UUID regex or allowed-id check) before using it in queries and return 400 for invalid input.
  3. Although ORMs like Prisma parameterize queries, do not rely solely on that: validate/sanitize inputs and avoid interpolating raw SQL. Use ORM query parameters and avoid raw query strings.
  4. Limit returned fields: explicitly select only non-sensitive columns (avoid returning secrets, tokens, or internal-only fields).
  5. Add access controls at the data level (row-level checks) so queried runs are filtered by the requesting user/organization.
  6. Implement rate limiting and audit logging for access to automation runs to detect and mitigate abuse.

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

# Issue Risk Level
1 Download token placed in URL query (exposed to logs/referrers) MEDIUM
2 Unvalidated 'os' value used in download request MEDIUM
3 No validation of tokenResponse JSON before using token MEDIUM
4 Token endpoint may be vulnerable to CSRF or replay MEDIUM

Recommendations:

  1. Do not put sensitive tokens in URL query parameters. Return the agent binary from a POST request or put the token in a secure, HttpOnly cookie. Alternatively, fetch the binary via fetch() using Authorization headers and stream the response as a Blob, then create an object URL to trigger download — this avoids putting the token in browser history, referer headers or server logs.
  2. Validate/whitelist the 'os' parameter server-side. Never trust client-detected OS values — only accept known values (e.g., 'macos', 'macos-intel', 'windows') and reject/normalize anything else.
  3. Validate the tokenResponse JSON schema before use. Check that tokenResponse.ok is true, that the JSON has a string token, and handle missing/invalid token cases gracefully (fail and notify the user rather than building a URL with undefined).
  4. Protect the /api/download-agent/token endpoint: require proper authentication (e.g., Authorization header or same-site session with CSRF tokens), issue single-use, short-lived tokens tied to the requester, and implement rate-limiting and server-side checks to prevent replay. Ensure token use requires the same client/session that requested it (bind token to user id, IP or session where feasible).
  5. Server-side: set appropriate Content-Disposition and Content-Type headers for downloads and avoid relying on client-side download attribute for security-sensitive behavior.
  6. Log and monitor download token issuance and consumption; expire tokens quickly and revoke on suspicious activity.

🔴 apps/portal/src/app/api/download-agent/route.ts (HIGH Risk)

# Issue Risk Level
1 Download token in URL (GET) can leak via logs, referers, or browser history HIGH
2 No rate limiting on token checks enables brute-force token enumeration HIGH
3 Race condition: token read then delete allows concurrent reuse HIGH
4 Unsanitized 'os' param used in Content-Disposition header (header injection) HIGH
5 Missing validation/whitelist for 'os' when selecting files/scripts HIGH
6 OrgId/employeeId embedded into generated script without sanitization HIGH
7 Generated script could contain attacker-controlled commands (script injection) HIGH

Recommendations:

  1. Send tokens in headers/body instead of URL; avoid GET for sensitive tokens
  2. Whitelist and validate 'os' values, and sanitize values used in headers
  3. Sanitize or escape orgId and employeeId before embedding in scripts
  4. Implement rate limiting and IP throttling on token retrieval endpoints
  5. Consume tokens atomically (get-and-delete) to prevent race reuse

🟡 apps/portal/src/app/api/download-agent/utils.ts (MEDIUM Risk)

# Issue Risk Level
1 Missing validation of userId and orgId before DB queries MEDIUM
2 Potential sensitive-data logging of userId/orgId via logger MEDIUM
3 No authorization check to confirm caller can access member data MEDIUM

Recommendations:

  1. Validate input formats and types before DB access: verify userId and orgId are expected formats (e.g., UUID v4) and reject or canonicalize malformed values early.
  2. Add strict type checks and sanitization for function inputs (e.g., ensure strings, length limits, allowed characters) to fail fast on invalid input.
  3. Avoid logging raw identifiers. Redact or hash sensitive fields before logging (e.g., logger('Member not found', { userId: redact(userId), orgId: redact(orgId) })). Consider configurable logging levels and PII-safe formatting.
  4. Enforce authorization: ensure the caller/context is authorized to access the member and organization (e.g., pass requester's user id/roles to the function and verify membership/permissions before returning data).
  5. Keep using ORM parameterized methods (as here) but still validate inputs; do not build raw SQL with these values. If raw queries are introduced later, use parameterized queries/prepared statements.
  6. Add unit/integration tests that exercise invalid/malicious inputs and unauthorized access paths to ensure checks are enforced.

🟡 apps/portal/src/utils/s3.ts (MEDIUM Risk)

# Issue Risk Level
1 Unauthenticated presigned URL generation (upload/download) MEDIUM
2 Presigned functions accept arbitrary bucket/key parameters MEDIUM
3 Missing fatal error on missing AWS creds in production MEDIUM
4 s3Client created with non-null assertions may use undefined creds MEDIUM
5 decodeURIComponent can throw on malformed percent-encoding (DoS) MEDIUM
6 Path traversal checks are simplistic and may miss edge cases MEDIUM
7 No integrity verification for downloaded agent binaries MEDIUM
8 Presigned upload permits arbitrary content and overwrites MEDIUM
9 Console.error reveals missing credentials state in production logs MEDIUM
10 isValidS3Host regex may not cover all S3 endpoints/outposts MEDIUM

Recommendations:

  1. Require authentication & authorization before calling getPresignedDownloadUrl/getPresignedUploadUrl; ensure callers enforce per-user permissions and map keys/buckets to allowed values.
  2. Whitelist allowed bucket names and key prefixes server-side. Do not accept arbitrary bucketName/key from callers. Normalize and canonicalize keys and enforce allowed patterns.
  3. Fail fast in production when required AWS env vars are missing: throw an exception or exit process rather than only logging, so a broken config cannot lead to partially-initialized client usage.
  4. Avoid non-null assertions for credentials. Validate and assert env vars before creating S3Client, and construct client only when values are present to prevent undefined credentials being used.
  5. Wrap decodeURIComponent in try/catch and validate percent-encoding before decoding. Use a robust URL/key canonicalization routine and reject malformed percent-encoding to prevent URIError DoS.
  6. Improve path traversal checks by canonicalizing paths and rejecting any '..' path segment after decoding, handling all encodings (percent-encoding, UTF variants). Use a path normalization function rather than substring checks.
  7. Add integrity verification for downloaded agent binaries (e.g., sign binaries and verify signatures, or verify strong hashes checked against a trusted source) before executing or distributing them.
  8. When issuing upload presigned URLs, restrict Content-Type, restrict allowed key prefixes, set ACLs to private, and consider using pre-signed POST with policy conditions to limit file size/type and prevent overwrites (or require unique names).
  9. Avoid logging sensitive configuration state. In production, prefer secure monitoring/alerting rather than console.error; if logging is necessary, avoid revealing which credentials or services are misconfigured.
  10. Review and expand isValidS3Host patterns to include all expected AWS S3 endpoint variants (outposts, access points, regional virtual-hosted styles) or, preferably, avoid relying on regex host validation and validate keys/buckets against internal whitelists.

💡 Recommendations

View 3 recommendation(s)
  1. Remove the hardcoded token in apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/workflow/UnifiedWorkflowCard.tsx. Do not embed secrets in client bundles — proxy or sign image requests from a server endpoint instead of placing tokens in URLs in frontend code.
  2. Harden server inputs in apps/app/src/app/api/automations/[automationId]/runs/route.ts: validate automationId against a strict format (e.g., UUID regex) before use, reject malformed values, and ensure DB access uses parameterized queries (do not interpolate the raw param into queries).
  3. Fix apps/portal/src/app/api/download-agent/route.ts: stop accepting sensitive tokens in query strings, whitelist/validate the 'os' parameter, and always escape or sanitize orgId/employeeId before embedding them into generated scripts to eliminate script-injection/path-injection vectors.

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

github-actions bot and others added 2 commits November 6, 2025 16:24
…ompliance (#1717)

Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
Co-authored-by: chasprowebdev <chasgarciaprowebdev@gmail.com>
Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
* chore(db): add new frameworks, requirements, and task templates for compliance

* chore: update trigger.dev to version 4.0.6 in deployment scripts
@vercel vercel bot temporarily deployed to staging – portal November 7, 2025 17:15 Inactive
@Marfuen Marfuen merged commit 9e7f1a7 into release Nov 7, 2025
10 of 11 checks passed
@claudfuen
Copy link
Contributor

🎉 This PR is included in version 1.56.7 🎉

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