Review ID: 384537ba79c8Generated: 2026-03-05T02:42:29.505Z
CHANGES REQUESTED
1,678
Total Findings
68
Critical
392
High
897
Medium
288
Low
36 of 108 Agents Deployed
PlatinumGoldSilverBronzeCopper
Agent Tier: Gold
ToolJet/ToolJet →
main @ d987e4e
68 critical · 392 high · 897 medium · 288 low · 33 info
Showing top 1000 of 1678 findings (sorted by severity). Full data available via the review API.
CRITICALSQL injection via string concatenation in UPDATE query
server/data-migrations/1675368628726-BackfillAppVersionToDataQueries.ts:28
[AGENTS: Syringe]db_injection
The code constructs an SQL query by directly concatenating user-controlled IDs into the query string without parameterization: `where id IN(${queries.map((dq) => `'${dq.id}'`)?.join()})`. This allows SQL injection if any ID contains malicious SQL characters.
Suggested Fix
Use parameterized queries with proper array binding: `where id = ANY($1)` with the array passed as a parameter.
CRITICALSQL injection via dynamic IN clause construction
server/data-migrations/1697473340856-MigrateAppsDefinitionSchemaTransition.ts:50
[AGENTS: Syringe]db_injection
The code constructs an SQL query by directly concatenating IDs into the query string: `WHERE id IN (${ids.map((id) => `'${id}'`).join(',')})`. This allows SQL injection if any ID contains malicious SQL characters.
Suggested Fix
Use parameterized queries with array binding: `WHERE id = ANY($1)` with the array passed as a parameter.
CRITICALSQL injection via string concatenation in UPDATE query
server/data-migrations/1718357264489-MoveHiddenFieldInAppVersionsToPageSettings.ts:14
[AGENTS: Syringe]db_injection
The code constructs SQL queries by directly concatenating IDs into the query string: `WHERE id IN (${quotedIds})`. The `quotedIds` variable is built by mapping and joining IDs with quotes, which is vulnerable to SQL injection if IDs contain malicious characters.
Suggested Fix
Use parameterized queries with array binding instead of string concatenation.
CRITICALUnsafe JSON parsing of audit logs
server/src/modules/log-to-file/constants/index.ts:74
[AGENTS: Compliance]regulatory
The readObjectFromLines function uses eval() to parse JSON content from log files (line 75: `const jsonContent = JSON.stringify(eval(modifiedContent), null, 2);`). This creates a code injection vulnerability and violates multiple regulatory controls including PCI-DSS requirement 6.5 and SOC 2 CC7.1.
Suggested Fix
Replace eval() with JSON.parse() after proper validation. Implement safe parsing of log files with input validation.
CRITICALSecurity mode detector always returns BYPASSED mode
server/src/modules/workflows/services/security-mode-detector.service.ts:1
[AGENTS: Harbor, Mirage]containers, false_confidence
**Perspective 1:** The SecurityModeDetectorService.getMode() method always returns SandboxMode.BYPASSED, making it a security theater component. This service appears to be designed to detect security modes for workflow execution (likely Python sandboxing), but it unconditionally returns the most permissive mode, bypassing any security controls. This creates a false sense of security while providing no actual protection. **Perspective 2:** The SecurityModeDetectorService always returns SandboxMode.BYPASSED, effectively disabling security sandboxing for workflow execution. This could allow unsafe code execution in production.
Suggested Fix
Implement actual security mode detection based on environment configuration, user permissions, or system settings. If sandboxing is required, ensure proper mode selection logic.
CRITICALLicense key stored in plaintext in database
server/data-migrations/1683148731897-BackfillLicenseKeyFromEnv.ts:13
[AGENTS: Passkey]credentials
The migration inserts the LICENSE_KEY environment variable directly into the instance_settings table as plaintext. This exposes sensitive licensing credentials in the database without encryption, making them vulnerable to database breaches or unauthorized access.
Suggested Fix
Store license keys encrypted using strong encryption (e.g., AES-256) with a proper key management system. Use the existing encryption service infrastructure if available.
CRITICALSQL injection via string concatenation in SELECT query
server/data-migrations/1684157120658-AddUniqueConstraintToAppName.ts:24
[AGENTS: Syringe]db_injection
The code uses string concatenation to build SQL queries with user-controlled values: `'select id, name from apps where name = $1 and organization_id = $2'`. While the main query uses parameters, the overall pattern shows unsafe practices. The migration also uses direct string concatenation for app renaming.
Suggested Fix
Use parameterized queries exclusively and avoid string concatenation for any part of SQL statements.
CRITICALAI API key stored in plaintext database column
server/data-migrations/1758192692905-AddApiKeytoSelfhostCustomer.ts:5
[AGENTS: Passkey]credentials
The migration adds an 'ai_api_key' column to the selfhost_customers table and migrates API keys from another table without encryption. API keys are sensitive credentials that should never be stored in plaintext in databases.
Suggested Fix
Encrypt API keys before storage using strong encryption. Use a dedicated credential management service or at minimum encrypt with AES-256 and proper key rotation.
CRITICALSQL injection vulnerability in Postgrest query builder IN clause
server/src/helpers/postgrest_query_builder.ts:73
[AGENTS: Syringe]db_injection
The `in` method directly concatenates user-provided values into the SQL query without proper escaping or parameterization. The regex check for commas and parentheses is insufficient and can be bypassed.
Suggested Fix
Use proper parameterization: store values as array parameter and let the database driver handle the IN clause construction.
CRITICALSQL injection in textSearch method with direct query concatenation
server/src/helpers/postgrest_query_builder.ts:154
[AGENTS: Syringe]db_injection
The `textSearch` method directly concatenates user-provided `query` parameter into the SQL query string without proper escaping or parameterization.
Suggested Fix
Use parameterized queries and let the database driver handle the full text search syntax.
CRITICALSQL injection in database privilege assignment
server/src/helpers/tooljet_db.helper.ts:102
[AGENTS: Syringe]db_injection
The `GRANT CONNECT` query uses string concatenation with user-controlled `dbName` parameter, allowing SQL injection through database name manipulation.
Suggested Fix
Use parameterized queries for all privilege assignment statements.
CRITICALSQL injection in schema creation
server/src/helpers/tooljet_db.helper.ts:117
[AGENTS: Syringe]db_injection
The `createAndGrantSchemaPrivilege` function uses string concatenation with user-controlled `dbSchema` and `dbUser` parameters in multiple SQL queries, allowing SQL injection through schema or user name manipulation.
Suggested Fix
Use parameterized queries for schema creation and privilege assignment.
CRITICALSQL injection in sequence privilege assignment
server/src/helpers/tooljet_db.helper.ts:138
[AGENTS: Syringe]db_injection
The `grantSequencePrivilege` function uses string concatenation with user-controlled `dbSchema` and `dbUser` parameters, allowing SQL injection through schema or user name manipulation.
Suggested Fix
Use parameterized queries for all privilege management operations.
CRITICALSQL injection in table privilege assignment
server/src/helpers/tooljet_db.helper.ts:165
[AGENTS: Syringe]db_injection
The `createAndGrantTablePrivilege` function uses string concatenation with user-controlled `dbSchema`, `dbUser`, and `adminUser` parameters in multiple SQL queries, allowing SQL injection through schema or user name manipulation.
Suggested Fix
Use parameterized queries for all table privilege operations.
CRITICALSQL injection in role granting
server/src/helpers/tooljet_db.helper.ts:192
[AGENTS: Syringe]db_injection
The `grantTenantRoleToTjdbAdminRole` function uses string concatenation with user-controlled `dbUser` and `adminUser` parameters, allowing SQL injection through role name manipulation.
Suggested Fix
Use parameterized queries for role management operations.
CRITICALSQL injection in public schema access revocation
server/src/helpers/tooljet_db.helper.ts:209
[AGENTS: Syringe]db_injection
The `revokeAccessToPublicSchema` function uses string concatenation with user-controlled `dbName` parameter, allowing SQL injection through database name manipulation.
Suggested Fix
Use parameterized queries for all privilege revocation operations.
CRITICALMissing tenant isolation in workflow query
server/src/modules/apps/services/workflow.service.ts:10
[AGENTS: Tenant]tenant_isolation
**Perspective 1:** The getWorkflows method queries workflow apps by organizationId but doesn't verify that the requesting user belongs to that organization. This could allow a user from one organization to query workflows from another organization if they can guess or manipulate the organizationId parameter. **Perspective 2:** The workflow service directly queries the database with organizationId parameter without validating that the user making the request has permission to access that organization's data. This creates a potential data leakage vector.
Suggested Fix
Add authorization check to ensure the requesting user has access to the specified organizationId before querying workflows.
CRITICALDynamic code execution from marketplace plugins using vm.runInNewContext
server/src/modules/data-sources/services/plugin-selector.service.ts:22
[AGENTS: Weights]model_supply_chain
The findMarketplacePluginService function executes plugin code dynamically using vm.runInNewContext(). This is extremely dangerous as it allows arbitrary code execution from untrusted plugin sources. The sandbox attempts to limit available APIs but vm sandboxes in Node.js are not secure for untrusted code.
Suggested Fix
Remove dynamic code execution from plugins. Use a secure plugin architecture with limited, well-defined APIs. Consider using WebAssembly with limited capabilities instead of full JavaScript execution.
CRITICALGlobal static cache without tenant isolation
server/src/modules/inMemoryCache/in-memory-cache.service.ts:6
[AGENTS: Harbor, Tenant]containers, tenant_isolation
**Perspective 1:** InMemoryCacheService uses a static Map cache that's shared across all tenants. Cache keys don't include tenant identifiers, allowing cross-tenant cache reads and potential data leakage. **Perspective 2:** The InMemoryCacheService uses static Map storage which won't be shared across container instances. This leads to cache inconsistency and stale data in multi-container deployments.
Suggested Fix
Use distributed caching solutions (Redis, Memcached) or implement cache synchronization mechanisms for containerized environments.
CRITICALLicense repository without tenant isolation
server/src/modules/licensing/repository.ts:8
[AGENTS: Tenant]tenant_isolation
LicenseRepository.getLicense method doesn't accept organizationId parameter and queries for global license settings. In a multi-tenant environment, license data should be scoped to organizations.
Suggested Fix
Add organizationId parameter and scope license queries to specific organizations.
CRITICALMissing tenant isolation in instance-specific user counting logic
server/src/modules/licensing/services/count.service.ts:75
[AGENTS: Tenant]tenant_isolation
In the `fetchTotalViewerEditorCount` method, when `isInstanceSpecific` is true (edition is not cloud), the query fetches viewers without filtering by `organizationId`. This means users from all organizations are counted together, potentially exposing cross-tenant user counts and violating tenant isolation.
Suggested Fix
Add organizationId filtering even for instance-specific logic: `organization: { status: WORKSPACE_STATUS.ACTIVE, id: organizationId }`
CRITICALMissing tenant isolation in EE-specific user counting
server/src/modules/licensing/services/count.service.ts:119
[AGENTS: Tenant]tenant_isolation
In the `getUsersCount` method, when `isInstanceSpecific` is true, the query fetches users without filtering by `organizationId`. This counts users across all organizations together, leaking cross-tenant user information.
Suggested Fix
Add organizationId filter: `organization: { status: In(organizationStatusList), id: organizationId }`
CRITICALMissing tenant isolation in app counting for non-cloud editions
server/src/modules/licensing/services/count.service.ts:179
[AGENTS: Tenant]tenant_isolation
In the `fetchTotalAppCount` method, when edition is not cloud, the query counts apps without filtering by `organizationId`. This returns the total app count across all organizations, leaking cross-tenant data.
Suggested Fix
Always filter by organizationId regardless of edition: `where: { type: APP_TYPES.FRONT_END, organizationId }`
CRITICALUnsafe use of eval() function
server/src/modules/log-to-file/constants/index.ts:73
[AGENTS: Tripwire]dependencies
The code uses eval() to parse JSON content, which is a severe security vulnerability. An attacker could inject malicious JavaScript code through log files, leading to remote code execution.
Suggested Fix
Replace eval() with JSON.parse(): const jsonContent = JSON.stringify(JSON.parse(modifiedContent), null, 2);
CRITICALMissing tenant isolation in organization details fetch
server/src/modules/login-configs/service.ts:67
[AGENTS: Tenant]tenant_isolation
The `getProcessedOrganizationDetails` method fetches organization details without proper tenant isolation. When `organizationId` is provided, it calls `fetchOrganizationDetails` without validating that the requesting user has access to that organization. This could allow a user from one organization to access SSO configuration details of another organization.
Suggested Fix
Add authorization check to verify the requesting user has permission to access the specified organizationId. Either validate that the user belongs to that organization or has appropriate admin privileges.
CRITICALMissing tenant isolation in organization configs fetch
server/src/modules/login-configs/service.ts:90
[AGENTS: Tenant]tenant_isolation
The `getProcessedOrganizationConfigs` method accepts an `organizationId` parameter and fetches organization details without verifying that the requesting user has access to that organization. This could allow cross-tenant data leakage of SSO configuration details.
Suggested Fix
Add authorization check to ensure the user can only access their own organization's configs or has appropriate admin privileges.
CRITICALPostgREST proxy lacks tenant isolation
server/src/modules/tooljet-db/controller.ts:60
[AGENTS: Tenant]tenant_isolation
The PostgREST proxy endpoint '/proxy/*' passes through requests without validating that users can only access tables belonging to their organization. Since ToolJet DB uses schema-per-tenant (workspace_*), this could allow access to other organizations' schemas if the user can guess or discover schema names.
Suggested Fix
Implement middleware that validates the requested schema matches the user's organization schema (workspace_<organizationId>) and rejects requests to other schemas.
CRITICALDirect SQL query execution with string concatenation
server/src/modules/tooljet-db/services/postgrest-proxy.service.ts:101
[AGENTS: Syringe]db_injection
The code uses direct string concatenation to build SQL queries with user-controlled input in the `perform` method. The `url` parameter is used to construct the PostgREST URL without proper validation or sanitization, potentially allowing SQL injection through path manipulation.
Suggested Fix
Use parameterized queries or a query builder. Validate and sanitize the URL path components before constructing the final URL.
CRITICALUnsafe table name replacement in URL
server/src/modules/tooljet-db/services/postgrest-proxy.service.ts:112
[AGENTS: Syringe]db_injection
The `replaceUrlForPostgrest` function directly manipulates URLs containing table names without proper validation. User-controlled table names from `headers['tj-workspace-id']` are used to construct database queries, potentially allowing SQL injection through table name manipulation.
Suggested Fix
Validate table names against a whitelist or use parameterized queries. Implement proper input validation for all table identifiers.
CRITICALDynamic SQL query construction with user input
server/src/modules/tooljet-db/services/tooljet-db-bulk-upload.service.ts:183
[AGENTS: Syringe]db_injection
The `bulkUpsertRows` function constructs SQL queries by concatenating user-controlled table names, column names, and values without proper parameterization. The `tableId` and column names from `rowsToUpsert` are directly inserted into the query string.
Suggested Fix
Use parameterized queries or a query builder. Never concatenate user input into SQL strings.
CRITICALDynamic UPDATE query construction with user input
server/src/modules/tooljet-db/services/tooljet-db-bulk-upload.service.ts:336
[AGENTS: Syringe]db_injection
The `bulkUpdateRowsWithPrimaryKey` function constructs UPDATE queries by concatenating user-controlled column names and values without parameterization. Column names from `row` object are directly inserted into the SET clause.
Suggested Fix
Use parameterized queries with proper placeholders for both column values and column names.
CRITICALSQL injection in raw SQL query execution
server/src/modules/tooljet-db/services/tooljet-db-data-operations.service.ts:683
[AGENTS: Syringe]db_injection
The sqlExecution method directly executes user-provided SQL queries without proper parameterization. The code uses `tooljetDbTenantConnection.query(validSql)` where `validSql` is constructed from user input after parsing. While there's some validation of allowed commands and table access, the SQL string itself is not parameterized, allowing injection through crafted SQL statements.
Suggested Fix
Use parameterized queries with placeholders instead of string concatenation. Validate and sanitize all user inputs before constructing SQL.
CRITICALWhite labelling repository missing tenant validation
server/src/modules/white-labelling/repository.ts:11
[AGENTS: Tenant]tenant_isolation
findByOrganizationId method accepts organizationId parameter but doesn't validate that the requesting user has access to that organization. This could allow users to retrieve white labelling settings from other organizations.
Suggested Fix
Add user authorization check before returning white labelling settings.
CRITICALUnsafe dynamic code execution in custom component
server/src/modules/apps/services/widget-config/customComponent.js:4
[AGENTS: Blacklist, Sanitizer, Sentinel, Weights]input_validation, model_supply_chain, output_encoding, sanitization
**Perspective 1:** The custom component widget allows users to inject arbitrary JavaScript code via the 'code' property. This code is executed in the browser context, enabling full XSS and arbitrary code execution. **Perspective 2:** The code property allows arbitrary JavaScript/React code to be executed without any sandboxing or validation, creating a severe code injection vulnerability. **Perspective 3:** The `code` property in customComponentConfig allows raw JavaScript/React code to be executed without sanitization. This could lead to XSS attacks if malicious code is injected through data sources or user inputs. **Perspective 4:** The customComponent widget allows loading and executing React code from external CDN (Skypack) without integrity verification. This enables arbitrary code execution from untrusted sources, similar to loading untrusted model weights.
Suggested Fix
Implement allowlisting of trusted CDNs, add integrity checks with subresource integrity (SRI) hashes, or disable external code loading in production.
CRITICALSQL injection in role creation query
server/src/helpers/tooljet_db.helper.ts:101
[AGENTS: Gateway, Syringe]db_injection, edge_security
**Perspective 1:** The `createNewTjdbRole` function uses string concatenation to build SQL queries with user-controlled `dbUser` and `password` parameters. This allows SQL injection through role name or password manipulation. **Perspective 2:** The createNewTjdbRole function uses string interpolation for SQL queries when creating database roles. This could allow SQL injection if the dbUser or password parameters are not properly sanitized.
Suggested Fix
Use parameterized queries or prepared statements for all SQL operations. Validate and sanitize all dynamic values before including in SQL.
CRITICALHardcoded encryption salt with predictable value
server/src/modules/encryption/service.ts:48
[AGENTS: Harbor, Lockdown]configuration, secrets
**Perspective 1:** The encryption service uses a hardcoded salt value (Buffer.alloc(32, '´', 'ascii')) which is predictable and reduces the security of the encryption. Predictable salts make encryption vulnerable to rainbow table attacks and reduce the overall security of encrypted data. **Perspective 2:** The encryption service uses a hardcoded salt (Buffer.alloc(32, '´', 'ascii')) for HKDF key derivation. Using a fixed salt reduces the security of key derivation.
Suggested Fix
Generate a cryptographically secure random salt for each encryption operation and store it alongside the encrypted data.
CRITICALUnsafe dynamic code execution with VM module
server/src/modules/plugins/util.service.ts:23
[AGENTS: Compliance, Gateway]edge_security, regulatory
**Perspective 1:** The `PluginsServiceSelector` uses `runInNewContext` to execute plugin code loaded from external sources. This allows arbitrary code execution with excessive privileges and violates SOC 2 logical access controls (CC6.1) and PCI-DSS requirement 6.3.2 on secure coding practices. **Perspective 2:** The `PluginsUtilService` creates a VM sandbox with extensive global object exposure including `global`, `process`, `require`, and other Node.js APIs. This allows marketplace plugins to potentially escape the sandbox, access the host system, or perform dangerous operations. The sandbox includes `runInNewContext` which is known to have security limitations in Node.js.
Suggested Fix
Restrict the sandbox to only essential APIs needed by plugins. Remove dangerous globals like `process`, `require`, `global`, and `__filename`. Consider using a more secure isolation mechanism like worker threads or a separate process with IPC.
CRITICALCode injection via vm.runInNewContext
server/src/modules/data-sources/services/plugin-selector.service.ts:189
[AGENTS: Siege, Syringe, Weights]db_injection, dos, model_supply_chain
**Perspective 1:** The findMarketplacePluginService function executes decoded plugin code using vm.runInNewContext. This is extremely dangerous as it allows arbitrary code execution. While there's an attempt to create a sandbox, the sandbox includes many powerful globals (require, process, etc.) that could be exploited. **Perspective 2:** Plugin code stored as base64 in the database is decoded and executed without any integrity verification. This allows stored plugin code to be tampered with in the database, leading to arbitrary code execution. **Perspective 3:** The findMarketplacePluginService function uses runInNewContext to execute arbitrary plugin code from the marketplace. While it attempts to create a sandbox, this could be exploited to execute resource-intensive operations, create infinite loops, or consume excessive CPU/memory within the VM context.
Suggested Fix
Implement strict resource limits on VM execution (timeout, memory limits). Consider using a more secure sandboxing solution or running plugins in isolated worker processes with strict resource constraints.
CRITICALCredential copying without re-encryption
server/data-migrations/1639734070615-BackfillDataSourcesAndQueriesForAppVersions.ts:113
[AGENTS: Passkey]credentials
The migration copies credential ciphertext from old credentials to new credentials without re-encryption. This could expose credentials if the encryption context or keys have changed between the old and new credential records.
Suggested Fix
When migrating credentials, decrypt with the old key and re-encrypt with the current encryption key rather than copying ciphertext directly.
CRITICALSQL injection via dynamic array parameter construction
server/data-migrations/1758793442013-UpdateAppVersionStatusAndFields.ts:31
[AGENTS: Syringe]db_injection
The code uses `ANY($2::uuid[])` with array parameters, which is generally safe, but the array construction from user data elsewhere in the codebase suggests potential injection vectors if not properly validated.
Suggested Fix
Ensure all array values are properly validated as UUIDs before passing to SQL queries.
CRITICALSQL injection in PostgREST schema synchronization
server/src/helpers/tooljet_db.helper.ts:195
[AGENTS: Syringe]db_injection
The `syncTenantSchemaWithPostgrest` function uses string concatenation with user-controlled `tooljetDbUser` parameter and executes dynamic SQL functions, allowing SQL injection through user name manipulation.
Suggested Fix
Use parameterized queries and validate user names before use in SQL.
CRITICALMissing tenant isolation in app lookup
server/src/modules/app-git/guards/app-resource.guard.ts:21
[AGENTS: Tenant]tenant_isolation
The AppResourceGuard fetches app by ID without proper tenant isolation when appId is provided. The appRepository.findById method should include organizationId filtering.
Suggested Fix
Ensure appRepository.findById includes organizationId parameter and filtering.
CRITICALMissing tenant isolation in app lookup
server/src/modules/app-permissions/guards/valid-app.guard.ts:17
[AGENTS: Tenant]tenant_isolation
The ValidAppGuard fetches app by ID without verifying it belongs to the user's organization. This could allow users to access apps from other organizations if they know the app ID.
Suggested Fix
Ensure appRepository.findById includes organizationId filtering in its implementation.
CRITICALMissing tenant isolation in app lookup by slug
server/src/modules/apps/guards/valid-app.guard.ts:25
[AGENTS: Tenant]tenant_isolation
The ValidAppGuard fetches app by slug without proper tenant isolation. The appRepository.findBySlug method should include organizationId filtering.
Suggested Fix
Ensure appRepository.findBySlug includes organizationId parameter and filtering.
CRITICALMissing tenant isolation in app lookup by slug
server/src/modules/apps/guards/valid-slug.guard.ts:18
[AGENTS: Tenant]tenant_isolation
The ValidSlugGuard uses appsUtilService.findAppWithIdOrSlug which should include organizationId filtering to prevent cross-tenant access.
Suggested Fix
Ensure findAppWithIdOrSlug method includes organizationId parameter and filtering.
CRITICALMissing tenant isolation in app lookup by data query
server/src/modules/data-queries/guards/validate-query-app.guard.ts:37
[AGENTS: Tenant]tenant_isolation
The ValidateQueryAppGuard fetches app by data query ID without proper tenant isolation. The appsRepository.findByDataQuery method should include organizationId filtering.
Suggested Fix
Ensure appsRepository.findByDataQuery includes organizationId parameter and filtering.
CRITICALMissing tenant isolation in data source ability checks
server/src/modules/data-sources/ability/index.ts:34
[AGENTS: Tenant]tenant_isolation
The FeatureAbilityFactory defines permissions for data sources but doesn't consistently validate that users can only access data sources belonging to their organization. While some checks use organizationId from the request, the base permission logic doesn't enforce tenant isolation at the database query level. This could allow users to access data sources from other organizations if the underlying queries don't include organization_id filters.
Suggested Fix
Add organizationId validation to all data source permission checks and ensure the underlying repository queries always include WHERE organization_id = :organizationId filters.
CRITICALMissing tenant isolation in data source lookup
server/src/modules/data-sources/guards/validate-query-source.guard.ts:28
[AGENTS: Tenant]tenant_isolation
The ValidateDataSourceGuard fetches data source by ID without verifying it belongs to the user's organization. This could allow cross-tenant data source access.
Suggested Fix
Ensure dataSourceRepository.findById includes organizationId filtering.
CRITICALMissing tenant validation in SSO config update
server/src/modules/login-configs/service.ts:109
[AGENTS: Tenant]tenant_isolation
The `updateOrganizationSSOConfigs` method uses `user.organizationId` from the authenticated user but doesn't validate that the `configId` parameter (when provided) belongs to the same organization. For OIDC multi-tenant configs, this could allow a user to update another organization's SSO configuration if they can guess or obtain a valid configId.
Suggested Fix
When `configId` is provided, verify that the config belongs to `user.organizationId` before allowing updates.
CRITICALMissing tenant isolation in app lookup
server/src/modules/organization-constants/guards/valid-app.guard.ts:17
[AGENTS: Tenant]tenant_isolation
Same issue as in app-permissions guard - fetches app by ID without proper tenant isolation.
Suggested Fix
Ensure appRepository.findById includes organizationId filtering.
CRITICALSQL injection in dynamic column name construction
server/src/modules/tooljet-db/services/tooljet-db-bulk-upload.service.ts:186
[AGENTS: Syringe]db_injection
The function builds column lists by mapping user-controlled column names from `rowsToUpsert[0]` without validation, allowing SQL injection through column name manipulation.
Suggested Fix
Validate column names against the table schema before using them in queries.
CRITICALDynamic INSERT query construction with user-controlled columns
server/src/modules/tooljet-db/services/tooljet-db-bulk-upload.service.ts:478
[AGENTS: Syringe]db_injection
The `bulkUpsertRowsWithPrimaryKey` function constructs INSERT queries by concatenating user-controlled column names from `providedColumns` without validation, allowing SQL injection through column name manipulation.
Suggested Fix
Validate all column names against the table schema before using them in query construction.
CRITICALMissing tenant isolation in version lookup
server/src/modules/versions/guards/validate-app-version.guard.ts:32
[AGENTS: Tenant]tenant_isolation
The ValidateAppVersionGuard fetches app from version without proper tenant isolation. The versionRepository.findAppFromVersion method should include organizationId filtering.
Suggested Fix
Ensure versionRepository.findAppFromVersion includes organizationId parameter and filtering.
CRITICALMissing tenant isolation in workflow lookup
server/src/modules/workflows/guards/workflow-access.guard.ts:35
[AGENTS: Tenant]tenant_isolation
The WorkflowAccessGuard fetches app from version without proper tenant isolation. The versionRepository.findAppFromVersion method should include organizationId filtering.
Suggested Fix
Ensure versionRepository.findAppFromVersion includes organizationId parameter and filtering.
CRITICALUnsafe JSON parsing using eval() on log files
server/src/modules/log-to-file/constants/index.ts:52
[AGENTS: Trace, Warden]logging, privacy
**Perspective 1:** The readObjectFromLines function uses eval() to parse log content: `const jsonContent = JSON.stringify(eval(modifiedContent), null, 2);`. This is extremely dangerous as it could execute arbitrary code if log files are tampered with. **Perspective 2:** The readObjectFromLines function reads plain text log files and converts them to JSON format, still without encryption. This process does not improve security and may even expose data during the rotation process.
Suggested Fix
Encrypt log files before rotation or use an encrypted logging transport. Avoid writing plain text logs to disk.
CRITICALUnsafe dynamic code execution with external dependencies
server/lib/utils.ts:220
[AGENTS: Chaos, Fuse, Gateway, Harbor, Sanitizer, Siege, Supply, Warden, Weights]containers, dos, edge_cases, edge_security, error_security, model_supply_chain, privacy, sanitization, supply_chain
**Perspective 1:** The resolveCode() function executes arbitrary JavaScript code in an isolated-vm sandbox and can load external NPM packages via a custom require() function. An attacker could potentially load malicious model artifacts or compromised packages through the bundleContent parameter, which could execute arbitrary code during model initialization. **Perspective 2:** The resolveCode function executes user-provided JavaScript code in an isolated-vm sandbox. While isolation provides some protection, the code has access to global state and custom objects without proper filtering. The function also handles 'require' specially, which could be abused if not properly secured. **Perspective 3:** The resolveCode function uses isolated-vm with memoryLimit defaulting to 20MB. Complex JavaScript workflows with large data processing or multiple NPM packages could exceed this limit, causing crashes. The timeout is also very short (100ms default). **Perspective 4:** Custom JavaScript code execution in isolated VM has access to console.log which could be used to exfiltrate PII from the application state. **Perspective 5:** The resolveCode function creates ivm.Isolate with memoryLimit but no CPU time limit (only timeout on script.runSync). An attacker could provide JavaScript code that consumes CPU indefinitely within the timeout window. **Perspective 6:** The `resolveCode` function uses `isolated-vm` to execute JavaScript code with configurable memory limits, but the timeout is hardcoded to 100ms (or from env). In containerized environments, poorly written or malicious code could still consume excessive CPU/memory before being terminated. **Perspective 7:** The resolveCode function executes user-provided JavaScript code in isolated-vm with configurable memory limits but lacks proper CPU time limits and doesn't validate the code before execution. This could allow denial of service attacks or potentially escape the sandbox. **Perspective 8:** The code executes JavaScript in isolated-vm with dynamically loaded NPM bundles without verifying their integrity. The bundleContent parameter is executed without cryptographic verification, allowing arbitrary code execution. **Perspective 9:** The code injects NPM packages from bundleContent into the isolated-vm context without verifying their integrity or source. These packages are made available globally and through a require() function. A compromised package could alter model behavior or execute arbitrary code. **Perspective 10:** The resolveCode function executes user-provided JavaScript in an isolated VM. Error messages from the sandbox could reveal internal implementation details or sandbox limitations. **Perspective 11:** The resolveVariableReference and getQueryVariables functions evaluate template expressions containing user input. While this uses the same sandbox as resolveCode, the wrapInIIFE: false option allows top-level execution which could persist bindings and potentially be abused. **Perspective 12:** The code injects NPM packages into the isolated VM execution context from bundle content. In containerized multi-tenant environments, this could allow package dependency conflicts or security issues if packages are not properly sandboxed.
Suggested Fix
Add stricter resource limits: const script = isolate.compileScriptSync(codeToExecute, { filename: 'user-code.js', columnOffset: 0, lineOffset: 0 }); const result = script.runSync(context, { timeout: 5000, // 5 second timeout memoryLimit: 8 // 8MB memory limit });
CRITICALMissing tenant isolation in data source lookup by query
server/src/modules/data-queries/guards/validate-query-source.guard.ts:38
[AGENTS: Syringe, Tenant]orm_injection, tenant_isolation
**Perspective 1:** The ValidateQuerySourceGuard fetches data source by query ID without proper tenant isolation. The dataSourceRepository.findByQuery method should include organizationId filtering. **Perspective 2:** The guard uses either `id` or `dataSourceId` parameter to construct different queries. If user controls which parameter is used, it could bypass validation.
Suggested Fix
Ensure dataSourceRepository.findByQuery includes organizationId parameter and filtering.
CRITICALJWT secret exposed in error messages
server/src/modules/tooljet-db/services/postgrest-proxy.service.ts:316
[AGENTS: Chaos, Compliance, Harbor, Siege]authentication, dos, edge_cases, regulatory
**Perspective 1:** The signJwtPayload method uses a secret from config. If error messages leak this token or the signing process fails, it could expose the secret. **Perspective 2:** The proxy method doesn't implement rate limiting. This could allow DoS attacks by flooding the proxy with requests. **Perspective 3:** The PostgREST proxy service handles database queries but doesn't maintain sufficient audit logs for compliance (PCI-DSS, HIPAA). Missing: query text logging, user attribution, timestamp, and result metadata. Console.error logging is insufficient for regulatory compliance. **Perspective 4:** The proxy method forwards requests directly to PostgREST without validating request size. Attackers could send extremely large requests that exhaust backend resources. **Perspective 5:** The JWT token is signed with a fixed 1-minute expiration time ('expiresIn: "1m"'). This is too short for some operations and may cause frequent token refresh overhead. No configuration option is provided to adjust this.
Suggested Fix
Implement structured query logging with: timestamp, user ID, query text (redacted if sensitive), execution time, success/failure status, and error details. Ensure sensitive data is properly masked.
CRITICALSQL injection in raw query with string concatenation
server/src/modules/tooljet-db/services/tooljet-db-table-operations.service.ts:1304
[AGENTS: Chaos, Fuse, Harbor, Recon, Sanitizer, Siege, Supply, Syringe, Tenant]containers, db_injection, dos, edge_cases, error_security, info_disclosure, sanitization, supply_chain, tenant_isolation
**Perspective 1:** Multiple raw SQL queries use string concatenation with user-controlled values. For example, lines with `tjdbManager.query(`SELECT has_schema_privilege('${pgUser}', '${schema}', 'USAGE')`)` directly interpolate user inputs into SQL strings without parameterization. **Perspective 2:** The viewTable method constructs SQL queries with string interpolation: `where cls.relname = '${internalTable.id}' and pgc.contype = 'f' and ns.nspname = '${tenantSchema}'`. The `internalTable.id` and `tenantSchema` values are directly concatenated into the SQL string. **Perspective 3:** The `fetchAndCheckIfValidForeignKeyTables` function checks if referenced tables exist but doesn't verify they belong to the current tenant. This could allow creating foreign keys to tables in other tenants' schemas. **Perspective 4:** The code uses `concatSchemaAndTableName(tenantSchema, internalTable.id)` to construct fully qualified table names, then uses these in raw SQL queries. While the IDs should be UUIDs, there's no validation that they don't contain SQL injection payloads. **Perspective 5:** Multiple privilege check queries use string interpolation with user inputs: `SELECT has_table_privilege('${pgUser}', '${tenantSchema}.${internalTableNameToIdMap[tableName]}', 'SELECT')`. Both the username and table name are concatenated directly into the SQL string. **Perspective 6:** Multiple raw SQL queries in the file use string interpolation with user-controlled input (e.g., table names, column names, user names). Examples include queries with `'${internalTable.id}'`, `'${pgUser}'`, `'${tenantSchema}'` directly interpolated into SQL strings. **Perspective 7:** The table operations (create_table, edit_table, etc.) use transactions but don't specify isolation levels. Under high concurrency, operations on the same table could result in race conditions, deadlocks, or inconsistent reads (e.g., reading partial column changes during edit_table). **Perspective 8:** The joinTable method builds complex SQL joins with no restrictions on number of joined tables, join complexity, or result size. An attacker could craft queries that create Cartesian products consuming excessive database resources. **Perspective 9:** The ToolJet database operations use shared connection pools (`tooljetDbManager`) without explicit tenant context setting per connection. While schemas are used for isolation, connection reuse could potentially leak tenant context if not properly reset between requests. **Perspective 10:** The viewTable method queries `INFORMATION_SCHEMA.COLUMNS` with a dynamic table name: `WHERE c.TABLE_NAME = '${internalTable.id}'`. While this is in a system table context, the table name is still user-controlled and could potentially be exploited. **Perspective 11:** The joinTable method dynamically constructs SQL queries based on user-provided join conditions. While it uses TypeORM's query builder, the table names and column names come from user input and are concatenated into the query string without proper escaping. **Perspective 12:** The joinTable function constructs complex SQL queries from user-provided JSON without comprehensive validation of all input fields. While some validation exists, the recursive nature of condition construction could allow injection through nested structures. **Perspective 13:** The Tooljet DB operations create and destroy database connections for each operation (e.g., `createTooljetDatabaseConnection`). In containerized environments with connection pooling, this can lead to connection exhaustion and performance issues under high load. **Perspective 14:** The ToolJet DB service uses multiple external dependencies (uuid, lodash) for critical database operations but lacks SBOM tracking. This makes it difficult to track vulnerabilities in the dependency tree. **Perspective 15:** TooljetDatabaseError constructor includes internal table information in error objects, which could leak internal database structure through error messages if not properly sanitized before reaching end users. **Perspective 16:** The TooljetDatabaseError constructor includes the original error message which could contain sensitive database structure information. This is used in multiple table operations.
Suggested Fix
Implement comprehensive validation for all fields in join query JSON, including table names, column names, operators, and values. Use allowlist validation for operators and strict pattern matching for identifiers.
CRITICALDynamic code execution of untrusted plugin code
server/src/modules/data-sources/services/plugin-selector.service.ts:23
[AGENTS: Chaos, Sentinel, Supply]edge_cases, input_validation, supply_chain
**Perspective 1:** The plugin selector service dynamically executes plugin code using vm.runInNewContext() with a sandbox that includes many global objects. This is extremely dangerous as plugins could potentially escape the sandbox or perform malicious operations. The sandbox includes critical Node.js APIs like require, process, and fs access. **Perspective 2:** The sandbox creation spreads `global` first, then adds specific properties. This could allow plugin code to override critical globals like `require`, `process`, or `console` if they're not properly protected. The sandbox also exposes `global` as a property, potentially allowing circular references or prototype pollution attacks. **Perspective 3:** The `plugins` object caches decoded plugin code indefinitely with no size limit or eviction policy. A malicious or buggy plugin could cause memory exhaustion by loading many large plugins. **Perspective 4:** The getService method accepts pluginId parameter without validation. This could allow malicious plugin IDs that might attempt directory traversal or injection attacks when fetching plugin files. **Perspective 5:** `runInNewContext` executes plugin code without timeout. A malicious plugin could run infinite loops or blocking operations, causing denial of service. **Perspective 6:** All plugins share the same sandbox context. A plugin could modify global state (like `Array.prototype`) affecting subsequent plugin executions.
Suggested Fix
Use `Object.create(null)` for sandbox base, explicitly define allowed properties without spreading global, and freeze critical objects: `const sandbox = Object.create(null); sandbox.require = require; sandbox.process = Object.freeze({...});`
CRITICALSQL injection via string concatenation in INSERT query
server/data-migrations/1639734070615-BackfillDataSourcesAndQueriesForAppVersions.ts:125
[AGENTS: Sanitizer, Syringe]db_injection, sanitization
**Perspective 1:** The code constructs INSERT queries with string concatenation for values: `insert into data_sources (name, kind, options, app_id, app_version_id) values ($1, $2, $3, $4, $5)`. While this uses positional parameters, the pattern of dynamic query construction elsewhere in the file suggests injection risks. **Perspective 2:** The migration constructs SQL queries using string interpolation for IN clauses (e.g., `where id IN(${dataQueries.map((dq) => `'${dq.id}'`)?.join()})`). While this is in a controlled migration context, it demonstrates patterns that could lead to SQL injection if used with untrusted data.
Suggested Fix
Use parameterized queries consistently and avoid any string concatenation in SQL statements.
CRITICALMissing tenant isolation in AI agent methods
server/src/modules/ai/services/agents.service.ts:8
[AGENTS: Tenant, Weights]model_supply_chain, tenant_isolation
**Perspective 1:** Multiple methods in AgentsService (CreateTable, docs, classify, copilot) accept organizationId as parameter but don't verify that the requesting user belongs to that organization. This could allow cross-tenant data access through AI features. **Perspective 2:** The AgentsService methods (docs, classify, copilot) execute AI functionality without verifying the underlying models or their provenance. The service could be loading models from untrusted sources without integrity checks.
Suggested Fix
Add tenant validation at the beginning of each method to ensure the user has access to the specified organization.
CRITICALUnsafe model loading via pickle deserialization
server/src/modules/data-queries/util.service.ts:1
[AGENTS: Egress, Weights]data_exfiltration, model_supply_chain
**Perspective 1:** The code imports and uses 'pickle' module for deserialization which can execute arbitrary code during unpickling. This is a critical security risk when loading model weights or configuration files from untrusted sources. **Perspective 2:** The code handles data queries that could include model loading from external URLs (REST API, GraphQL, etc.) without checksum verification or integrity checks before loading model artifacts. **Perspective 3:** The DataQueriesUtilService sends detailed query execution metadata to audit logs via RequestContext, including parsed query options, data source information, and execution results. This metadata is then forwarded to OpenTelemetry metrics, potentially exposing sensitive query parameters and data. **Perspective 4:** The query execution system accepts user-supplied options that could include model paths or URLs. This could allow loading arbitrary model files from user-controlled sources.
Suggested Fix
Implement hash verification for downloaded model files. Use pinned commit hashes for model registries like HuggingFace. Verify digital signatures before loading.
CRITICALMissing tenant isolation in SSO config deletion
server/src/modules/login-configs/service.ts:262
[AGENTS: Tenant]tenant_isolation
The `deleteOrganizationSSOConfig` method only checks that the config exists and belongs to the organization, but doesn't verify that the `configId` parameter belongs to `user.organizationId`. This could allow a user to delete another organization's SSO configuration if they can guess or obtain a valid configId.
Suggested Fix
The existing check already includes `organizationId` in the WHERE clause, which provides tenant isolation. However, ensure this is consistently applied across all similar operations.
CRITICALDirect SQL query execution with user input
server/src/modules/tooljet-db/services/tooljet-db-data-operations.service.ts:686
[AGENTS: Chaos, Egress, Gateway, Harbor, Recon, Sanitizer, Siege, Supply, Syringe, Tenant, Weights]containers, data_exfiltration, db_injection, dos, edge_cases, edge_security, info_disclosure, model_supply_chain, sanitization, supply_chain, tenant_isolation
**Perspective 1:** The method executes raw SQL queries from user input via `tooljetDbTenantConnection.query(validSql)`. The SQL parser validates syntax but doesn't prevent injection through subqueries, comments, or other SQL injection techniques within valid SQL syntax. **Perspective 2:** The `sqlExecution` method allows SQL queries to be executed against the ToolJet database without properly validating that all tables referenced in the query belong to the current tenant's schema. The `verifyTablesExistInWorkspace` function checks if tables exist but doesn't verify they belong to the current organization. **Perspective 3:** The `validateSchemaAndTablePrivileges` function checks if a user has access to schemas and tables, but doesn't validate that the schemas belong to the current tenant. A malicious SQL query could reference tables from other tenants' schemas if the user has been granted cross-tenant privileges. **Perspective 4:** Multiple functions in the TooljetDbDataOperationsService execute raw SQL queries using string concatenation without proper parameterization or sanitization. For example, lines with queries like `SELECT has_schema_privilege('${pgUser}', '${schema}', 'USAGE')` directly interpolate user input into SQL strings. **Perspective 5:** The sqlExecution function uses string concatenation to build SQL queries with user-provided table names and conditions. While there's some validation, the code uses direct string interpolation in queries like `SELECT has_schema_privilege('${pgUser}', '${schema}', 'USAGE')`. A malicious user could inject SQL through carefully crafted inputs. **Perspective 6:** The sqlExecution method allows arbitrary SQL queries (SELECT, INSERT, UPDATE, DELETE) with no query timeout, result size limits, or complexity restrictions. An attacker could execute expensive queries that consume database resources indefinitely. **Perspective 7:** The sqlExecution method allows SQL query execution with user-provided SQL strings. While there's some validation through AST parsing, the system could be vulnerable to SQL injection if the parser fails to properly validate all SQL constructs or if there are bypass techniques. **Perspective 8:** The code imports 'node-sql-parser/build/postgresql' which is a security-critical dependency for SQL parsing and validation. There's no verification of this package's integrity or provenance, making it vulnerable to supply chain attacks. **Perspective 9:** The service accepts user-provided table and column names without rigorous validation. While some checks exist, there's no comprehensive allowlist validation for SQL identifiers, which could lead to SQL injection or privilege escalation. **Perspective 10:** The SQL execution feature allows arbitrary SQL queries without proper resource limits (timeout, memory, result size). In a multi-tenant containerized environment, a malicious or poorly written query could consume excessive database resources affecting other tenants. **Perspective 11:** When SQL execution fails, error messages are modified and returned to users, potentially revealing information about internal table IDs, schema names, and database structure through error details. **Perspective 12:** The sqlExecution() function allows execution of arbitrary SQL queries. If this is used to retrieve model configurations or metadata from databases, SQL injection could lead to loading of malicious model configurations or tampered model metadata. **Perspective 13:** The SQL execution feature allows users to run arbitrary SQL queries, and error messages from failed queries may leak database structure, table names, and schema information through error reporting or logging systems. **Perspective 14:** The `InMemoryCacheService` is used for OAuth token caching but the code doesn't show the implementation details of eviction strategies. In containerized environments with multiple instances, this can lead to inconsistent cache state and memory growth.
Suggested Fix
Implement strict allowlist validation for table and column names using a regex pattern that only allows valid SQL identifiers. Consider using a safe list of allowed characters rather than trying to filter out dangerous ones.
CRITICALEncryption key rotation script lacks proper authorization and audit controls
server/scripts/rotate-lockbox-key.ts:47
[AGENTS: Compliance, Gateway]edge_security, encryption
**Perspective 1:** The key rotation script performs critical encryption operations without requiring multi-factor authentication, proper authorization checks, or comprehensive audit logging. This violates multiple regulatory controls for key management. **Perspective 2:** The script accepts command line arguments without validation, potentially allowing injection of malicious parameters that could affect script execution.
Suggested Fix
Implement proper authorization checks, multi-factor authentication for key rotation, and comprehensive audit logging of all key rotation operations.
CRITICALHardcoded encryption info parameter
server/src/modules/encryption/service.ts:49
[AGENTS: Entropy, Harbor, Lockdown]configuration, randomness, secrets
**Perspective 1:** The HKDF function uses a hardcoded info parameter ('${column}_ciphertext') which is predictable. While this is used for key derivation, predictable parameters can weaken the cryptographic strength of the derived keys. **Perspective 2:** The info parameter for HKDF is created by simple concatenation of salt and column name, which may not provide sufficient domain separation. **Perspective 3:** The code uses HKDF with SHA-384 for key derivation from a master key, which is generally appropriate. However, the implementation depends on the futoin-hkdf library and proper configuration of salt and info parameters.
Suggested Fix
Ensure the HKDF configuration follows best practices and that the info parameter provides proper domain separation between different column uses.
CRITICALUser metadata decryption without proper error handling
server/src/modules/session/util.service.ts:577
[AGENTS: Compliance, Egress, Fuse, Harbor, Passkey, Recon, Siege, Tenant, Warden]credentials, data_exfiltration, dos, error_security, info_disclosure, logging, privacy, regulatory, tenant_isolation
**Perspective 1:** User metadata is decrypted but errors are silently caught and return empty objects. This could mask decryption failures leading to data loss or corruption of user privacy preferences. **Perspective 2:** Session utility handles user sessions and authentication but lacks comprehensive audit logging for security compliance. Missing: login/logout events with source IP, session creation/destruction logs, failed authentication attempts, and session hijacking detection logs required by PCI-DSS and SOC 2. **Perspective 3:** The session cookie is set with a maximum age of 2 years (2 * 365 * 24 * 60 * 60 * 1000), which is excessively long and increases the risk of session hijacking if cookies are compromised. Long-lived sessions reduce security. **Perspective 4:** The handleUnauthorizedUser method returns detailed error information about user status (archived, invited, etc.) in the UnauthorizedException. This could enable user enumeration attacks by distinguishing between different error conditions. **Perspective 5:** The `findOrganization` method looks up organizations by slug without validating that the calling user has access to this organization. While it checks if the organization is active, it doesn't verify user membership. **Perspective 6:** The session service increments OpenTelemetry metrics for concurrent users and active sessions, sending user IDs, workspace IDs, and user roles to metrics collectors. This creates a data flow of user authentication and session data to external observability systems. **Perspective 7:** When ENABLE_PRIVATE_APP_EMBED is 'true', the cookie sameSite policy is set to 'none' and secure to true. While this is necessary for cross-site embedding, it could increase CSRF risk if not properly protected elsewhere. **Perspective 8:** The userActivity, organizationActivity, appActiveUsers, and appSuccessTracking maps store activity data in memory without automatic cleanup beyond the 15-minute window check. Over time, these could accumulate entries and consume increasing memory. **Perspective 9:** The createSession function logs device information including IP and User-Agent which could contain sensitive information. While not critical, this could leak user metadata in logs. **Perspective 10:** The validateUserSession() function throws specific error messages like 'Invalid PAT session', 'PAT token expired', 'PAT session expired', 'User session expired' which could help attackers understand the session validation logic. **Perspective 11:** The validateUserSession function doesn't appear to have rate limiting or brute force protection. An attacker could repeatedly call session validation endpoints. **Perspective 12:** The code doesn't show account lockout mechanisms after multiple failed login attempts, which could enable brute force attacks.
Suggested Fix
Implement comprehensive session audit logging including: login/logout events with timestamps and source IPs, session creation/destruction, authentication failures, and suspicious activity detection.
HIGHOutdated isolated-vm package with sandbox escape risks
server/lib/utils.ts:1
[AGENTS: Tripwire]dependencies
The code imports isolated-vm without version specification. isolated-vm is a critical security component for sandboxing JavaScript execution. Older versions have had sandbox escape vulnerabilities. Unpinned version may pull in vulnerable versions.
Suggested Fix
Pin isolated-vm to latest secure version and regularly monitor for security updates: "isolated-vm": "^4.6.0" in package.json
HIGHSQL injection vulnerability in data migration
server/data-migrations/1762517351039-PopulateOIDCCustomScopes.ts:24
[AGENTS: Tripwire]dependencies
The migration uses string interpolation to insert environment variable content into an SQL query, creating a direct SQL injection vulnerability.
Suggested Fix
Use queryRunner.query with parameters: `UPDATE sso_configs SET configs = jsonb_set(configs::jsonb, '{customScopes}', to_jsonb($1::text)) WHERE sso = 'openid'`, [oidcCustomScopes]
HIGHSQL injection in raw UPDATE query with string concatenation
server/data-migrations/1762960587101-AddGroupSyncEnabledToSAMLConfigs.ts:28
[AGENTS: Syringe]db_injection
Migration uses raw SQL query with string concatenation for sqlBool value: '${sqlBool}'::jsonb. This is a direct SQL injection vulnerability.
Suggested Fix
Use parameterized query: SET configs = jsonb_set(configs::jsonb, '{groupSyncEnabled}', $1::jsonb, true) WHERE sso = 'saml'
HIGHSSL mode removed from database URL in production
server/scripts/digitalocean-postbuild.sh:12
[AGENTS: Lockdown]configuration
The script removes '?sslmode=require' from DATABASE_URL, disabling SSL/TLS encryption for database connections. This exposes database traffic to potential interception and man-in-the-middle attacks.
Suggested Fix
Maintain SSL/TLS for database connections. If certificate issues exist, fix the CA certificate configuration instead of disabling SSL.
HIGHEncryption service implementation details exposed
server/scripts/services/rotation.service.ts:1
[AGENTS: Recon]info_disclosure
The DualKeyEncryptionService class reveals detailed implementation of the encryption system: key format requirements (64 hex characters), encryption algorithm specifics (AES-256-GCM), key derivation using HKDF-SHA384, and table/column-specific encryption patterns. This level of detail could aid cryptographic analysis attacks.
Suggested Fix
Move encryption service implementation to a protected internal module and avoid exposing implementation details in migration scripts.
HIGHWeak password validation for CE edition
server/src/helpers/utils.helper.ts:17
[AGENTS: Passkey]credentials
CE edition password validation only requires 5 characters minimum and allows up to 100 characters. This is extremely weak and doesn't meet modern security standards. No complexity requirements are enforced.
Suggested Fix
Increase minimum password length to at least 12 characters for CE edition and add basic complexity requirements.
HIGHApp Git controller endpoints return NotFoundException without implementation
server/src/modules/app-git/controller.ts:23
[AGENTS: Mirage]false_confidence
All endpoints in AppGitController (getAppsMetaFile, gitSyncApp, getAppMetaFile, getAppConfig, createGitApp, pullGitAppChanges, renameAppOrVersion, updateAppGitConfigs, getAppGitConfigs) throw NotFoundException without implementing any security controls or business logic. This creates false confidence in Git app synchronization security.
Suggested Fix
Implement proper authentication, authorization, and business logic for app Git operations.
HIGHComplete controller with all endpoints returning NotImplementedException
server/src/modules/app-permissions/controller.ts:24
[AGENTS: Mirage]false_confidence
The entire AppPermissionsController has every endpoint throwing NotFoundException or similar. The controller is fully defined with routes, guards, and decorators, suggesting a complete permissions system, but all endpoints are non-functional. This is security theater - the appearance of a permissions system without implementation.
Suggested Fix
Either implement the endpoints or remove the controller until it can be properly implemented.
HIGHMissing tenant isolation in app findBySlug
server/src/modules/apps/repository.ts:11
[AGENTS: Tenant]tenant_isolation
The findBySlug method queries App by slug and organizationId, which is correct. However, the retrieveAppDataUsingSlug method queries by slug only, which could return an app from any organization, leaking data.
Suggested Fix
Modify retrieveAppDataUsingSlug to accept organizationId or ensure slug is globally unique.
HIGHMissing tenant isolation in app findOneById
server/src/modules/apps/repository.ts:48
[AGENTS: Tenant]tenant_isolation
The findOneById method queries App by id only, without organizationId. This could leak app data across tenants.
Suggested Fix
Add organizationId parameter and filter.
HIGHMissing tenant isolation in app findByAppId
server/src/modules/apps/repository.ts:91
[AGENTS: Tenant]tenant_isolation
The findByAppId method queries App by appId without organizationId. This could leak app data across tenants.
Suggested Fix
Add organizationId parameter and filter, or ensure app IDs are globally unique.
HIGHFeature ability guard defines empty ability with no actual authorization logic
server/src/modules/auth/ability/index.ts:20
[AGENTS: Mirage]false_confidence
The FeatureAbilityFactory.defineAbilityFor method has an empty implementation that returns nothing. This creates false confidence that feature-based authorization is enforced when it's actually completely permissive. The guard is used to protect routes but provides no actual authorization checks.
Suggested Fix
Implement actual feature authorization logic or remove the guard if authorization is not needed.
HIGHSAML configuration endpoint returns 404
server/src/modules/auth/oauth/controller.ts:40
[AGENTS: Passkey]saml_implementation
The getSAMLRedirect endpoint throws NotFoundException, indicating SAML configuration retrieval is not implemented. This breaks SAML authentication flow.
Suggested Fix
Implement SAML configuration retrieval to return proper authorization URLs.
HIGHAI onboarding endpoint not implemented
server/src/modules/auth/website/controller.ts:24
[AGENTS: Passkey]authentication_flow
The onboard endpoint throws NotImplementedException, indicating the AI user onboarding flow is incomplete. This could lead to security bypasses or improper user creation.
Suggested Fix
Implement complete AI user onboarding with proper validation, password hashing, and session management.
HIGHAI onboarding SSO endpoint not implemented
server/src/modules/auth/website/controller.ts:36
[AGENTS: Passkey]oauth_implementation
The commonSignIn endpoint for AI onboarding throws NotImplementedException, indicating SSO integration for AI users is incomplete.
Suggested Fix
Implement SSO authentication flow for AI onboarding users.
HIGHAI MFA endpoints not implemented
server/src/modules/auth/website/controller.ts:56
[AGENTS: Passkey]mfa_implementation
The AI MFA endpoints (request-otp and verify-otp) throw NotImplementedException, indicating incomplete MFA implementation for AI onboarding.
Suggested Fix
Implement complete MFA flow with secure OTP generation, storage, and verification.
HIGHMissing implementation for MFA OTP endpoints
server/src/modules/auth/website/otp-controller.ts:15
[AGENTS: Compliance]incident_response
The WebsiteOtpController declares MFA OTP endpoints but throws NotImplementedException. Missing MFA implementation violates SOC 2 CC6.1 (Multi-factor authentication where appropriate) and PCI-DSS requirement 8.3 (Secure all individual non-console administrative access and all remote access using multi-factor authentication).
Suggested Fix
Implement proper MFA OTP generation, validation, and secure storage with audit logging.
HIGHMFA OTP endpoint not implemented
server/src/modules/auth/website/otp-controller.ts:16
[AGENTS: Passkey]mfa_implementation
The OTP endpoints for AI MFA (request-otp and verify-otp) throw NotImplementedException, indicating MFA functionality is incomplete or missing. This leaves authentication without proper multi-factor protection.
Suggested Fix
Implement proper OTP generation, storage, and verification with rate limiting and expiration.
HIGHAI onboarding service not implemented
server/src/modules/auth/website/service.ts:17
[AGENTS: Passkey]mfa_implementation
The handleOnboarding method throws NotImplementedException, indicating the core authentication flow for AI users is incomplete. This could lead to security bypasses or improper user creation.
Suggested Fix
Implement complete user onboarding with proper password hashing, validation, and session management.
HIGHMissing tenant isolation in data query retrieval by ID
server/src/modules/data-queries/repository.ts:28
[AGENTS: Tenant]tenant_isolation
The getOneById method queries DataQuery by id without tenant filtering. This could leak query data across tenants.
Suggested Fix
Add organizationId parameter and filter via joins.
HIGHMissing tenant isolation in data query deletion
server/src/modules/data-queries/repository.ts:90
[AGENTS: Tenant]tenant_isolation
The deleteOne method deletes DataQuery by id without tenant filtering. This could allow a tenant to delete another tenant's query.
Suggested Fix
Add organizationId filter via a join or subquery.
HIGHMissing tenant isolation in data query update
server/src/modules/data-queries/repository.ts:96
[AGENTS: Tenant]tenant_isolation
The updateOne method updates DataQuery by id without tenant filtering. This could allow a tenant to update another tenant's query.
Suggested Fix
Add organizationId filter in the WHERE clause.
HIGHOAuth token error information disclosure
server/src/modules/data-queries/util.service.ts:258
[AGENTS: Fuse]error_security
When OAuth token refresh fails, the error handling combines API error and refresh token error messages, potentially leaking sensitive OAuth token information or internal service details.
Suggested Fix
Sanitize OAuth-related error messages. Don't combine multiple error messages. Log detailed OAuth errors internally but return generic authentication errors to users.
HIGHPlugin data source query lacks tenant filtering
server/src/modules/data-sources/repository.ts:183
[AGENTS: Tenant]tenant_isolation
The getDatasourceByPluginId method returns data sources across ALL organizations that use a specific plugin, without any tenant isolation. This could leak information about other organizations' data source configurations.
Suggested Fix
Add organizationId parameter and include WHERE organization_id = :organizationId in the query.
HIGHQueries by datasource ID lacks tenant validation
server/src/modules/data-sources/repository.ts:193
[AGENTS: Tenant]tenant_isolation
The getQueriesByDatasourceId method retrieves queries for a datasource without verifying the datasource belongs to the requesting organization. This could allow accessing queries from other organizations' data sources.
Suggested Fix
Add organizationId parameter and join with data_sources table to verify organization ownership.
HIGHSample data source retrieval lacks tenant isolation
server/src/modules/data-sources/services/sample-ds.service.ts:20
[AGENTS: Tenant]tenant_isolation
The getAllSampleDataSource method accepts organizationId as optional parameter and when null is passed, it returns ALL sample data sources across ALL organizations without any tenant filtering. This could expose sample data source configurations across tenant boundaries.
Suggested Fix
Remove the ability to fetch sample data sources without organizationId or implement proper tenant isolation by requiring organizationId parameter and including it in the WHERE clause.
HIGHSample data source update affects all organizations
server/src/modules/data-sources/services/sample-ds.service.ts:64
[AGENTS: Tenant]tenant_isolation
The updateSampleDs method calls getAllSampleDataSource with null organizationId, which retrieves ALL sample data sources across ALL organizations, then updates options for all of them. This creates a cross-tenant data modification vulnerability.
Suggested Fix
Either remove this method or implement tenant-specific updates by requiring organizationId parameter and filtering updates to only that organization's sample data sources.
HIGHMissing tenant isolation in folder update
server/src/modules/folders/service.ts:34
[AGENTS: Tenant]tenant_isolation
The updateFolder method updates Folder by id without verifying the organizationId. This could allow a user to update a folder from another organization if they guess the folder ID.
Suggested Fix
Include organizationId in the WHERE clause of the update statement.
HIGHMissing tenant isolation in folder findOne
server/src/modules/folders/util.service.ts:13
[AGENTS: Tenant]tenant_isolation
The findOne method retrieves a folder by folderId without organizationId. This could leak folder data across tenants.
Suggested Fix
Include organizationId in the WHERE clause.
HIGHSecurity-critical methods implemented as empty stubs
server/src/modules/git-sync/base-git-util.service.ts:20
[AGENTS: Mirage]false_confidence
The BaseGitUtilService class contains multiple security-critical methods (getOrganizationById, createAppGit, WriteAppFile, writeMetaFile, readAppJson, UpdateGitApp, updateAppGit, validateAppJsonForImport, updateGitSyncSettings) that all throw 'Method not implemented.' errors. These methods are part of Git operations infrastructure and their incomplete implementation creates false confidence in security controls for source control integration.
Suggested Fix
Implement proper security validation and business logic for each method, or mark the class as abstract and require concrete implementations.
HIGHController endpoints return NotFoundException without actual implementation
server/src/modules/git-sync/controller.ts:19
[AGENTS: Mirage]false_confidence
All endpoints in GitSyncController (getOrgGitStatusByOrgId, create, update, setFinalizeConfig, changeStatus, deleteConfig, getOrgGitByOrgId) throw NotFoundException without implementing any actual security validation or business logic. This creates false confidence that Git synchronization features are properly secured and implemented.
Suggested Fix
Implement proper authentication, authorization, and business logic for Git synchronization operations.
HIGHDangerous use of eval() for parsing log content
server/src/modules/log-to-file/constants/index.ts:75
[AGENTS: Blacklist]output_encoding
The readObjectFromLines function uses eval() to parse log file content, which is extremely dangerous. If log files can be modified or contain malicious content, this could lead to arbitrary code execution.
Suggested Fix
Replace eval() with JSON.parse() after properly constructing the JSON string. Ensure the log content is properly formatted as JSON before parsing.