Back to skill

Security audit

work-fllows

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent NocoBase workflow guide, but it gives under-scoped instructions for raw SQL automation and bulk workflow deletion that could modify or remove live business data.

Review this skill carefully before installing. Use it only in environments where the agent is allowed to create and enable NocoBase workflows, and require explicit confirmation before enabling workflows, running raw SQL, or deleting workflows by prefix. Prefer higher-level update nodes or parameterized SQL, test in non-production first, and preview any workflows matched for deletion.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
skill.md:80
Finding
SQL Injection Through Unvalidated Workflow Variable in Auto-Numbering Query<![CDATA[ ## Vulnerability Details **File Location**: `skill.md:80` **Vulnerability Type**: SQL injection through direct template interpolation **Risk Level**: High ### Vulnerable Code ```text nb_add_node(wf_id, "sql", "Generate Number", '{"dataSource": "main", "sql": "UPDATE purchase_requests SET request_no = \'PR-\' || TO_CHAR(NOW(), \'YYYY\') || \'-\' || LPAD((SELECT COALESCE(MAX(CAST(SUBSTRING(request_no FROM \'[0-9]+$\') AS INT)),0)+1 FROM purchase_requests WHERE request_no LIKE \'PR-\' || TO_CHAR(NOW(), \'YYYY\') || \'-%\')::TEXT, 3, \'0\') WHERE id = {{$context.data.id}}"}') ``` ### Technical Analysis The SQL node directly inserts `{{$context.data.id}}` into executable SQL: ```sql WHERE id = {{$context.data.id}} ``` The template does not use a bound parameter, SQL escaping, quoting, or explicit numeric type validation. If an attacker can influence the trigger context or cause a crafted identifier to reach this variable, the resulting text can alter the intended SQL statement. Because the interpolation occurs in SQL syntax rather than in a parameter value, database parsing takes place after substitution. An injected expression or statement may therefore change the `WHERE` clause or execute additional SQL, subject to the template engine, database driver, and multi-statement configuration. The auto-numbering query also uses a `MAX(...)+1` sequence-generation pattern. Concurrent workflow executions can calculate the same next number, creating duplicate values unless a unique constraint and retry strategy are present. This concurrency issue is secondary to the injection risk. ### Attack Path 1. An attacker creates or manipulates a record or trigger payload that controls the value exposed as `$context.data.id`. 2. A collection workflow starts and evaluates the raw SQL node. 3. NocoBase substitutes the attacker-controlled value directly into the `WHERE id = ...` clause. 4. The database parses the substituted content as part of the SQL statement. 5. ...[truncated 855 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the raw SQL node with a NocoBase `update` node so the framework handles value binding: - Target collection: `purchase_requests` - Filter: record ID equal to the trigger record ID - Values: generated request number 2. If raw SQL is unavoidable, use the SQL node or database driver's supported bound-parameter mechanism. Do not concatenate workflow variables into SQL text. 3. Validate and normalize the identifier before database execution: - Require the expected type, such as a positive integer or canonical UUID. - Reject malformed, empty, or unexpected values. - Convert numeric identifiers to an integer before use. 4. Run the workflow under a least-privileged database account restricted to required tables and operations. 5. Add a unique constraint on `request_no`. 6. Replace `MAX(...)+1` with a database sequence, identity mechanism, or transactionally locked counter to prevent duplicate numbers during concurrent execution. 7. Add negative tests using malformed identifiers and verify that no generated SQL syntax can be influenced by trigger data. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
skill.md:149
Finding
SQL Injection Through Unvalidated Workflow Variable in Scheduled Insurance Update<![CDATA[ ## Vulnerability Details **File Location**: `skill.md:149` **Vulnerability Type**: SQL injection through direct template interpolation **Risk Level**: High ### Vulnerable Code ```text nb_add_node(wf_id, "sql", "Mark Expiring", '{"dataSource": "main", "sql": "UPDATE insurance SET remark = \'expiring soon\' WHERE id = {{$context.data.id}}"}') ``` ### Technical Analysis The scheduled workflow inserts `{{$context.data.id}}` directly into a raw SQL statement: ```sql UPDATE insurance SET remark = 'expiring soon' WHERE id = {{$context.data.id}} ``` No parameter binding, escaping, quoting, or identifier type validation is shown. If the workflow context can contain an attacker-influenced value, substitution occurs before the database parses the statement. The value can consequently be interpreted as SQL syntax rather than as an inert identifier. Although date-based triggers commonly obtain identifiers from existing records, the skill is generic and does not require those identifiers to be trusted, generated by the database, or validated. Records imported from external systems, custom trigger contexts, or compromised application data can therefore expose the SQL node to malicious input. ### Attack Path 1. An attacker causes a crafted identifier to be stored in or supplied through the record used by the date-based workflow trigger. 2. The scheduled workflow runs when the configured date condition is met. 3. The SQL node substitutes `$context.data.id` into the statement without validation or parameterization. 4. The database interprets the substituted value as part of the `WHERE` clause. 5. The payload may alter the predicate to update additional rows or execute additional statements if supported by the SQL execution interface. 6. Operations run with the permissions of the configured `main` data source. ### Impact Assessment At minimum, exploitation could cause unauthorized modification of multiple `insurance` records. If stacked statements or more ...[truncated 444 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer the documented NocoBase `update` node instead of raw SQL: - Collection: `insurance` - Filter: `id` equals `{{$context.data.id}}` - Value: `remark` equals `expiring soon` 2. If SQL must be used, pass the identifier through a supported bound parameter rather than interpolating it into the SQL string. 3. Enforce the identifier schema before execution: - Parse numeric IDs as integers. - Validate UUIDs against a strict canonical format. - Reject missing or malformed values. 4. Restrict the `main` data source account to the minimum required table and statement privileges. 5. Confirm that the SQL execution interface rejects multiple statements. 6. Add tests with malicious and malformed trigger values to ensure they cannot change SQL structure or expand the update scope. 7. Log failed validation events without recording sensitive payloads, and alert on repeated malformed workflow inputs. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This section provides a ready-to-run pattern that combines raw SQL data modification with workflow enablement, but does not warn that enabling the workflow can immediately automate future writes to production data. In this skill's context, the danger is elevated because it is operational guidance for automation tooling, so unsafe examples can cause persistent, repeated data changes rather than a one-time mistake.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill explicitly recommends bulk cleanup via `nb_delete_workflows_by_prefix("AM-")` without any warning that this can delete multiple workflows at once. In an agent setting, that omission is dangerous because a user may request cleanup casually and the agent could perform irreversible destructive actions across many workflows.

Static analysis

No suspicious patterns detected.