Back to skill

Security audit

Form Builder Pro

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent form builder, but its custom template rendering is powerful enough to become unsafe if used with untrusted templates or form definitions.

Review this before installing in any web-facing or multi-user environment. Use it only with trusted templates and trusted form definitions unless the renderer is changed to use sandboxing, autoescaping, strict validation, and pinned dependencies.

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
scripts/form_engine.py:236
Finding

Unrestricted Jinja2 Template Rendering Enables Server-Side Template Injection

Content
View full analysis
str: """Use a Jinja2 template to render the form.""" if template_str is None: template_str = self._default_template() template = Template(template_str) return template.render( form=self, fields=self.fields, name=self.name, description=self.description ) ``` ### Technical Analysis The `render` method compiles `template_str` directly with the unrestricted Jinja2 `Template` class. No sandbox, template allowlist, or trust-boundary enforcement is applied. The template context also exposes rich Python objects: - `form` references the complete `Form` instance. - `fields` contains `Field` instances. - Object attributes and methods are available to the template engine. Jinja2 templates are executable expressions rather than inert presentation data. If an untrusted party can influence `template_str`, the party may use object traversal to reach Python internals. In an unrestricted environment, this can potentially lead to local file access, disclosure of process data, or arbitrary command execution. The current examples use a hardcoded custom template, but the public method accepts any string and does not document or enforce that the template must be trusted. ### Attack Path 1. An application accepts a custom form template from a user, tenant, uploaded file, database record, or other untrusted source. 2. The application passes that content to `Form.render(template_str)`. 3. The method compiles the attacker-controlled content using unrestricted `jinja2.Template`. 4. The malicious template traverses exposed Python objects or their classes to reach sensitive runtime functionality. 5. The payload executes with the permissions and environment of the Pytho ...[truncated 890 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/form_engine.py:236
Finding

Disabled HTML Autoescaping Allows Stored or Reflected Cross-Site Scripting

Content
View full analysis
str: """Use a Jinja2 template to render the form.""" if template_str is None: template_str = self._default_template() template = Template(template_str) return template.render( form=self, fields=self.fields, name=self.name, description=self.description ) def _default_template(self) -> str: """Default HTML template.""" return """ {% if description %}

{{ description }}

{% endif %} {% for field in fields %}
{{ field.label }} {% if field.required %}*{% endif %} {% if field.type == 'textarea' %} {{ field.default or '' }} {% elif field.type == 'select' %} {% for opt in field.options %} {{ opt.label }} {% endfor %} {% else %}
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (12)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The README presents the skill title and primary descriptive content in Chinese first, with no instruction that users may choose their preferred language. Under the policy, language constraints should be optional or explicitly justified; this file does not provide that opt-in or justification.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill metadata advertises functionality that likely reads YAML/config files and may serialize or write form-related data, but it declares no explicit tool scope such as permissions or allowed-tools. This creates an authorization ambiguity where a host agent may grant broader file access than users expect, increasing the risk of unintended local file reads or writes if the skill is invoked on attacker-controlled paths.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file's user-facing text, docstrings, labels, and printed messages are entirely in Chinese, which imposes a specific language/locale without any indication of user opt-in or configurability. Under the stated policy, locale-specific behavior should either be optional or explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The default rendered form hard-codes the submit button text as '提交', and the file-level descriptions/comments are also Chinese-centric. This creates a natural-language locale constraint in user-facing behavior without any opt-in, language selection, or documented region-specific justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The metadata description includes fixed Chinese and English text, and the document overall duplicates content in both languages without saying how language should be chosen for the user. Under the policy rule, fixed language behavior can be a concern when no explicit user choice or opt-in is described.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code performs a filesystem write by creating /tmp/survey_form.yaml. Although the inline comment notes that the file is being saved, there is no user-facing disclosure such as a print statement or warning indicating that running the example will create a file on disk.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified with only a lower bound, which makes builds non-reproducible and allows future installs to resolve to unexpected versions, including versions with new vulnerabilities or breaking security behavior. In a form engine context, this matters because jsonschema participates in validation of potentially untrusted user-supplied schemas and data, so dependency drift can affect security and correctness.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
jsonschema>=4.19.0
pyyaml>=6.0
jinja2>=3.1.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
99% confidence
Finding

PyYAML is unpinned, so deployments may install different versions over time, including versions affected by known unsafe parsing or input-validation issues. Given this skill is a form builder that may ingest configuration-like data, YAML handling increases risk because unsafe or outdated parser behavior can expose deserialization or parsing-related vulnerabilities when processing untrusted content.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
jsonschema>=4.19.0
pyyaml>=6.0
jinja2>=3.1.0

Unverifiable Dependency: pyyaml has 8 known advisory(ies) (CVE-2019-20477 (Deserialization of Untrusted Data in PyYAML); CVE-2020-1747 (Improper Input Validation in PyYAML); CVE-2020-14343 (Improper Input Validation in PyYAML) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
97% confidence
Finding

Because PyYAML is not pinned, the manifest cannot prove that deployed installations avoid versions with known advisories, several of which relate to unsafe handling of untrusted data. This is more concerning in this skill than in a generic utility because a form builder may process externally supplied schemas or configuration, making parser safety directly relevant to attack surface.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
99% confidence
Finding

Jinja2 is unpinned, which permits uncontrolled version selection and makes it impossible to guarantee that only patched releases are installed. In a dynamic form-rendering engine, template processing is security-sensitive because templating libraries can become vectors for sandbox escape, server-side template injection, or unsafe rendering behavior if vulnerable versions are used.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
jsonschema>=4.19.0
pyyaml>=6.0
jinja2>=3.1.0

Unverifiable Dependency: jinja2 has 16 known advisory(ies) (CVE-2019-10906 (Jinja2 sandbox escape via string formatting); CVE-2014-1402 (Incorrect Privilege Assignment in Jinja2); CVE-2025-27516 (Jinja2 vulnerable to sandbox breakout through attr filter selecting format metho) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The manifest leaves Jinja2 version selection open-ended, so installations could resolve to releases impacted by known vulnerabilities, including sandbox-escape-style issues. This is especially relevant for a form engine advertising dynamic rendering and conditional logic, because templating functionality often processes user-influenced content and therefore sits on a sensitive execution boundary.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file header uses Chinese-only descriptive text ("单元测试"), and the rest of the file's docstrings, labels, and messages are also written exclusively in Chinese. Under the policy for natural-language content, forcing a specific language without opt-in or justification can be a locale-policy violation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.