Back to skill

Security audit

Query Payful Account

Security checks for vulnerabilities and agentic risk

Overview

This skill is a mostly straightforward Payful balance checker, but it can send full account session cookies to an arbitrary API URL if invoked with its custom endpoint option.

Review before installing. Only use this in a trusted environment, do not invoke --api-url with any unverified host, and prefer a version that removes or allowlists custom endpoints and uses scoped read-only Payful credentials instead of full browser session cookies.

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 (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/query_balance.py:31
Finding

Arbitrary API URL Allows Exfiltration of Payful Session Credentials

Content
View full analysis
dict: """Query Payful account balance.""" base_url = api_url or "https://global.payful.com" endpoint = f"{base_url}/api/user/account/queryUserAccBalByHomePage" user_id = get_env_var("PAYFUL_USER_ID") token = get_env_var("PAYFUL_TOKEN") cookie = f"AGL_USER_ID={user_id}; BF-INTERNATIONAL-MEMBER-TOKEN={token}" headers = { 'Accept': 'application/json, text/plain, */*', 'Accept-Language': 'zh-CN', 'Connection': 'keep-alive', 'Cookie': cookie, ``` ```python def main(): import argparse parser = argparse.ArgumentParser(description='Query Payful account balance') parser.add_argument('--api-url', help='Custom API base URL') parser.add_argument('--json', action='store_true', help='Output JSON') parser.add_argument('--raw', action='store_true', help='Output raw response') args = parser.parse_args() result = query_balance(args.api_url) ``` ### Technical Analysis The `--api-url` command-line option accepts an unrestricted URL and passes it directly to `query_balance`. The supplied value becomes the request's base URL, while the script unconditionally attaches the sensitive `PAYFUL_USER_ID` and `PAYFUL_TOKEN` values as cookies. No validation restricts the destination to an approved Payful hostname, enforces HTTPS, rejects unexpected ports, or otherwise establishes that credentials are being sent to a trusted origin. Consequently, a caller can select an attacker-controlled HTTP or HTTPS server as the destination. Use of plain HTTP would also expose the credentials to network interception. The documentation identifies these values as b ...[truncated 1939 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description claims the skill can query balance, transactions, and account details. However, the supplied code only calls one balance-specific endpoint (queryUserAccBalByHomePage) and processes balance fields such as available, frozen, and total amounts by currency/account type. There is no code for transaction history retrieval or broader account profile/details lookup. The environment variable requirements match, and there are no suspicious undeclared side capabilities, but the declared functionality overstates what the code actually does. Therefore this is a description/behavior mismatch.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares access to sensitive environment credentials and makes network requests, but does not define any explicit tool scope such as allowed tools or permissions. In an agent environment, this weakens sandboxing and review controls, making it easier for the skill to access secrets and exfiltrate account data without clear policy boundaries.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The API reference specifies Accept-Language: zh-CN, which forces a specific language/locale. The file does not offer users a language choice or explain why this locale restriction is required for a region-specific use case.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The request header hard-codes Accept-Language: zh-CN, and the user-facing output strings are also fixed in Chinese elsewhere in the file. This imposes a specific language/locale without opt-in or documented justification, which matches the language-policy violation criteria.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The optional --api-url parameter lets the script send the Payful session token and user ID cookie to any caller-supplied host, not just the legitimate Payful domain. In this skill’s context, that means credentials and account balance data can be exfiltrated through a normal-looking balance query, which is more dangerous because the skill’s stated purpose does not require arbitrary endpoints.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

A custom API base URL allows the request, including authentication cookies and returned financial data, to be redirected to an arbitrary endpoint without any warning to the user. Because this is a balance-query skill that relies on sensitive environment variables, the behavior creates a straightforward credential and financial-data exfiltration path.

Content

No source excerpt is available for this finding.

Excessive Permissions

Low
Category
Privilege Escalation
Confidence
84% confidence
Finding

The skill relies on browser session cookies that the documentation itself states grant full account access. Using full-session credentials for a narrow read-only task like balance lookup increases blast radius: if the skill, runtime, logs, or network path are compromised, an attacker could gain complete control of the Payful account rather than limited read access.

Content

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

md
This skill queries Payful account information via the Payful API.

> **Security notice**: `PAYFUL_TOKEN` and `PAYFUL_USER_ID` are sensitive browser session cookies extracted from global.payful.com. They grant full access to your Payful account. Only set these values in a trusted environment and never share them.

## Prerequisites