Back to skill

Security audit

Xanadu Portfolio Optimizer

Security checks for vulnerabilities and agentic risk

Overview

The skill’s portfolio tools are mostly coherent, but it ships unsafe billing code with a hardcoded payment API key and a charge function that can send user IDs and amounts to an external billing service.

Review this skill before installing. The portfolio optimizer itself is user-invoked and uses expected market-data lookups, but the bundled billing files should not ship with a hardcoded SkillPay key or an unconstrained charge method. Install only if the publisher rotates the exposed credential, removes secrets from source, clearly documents billing consent and data flow, and fixes the stale Social Media Manager metadata and broken --file interface.

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/billing_config.py:1
Finding

Hardcoded SkillPay API Credential and Sensitive Billing Data Transmission

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (10)

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The top-level documentation says this file is for "SkillPay Integration for Xanadu Social Media Manager," implying social media management functionality, but the actual implemented behavior is a payment client that reads billing credentials and performs remote charge requests. This is an active intent mismatch between the documented identity/purpose of the file and what the code actually does.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This skill loads billing credentials and implements remote charging logic without any clear, documented user-facing purpose or authorization flow in the provided context. In an agent skill ecosystem, undisclosed payment and credential-handling capabilities are dangerous because they enable monetization or data transmission beyond what a user may reasonably expect.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/billing.py (reported line 26)May include surrounding context.

python
def __init__(self, api_key: str = None, skill_id: str = None):
        self.api_key = api_key or SKILLPAY_API_KEY
        self.skill_id = skill_id or SKILL_ID
        self.base_url = "https://api.skillpay.me/v1"
        
        if not self.api_key:
            raise ValueError("SkillPay API key required")

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

This code performs an external POST to a payment endpoint, transmitting billing-related data off-system. External transmission is especially sensitive in agent skills because it can expose user identifiers and trigger financial actions without transparent review or runtime controls.

Content

Scanner excerpt · scripts/billing.py (reported line 36)May include surrounding context.

python
amount = amount or DEFAULT_PRICE
        
        try:
            response = requests.post(
                f"{self.base_url}/charge",
                json={
                    "api_key": self.api_key,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The charge method sends an API key, user ID, and amount to an external service with no visible disclosure, consent, or confirmation mechanism. In a skill context this can result in silent billing, unexpected transmission of identifiers, and misuse of payment credentials if the function is invoked by another component without strong policy checks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

A live-looking secret API key is hardcoded directly in source code, which makes it accessible to anyone with repository or artifact access and likely to be harvested automatically by secret-scanning tools or attackers. Exposure of a billing or payment-related credential can enable unauthorized API use, fraudulent charges, service abuse, or compromise of connected billing operations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script sends user portfolio ticker symbols to yfinance without explicit disclosure or consent. While symbol lookups are central to the tool's purpose, portfolio composition can still be sensitive financial metadata, and transmitting it to a third-party service may leak private investment information or violate user expectations in local/offline contexts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

Sector analysis performs additional third-party lookups for each portfolio symbol, increasing unnecessary disclosure beyond the minimum required for core valuation. Repeated undisclosed requests can expand the privacy footprint of the user's portfolio and make traffic analysis easier.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

Historical price retrieval for volatility analysis makes further external requests for portfolio symbols without clearly informing the user. In a financial tool, this can expose additional details about user holdings and analysis behavior to third-party services, even if no direct compromise occurs.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The harvest subcommand defines an optional --file argument, implying the tool can read holdings from a JSON file. However, the dispatch logic always calls tax_loss_harvest(args.holdings) and never uses args.file, so the documented interface contradicts actual behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.