Back to skill

Security audit

The Agent SaaS Factory: Build, Deploy, and Monetize Software Products with Autonomous AI Agents

Security checks for vulnerabilities and agentic risk

Overview

This is a non-executing guide, but its examples direct agents to perform broad code, database, billing, and dispute actions with weak boundaries.

Review carefully before installing. Treat this as high-risk operational guidance: use only sandbox or test accounts unless you add endpoint allowlisting, separate least-privilege credentials, human approval for merges, migrations, payments, and disputes, redaction for logs/issues, and production-grade audit controls.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (6)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:161
Finding

Caller-Controlled Gateway URL Can Exfiltrate API Credentials and Sensitive Payloads

Content
View full analysis
dict: """Execute a tool on the GreenHelix gateway.""" resp = self.session.post( f"{self.base_url}/v1", json={"tool": tool, "input": input_data}, ) if resp.status_code == 402: raise BudgetExhaustedError( f"Agent {self.agent_id} budget exceeded: {resp.text}" ) resp.raise_for_status() return resp.json() ``` The same pattern is repeated by the database, billing, and dispute clients. ### Technical Analysis The client installs the bearer credential into a persistent `requests.Session`, but accepts an arbitrary `base_url` without validating its scheme or hostname. Consequently, the credential and every tool payload are sent to whichever endpoint the caller supplies. This is especially sensitive because payloads may contain repository contents, SQL statements and query parameters, customer names and email addresses, payment identifiers, invoice information, and dispute evidence. The implementation also permits an `http://` URL, allowing the bearer credential and payload to be transmitted without transport encryption. Sending authenticated requests to the declared GreenHelix API is necessary for the guide's stated integration functionality. Allowing unrestricted replacement of the credential-bearing destination is not necessary and exceeds a safe minimum-trust design. ### Attack Path 1. An attacker infl ...[truncated 983 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:1261
Finding

A Single Broad Credential Is Reused Across Repository, Database, and Billing Authorities

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:579
Finding

Unrestricted SQL Execution Enables Destructive Database Operations

Content
View full analysis
dict: """Run a SELECT query. Read-only.""" payload = {"sql": sql} if params: payload["params"] = params return self._execute("query", payload) def execute_query( self, sql: str, params: Optional[List] = None, ) -> dict: """Run any SQL statement (INSERT, UPDATE, DELETE, DDL).""" payload = {"sql": sql} if params: payload["params"] = params return self._execute("execute_query", payload) def execute_migration( self, migration_sql: str, version: str, description: str, ) -> dict: """Run a schema migration with version tracking.""" return self._execute("execute_migration", { "migration_sql": migration_sql, "version": version, "description": description, }) def schema_first_design( self, tables: dict, ) -> List[dict]: results = [] for table_name, columns in tables.items(): col_defs = ", ".join(columns) sql = f"CREATE TABLE IF NOT EXISTS {table_name} ({col_defs})" result = self.execute_query(sql) results.append({"table": table_name, "result": result}) return results ``` ### Technical Analysis `execute_query` and `execute_migration` intentionally accept unrestricted SQL, including destructive DDL and DML. In addition, `schema_first_design` directly interpolates table names and complete column definitions into SQL. SQL value parameters cannot protect identifiers or raw schema fragments. The guide later presents a regular-expression SQL validator, but it is only shown as a comment and is not integrated into `AgentDBA._execute`. Even if integrated, a blacklist would not safely constrain arbitrary SQL grammar or prevent all destructive ...[truncated 1316 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:348
Finding

Repository Automation Writes to Main and Self-Approves Merges

Content
View full analysis
List[dict]: results = [] for path, content in files.items(): result = self.create_or_update_file( owner=owner, repo=repo, path=path, content=content, message=f"scaffold: add {path}", branch=branch, ) results.append(result) return results def review_and_merge( self, owner: str, repo: str, head_branch: str, title: str, description: str, ) -> dict: pr = self.create_pull_request( owner=owner, repo=repo, title=title, body=description, head=head_branch, base="main", ) pull_number = pr["number"] issues_found = [] for pattern in ["eval(", "exec(", "password =", "secret ="]: hits = self.search_code( query=pattern, owner=owner, repo=repo, ) if hits.get("total_count", 0) > 0: issues_found.append(pattern) if issues_found: self.create_issue( owner=owner, repo=repo, title=f"Security review: patterns found in PR #{pull_number}", body=f"Found: {', '.join(issues_found)}. Review before merge.", labels=["security", "automated-review"], ) return {"status": "blocked", "pr": pr, "issues": issues_found} merged = self.merge_pull_request( owner=owner, repo=repo, pull_number=pull_number, ) return {"status": "merged", "pr": pr, "merge": merged} ``` ### Technical Analysis The scaffolding workflow defaults to writing directly to `main`. The same autonomous agent can also cr ...[truncated 1441 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:1383
Finding

Build Manifest Is Published to an Issue Without Data Minimization

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:1665
Finding

Automated Dispute Resolution Uses Insufficient Evidence and Exposes Customer Identifiers

Content
View full analysis
dict: dispute = self.get_dispute(dispute_id) amount = dispute.get("amount_cents", 0) if amount > self.escalation_rules.require_human_above: return { "action": "escalated", "reason": f"Amount ${amount/100:.2f} exceeds auto-resolve threshold", "dispute": dispute, } if self._auto_resolve_count >= self.escalation_rules.max_auto_resolve_count: return { "action": "escalated", "reason": "Auto-resolve count limit reached", "dispute": dispute, } tx_id = dispute.get("transaction_id", "") payment = billing.get_payment_intent(tx_id) db_records = dba.query( "SELECT * FROM revenue_events WHERE stripe_payment_intent_id = $1", params=[tx_id], ) evidence = { "payment_status": payment.get("status"), "payment_created": payment.get("created"), "delivery_confirmed": len(db_records.get("rows", [])) > 0, "customer_id": payment.get("customer"), } self.respond_dispute( dispute_id=dispute_id, response_text=( f"Payment {tx_id} was completed successfully on " f"{payment.get('created')}. Service delivery confirmed " f"in application database. Customer ID: {payment.get('customer')}." ), evidence=evidence, ) if amount <= self.escalation_rules.max_amount_cents: resolution = self.resolve_dispute( dispute_id=dispute_id, resolution="rejected", notes="Auto-resolved: evidence confirms valid transaction", ) self._auto_resolve_count ...[truncated 2034 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (11)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · SKILL.md (reported line 489)May include surrounding context.

md
"## Requirements\n"
        "- POST /api/subscribers to add new subscriber\n"
        "- GET /api/subscribers to list all subscribers\n"
        "- DELETE /api/subscribers/:id to unsubscribe\n"
        "- Store in Postgres with email uniqueness constraint\n\n"
        "## Acceptance Criteria\n"
        "- All endpoints return JSON\n"

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · SKILL.md (reported line 2118)May include surrounding context.

From a human operator's terminal:

touch /tmp/agent_kill_switch <-- stops the agent immediately

rm /tmp/agent_kill_switch <-- allows it to resume

text

---

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The guide presents full automation across GitHub, Postgres, Stripe, and dispute tooling but does not prominently warn that these examples perform real write actions affecting code, databases, billing objects, and customer-facing workflows. In this context, the omission increases operational risk because users may treat the content like passive documentation while enabling high-impact capabilities with live credentials.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This code sends authenticated requests containing tool names and user-supplied inputs to an external endpoint, creating a clear external data transmission path. In a skill that orchestrates repositories, databases, and billing, that means sensitive business data, code, metadata, or credentials-adjacent information may be transmitted off-host to a third-party service.

Content

Scanner excerpt · SKILL.md (reported line 163)May include surrounding context.

md
self,
        api_key: str,
        agent_id: str,
        base_url: str = "https://api.greenhelix.net/v1",
    ):
        self.base_url = base_url
        self.agent_id = agent_id

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The AgentDBA client forwards database operations to an external API endpoint, so schema details, SQL text, query parameters, and potentially sensitive records can leave the local environment. That is materially significant here because the skill is positioned for autonomous management of SaaS production data.

Content

Scanner excerpt · SKILL.md (reported line 544)May include surrounding context.

md
self,
        api_key: str,
        agent_id: str,
        base_url: str = "https://api.greenhelix.net/v1",
    ):
        self.base_url = base_url
        self.agent_id = agent_id

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The guide documents AgentDBA.query as "read-only," but the implementation simply forwards arbitrary SQL to the remote gateway without verifying that the statement is a SELECT or otherwise non-mutating. In an autonomous-agent context, that mismatch is dangerous because downstream users or agents may trust the interface contract and accidentally execute destructive or state-changing SQL against production data.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The billing client transmits payment-related operations to an external API gateway, which can involve customer identifiers, invoice/payment metadata, and transaction context. In a payment workflow, such transmissions are inherently sensitive and can have financial and compliance implications if not clearly bounded and disclosed.

Content

Scanner excerpt · SKILL.md (reported line 888)May include surrounding context.

md
self,
        api_key: str,
        agent_id: str,
        base_url: str = "https://api.greenhelix.net/v1",
    ):
        self.base_url = base_url
        self.agent_id = agent_id

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

The factory class centralizes repo, database, and billing actions behind one externally connected orchestrator, magnifying the sensitivity of outbound transmissions. A single build operation may send code, schema, pricing, and operational metadata to the remote service, so misuse or misunderstanding can have broad blast radius.

Content

Scanner excerpt · SKILL.md (reported line 1266)May include surrounding context.

md
self,
        api_key: str,
        agent_id: str,
        base_url: str = "https://api.greenhelix.net/v1",
    ):
        self.developer = AgentDeveloper(
            api_key=api_key,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The dispute automation section describes automatic responses and resolutions without a clear warning that these actions can directly affect customer funds, chargeback outcomes, and legal/compliance posture. Because the skill targets autonomous operation, missing this warning makes harmful financial decisions more likely to be delegated without adequate human review.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The dispute automation client transmits dispute details, evidence, transaction references, and resolution actions to an external gateway. Given that this affects customer funds and adjudication outcomes, the transmission path is particularly sensitive and should be treated as high-risk rather than routine telemetry.

Content

Scanner excerpt · SKILL.md (reported line 1595)May include surrounding context.

md
self,
        api_key: str,
        agent_id: str,
        base_url: str = "https://api.greenhelix.net/v1",
        escalation_rules: Optional[EscalationRule] = None,
    ):
        self.base_url = base_url

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill recommends branch protection and states agents should never write directly to protected branches, but multiple examples default to branch="main" or omit a branch so writes land on the default branch. This contradiction weakens the control in practice and can let autonomous code changes bypass review, increasing the chance of unsafe code, secrets, or destructive config changes being committed directly.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.