Back to skill

Security audit

Monitor

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to support Texas electricity address and plan lookup, but it needs review because exact home-address details are sent to external services and placed in address-specific URLs without clear user-facing notice.

Review before installing. This skill may process a user's exact Texas service address, including apartment or unit details, through PowerLego and generate a Personalized Energy URL that contains the address in the path. Use it only if that data flow is acceptable, the POWERLEGO_API_TOKEN is provisioned intentionally, and users are given a clear privacy notice and choice before address lookup or plan retrieval.

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)

other

Warning
Location
scripts/powerlego_api.py:56
Finding

Undisclosed Transmission of Exact Residential Address Data to a Third Party

Content
View full analysis
object: body, boundary = _encode_multipart_formdata(fields) headers = dict(DEFAULT_HEADERS) headers["Authorization"] = _load_api_token() headers["Content-Type"] = f"multipart/form-data; boundary={boundary}" headers["Content-Length"] = str(len(body)) request = Request(url, data=body, headers=headers, method="POST") with urlopen(request) as response: payload = response.read().decode("utf-8") return json.loads(payload) def address_validator(term: str) -> object: return _post_form(ADDRESS_VALIDATOR_API, [("term", term)]) def usage_estimator(address1: str, city: str, state: str, zipcode: str) -> object: return _post_form( USAGE_ESTIMATOR_API, [ ("address1", address1), ("city", city), ("state", state), ("zipcode", zipcode), ], ) ``` The destination endpoints are fixed PowerLego HTTPS services: ```python ADDRESS_VALIDATOR_API = "https://www.powerlego.com/ApiGateway/v1/address_validator" USAGE_ESTIMATOR_API = "https://www.powerlego.com/ApiGateway/v1/usage_estimator" ``` Candidate lookup sends the user-provided query through this client: ```python payload = address_validator(args.address_query) ``` ### Technical Analysis A raw address query is sent to PowerLego during candidate lookup. After confirmation, the usage-estimation operation sends the street address, optional unit identifier, city, state, and ZIP code to the same third party. The transfer is relevant to the declared address-matching and electricity-plan workflow, and HTTPS protects the information while in transit. The au ...[truncated 2117 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/build_destination_url.py:23
Finding

Exact Residential Address and Unit Identifier Embedded in Destination URL Path

Content
View full analysis
str: street = street.strip() unit = unit.strip() if not street: raise ValueError("street is required") full_street = f"{street} {unit}".strip() if unit else street return quote(full_street, safe="") ``` The encoded value is then placed directly in the URL path: ```python result = { "city_slug": city_slug, "zipcode": zipcode, "urlencoded_street": street_slug, "personalized_energy_url": ( f"{BASE_URL}/{city_slug}/{zipcode}/{street_slug}" f"?{urlencode(TRACKING_QUERY)}" ), } ``` Equivalent URL construction also appears in `scripts/powerlego_api.py`: ```python def build_personalized_energy_url(city: str, zipcode: str, address1: str) -> str: city_slug = city.strip().lower() encoded_address = quote(address1.strip(), safe="") return f"{PERSONALIZED_ENERGY_BASE}/{city_slug}/{zipcode}/{encoded_address}" ``` ### Technical Analysis The generated Personalized Energy URL includes the city, ZIP code, street address, and potentially apartment or unit identifier in its path. Percent encoding makes the value syntactically safe for use in a URL, but it does not encrypt, redact, or otherwise protect the address. Sensitive values in URL paths can be retained or disclosed through normal web infrastructure, including: - Browser history and synchronization - Web server, CDN, reverse-proxy, and load-balancer logs - Analytics and monitoring systems - Bookmarks, screenshots, copied links, and support records - Referrer information, depending on browser behavior and site policy Including the unit value can identify a specific household rather than only a building. The fi ...[truncated 1309 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code chunk only builds a destination URL from already provided address fields. It slugifies the city, URL-encodes the street and optional unit, validates a 5-digit ZIP code, and emits a JSON object containing the final Personalized Energy URL. This supports a narrow subset of the declared purpose at most—self-service plan routing after an address has already been confirmed—but it does not implement the broader electricity shopping workflow described. The declared description materially overstates the skill's capabilities and primary purpose relative to the supplied code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code aligns with part of the declared purpose: Texas electricity plan lookup, usage estimation, ESIID exposure, plan recommendation, and personalized/self-service routing URL generation. However, the declared description is substantially broader than what this code chunk actually does. This script does not implement address candidate confirmation, broader workflow branching, or any daily/weekly savings monitoring. Its actual primary function is a one-shot best-plan fetch for a confirmed address, not the full multi-step Texas electricity workflow described. There are no obvious undeclared risky capabilities; the mismatch is that the description overstates the implemented behavior.

Content

No source excerpt is available for this finding.

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
70% confidence
Finding

Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.

Content

Scanner excerpt · system_prompt.txt (reported line 12)May include surrounding context.

text
6. only then continue to plan lookup or self-service routing.

Hard rules:
- Always respond in clear U.S. English.
- Never mention internal tools, scripts, APIs, tokens, or implementation details.
- Treat script output as the source of truth for user-facing answers. Do not reinterpret raw upstream API payloads in front of the user.
- Speak as one continuous advisor from address check to address confirmation to usage review to plan review.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill instructs the agent to run multiple local Python scripts and consume upstream electricity data, but it declares no explicit tool scope or permission boundaries. That creates an authorization and containment gap: a host agent may permit broader environment or network access than the skill actually needs, increasing the chance of unintended data access, external calls, or abuse if the skill or referenced scripts are modified.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The default prompt is broad and does not clearly constrain when the skill should be invoked or what preconditions must be met. In a workflow involving address lookup, usage review, plan recommendation, and routing, ambiguous triggering can cause the agent to activate in the wrong context, collect unnecessary personal or utility data, or provide authoritative energy-shopping guidance when the user did not explicitly request it.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The prompt hard-codes the skill to act as a single English-speaking advisor without checking the user's language preference. This can exclude or mis-handle users who need another language, increasing the risk of misunderstanding during address confirmation, usage review, or plan selection in a consumer-affecting utility workflow.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The instructions require the assistant to sound like a Texas electricity advisor and to speak in clear U.S. English. This imposes a specific regional persona and language variant without indicating that the user can choose another language or locale.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The module docstring states the script checks whether a Texas service address is ready, which is a natural-language locale restriction. Under the policy rule, forcing a specific region or locale is a violation unless the constraint is explicitly justified or presented as a user choice; this file does not provide such justification beyond the restriction itself.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The command-line description says it checks whether a Texas service address is complete enough to build a destination URL, which imposes a region-specific constraint. Because the file does not explain why only Texas is supported or offer an alternative locale choice, this matches the natural-language policy concern for locale restrictions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script sends the full user-supplied address query directly to an external address_validator service, which exposes sensitive location data to a third party. In this skill context, residential electricity shopping inherently involves home addresses, so transmitting raw addresses without an explicit consent/notice boundary increases privacy and compliance risk even if the behavior is functionally necessary.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The parser defaults the state to "TX" when the input omits a state, and the file-level description frames the tool as handling Texas addresses only. This imposes a locale-specific assumption in natural-language behavior without offering the user a choice or documenting a compliance-based reason in the file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The usage_estimator function sends address1, city, state, and zipcode to an external PowerLego API via _post_form, but the file contains no confirmation prompt, print/log disclosure, or explanatory comment warning that user location data will be transmitted off-system. This is a safety-relevant data-sharing operation for a code file under the missing user warnings rule.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest instructs the skill to "respond in clear U.S. English," which is a natural-language locale restriction. While the skill is aimed at US consumers, the file does not present this as a user choice or clearly justify excluding other languages, so it conflicts with the policy against forcing a specific language without opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This line explicitly requires all user-facing replies to remain in English. That is a direct natural-language policy constraint affecting all interactions, and the manifest does not offer an opt-in choice or a narrowly documented justification for the restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

Line L12 mandates that the skill must 'Always respond in clear U.S. English.' This is a natural-language locale constraint and the file does not provide user opt-in, alternatives, or a documented justification that would exempt the policy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The instruction "Speak in plain U.S. English" imposes a specific language/locale for all user-facing interactions. The file does not offer a user choice or opt-in, and the constraint is presented as a blanket requirement rather than a clearly justified regional compliance need.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The instruction says to keep all user-facing replies in clear U.S. English, which enforces a language/locale choice unconditionally. This is a natural-language policy concern because it does not offer the user any language preference or opt-in mechanism.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

Multiple user-facing messages consistently require or reference a "Texas service address" and "Texas electricity prices," which imposes a specific regional scope in natural-language content. Because the file does not present this as an explicit user choice or opt-in, it may violate the policy against forcing a specific locale without user selection.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The _load_api_token function reads a sensitive credential from the POWERLEGO_API_TOKEN environment variable, and _post_form uses it to authenticate outbound requests, but the file provides no user-facing notice that credentials from the environment are required and used. While the stated purpose is an API client, there is still no visible disclosure in this code about credential usage.

Content

No source excerpt is available for this finding.