T09 · Insecure Skill Coding Practices
- Location
scripts/aoment_visuals.py:133- Finding
Unrestricted reference-image URL retrieval enables internal resource disclosure
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a real Aoment image/video generation skill, but it needs review because it requires unverified remote updates and can fetch arbitrary reference-image URLs from the user's environment before uploading them to Aoment.
Install only if you are comfortable sending prompts, reference images, nicknames, API keys, and generated-media downloads through Aoment. Do not let an agent auto-replace this skill from the latest ZIP without manual review and integrity checks. Avoid passing sensitive internal URLs as reference images, and prefer safer credential handling than putting real API keys directly in shell commands.
scripts/aoment_visuals.py:133Unrestricted reference-image URL retrieval enables internal resource disclosure
SKILL.md:12Mandatory unsigned remote Skill updates permit post-audit payload substitution
scripts/aoment_visuals.py:3Unpinned runtime dependency creates avoidable supply-chain exposure
scripts/aoment_visuals.py:231Bearer API keys exposed through command-line arguments
The documentation promises image/video generation and API-key registration, but the analyzed package appears not to implement those functions and instead includes other behavior such as quota/account querying. A description-behavior mismatch prevents informed consent, impairs review, and can hide unexpected network or account-related operations behind a benign-looking skill label.
The skill instructs the agent to take a URL returned by an external service and immediately fetch it with curl. This is effectively a second-stage network fetch controlled by remote output, which can enable SSRF-like behavior, retrieval of unexpected content, large-file abuse, or downloading from untrusted domains if response validation is absent.
# Download image
curl -L -o output.jpg "$(uv run {baseDir}/scripts/aoment_visuals.py -k <your-api-key> -t text-to-image -p 'prompt' | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['image_url'])")"
# Or in two steps:
# 1. Generate
The documented pipeline feeds tool output directly into another command without an approval or validation boundary. When a network-facing script can influence the argument passed to curl, an attacker controlling the upstream response can steer the agent into unintended network actions or resource consumption.
# Download image
curl -L -o output.jpg "$(uv run {baseDir}/scripts/aoment_visuals.py -k <your-api-key> -t text-to-image -p 'prompt' | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['image_url'])")"
# Or in two steps:
# 1. Generate
The skill declares no explicit tool scope or allowed-tools despite documented behavior that requires network access and likely file interaction. Missing capability scoping increases the chance an agent runtime grants broader permissions than necessary, which weakens containment if the skill or its dependencies are compromised.
The skill instructs the agent to download and replace the skill package from a remote URL before use based only on freshness, not integrity. This creates a supply-chain execution path where a compromised host, tampered archive, or malicious update can change agent behavior and gain whatever permissions the skill has.
Instructing agents to fetch updated skill packages automatically without warning about executable-code risk normalizes unsafe behavior and bypasses normal review controls. In the context of agent skills, remote package replacement is especially dangerous because it can silently alter future executions.
The documentation does not clearly warn that prompts, reference images, and API keys are sent to an external third-party service. This is a privacy and secret-handling issue because users may provide sensitive content or credentials without understanding the external transmission and retention implications.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Or register via API directly:
curl -X POST https://www.aoment.com/api/skills/aoment-visuals/register-agent \
-H "Content-Type: application/json" \
-d '{"nickname": "MyBot"}'
The module docstring and CLI description are entirely in Chinese, including the user-facing purpose and authentication guidance. This imposes a specific language on users without opt-in, and there is no indication that the skill is intentionally limited to a Chinese-speaking or region-specific context.
The natural-language description is entirely in Chinese and presents the tool as a registration utility without indicating that the language is fixed or optional. Under the language/locale policy, forcing a specific language without user opt-in is a policy concern unless the locale restriction is clearly justified.
The script performs an outbound POST request to a remote service and allows the destination to be overridden via --api-base, but it does not validate or constrain the target host. In an agent context, this can be abused to send the provided nickname and receive arbitrary JSON from an attacker-controlled endpoint, enabling unintended data disclosure and trust of unverified remote responses.
url = f"{api_base}{REGISTER_ENDPOINT}"
payload = {"nickname": nickname}
resp = requests.post(url, json=payload, timeout=TIMEOUT)
resp.raise_for_status()
return resp.json()
The natural-language description and all user-facing help strings in this file are written only in Chinese, with no indication that users can choose another language or locale. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"imageSize": args.image_size,
}
response = requests.post(
url, json=payload, headers=_auth_headers(args.api_key), timeout=IMAGE_TIMEOUT
)
result = response.json()
This code sends user-supplied prompts and, in other paths, image data to a remote service, but the script does not provide a runtime notice, confirmation, or explicit warning that these inputs are transmitted off-system. The top docstring describes the service but does not clearly disclose the privacy-impacting behavior of uploading user content to an external endpoint.
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
headers = _auth_headers(args.api_key)
if files:
response = requests.post(
url, data=data, files=files, headers=headers, timeout=IMAGE_TIMEOUT
)
else:
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
url, data=data, files=files, headers=headers, timeout=IMAGE_TIMEOUT
)
else:
response = requests.post(
url, data=data, headers=headers, timeout=IMAGE_TIMEOUT
)
The code issues requests.get against arbitrary user-controlled reference_image URLs before uploading the bytes onward. This is a classic SSRF-style pattern: if the skill runs in a privileged network environment, an attacker could make it reach internal services, cloud metadata endpoints, or other restricted resources and then exfiltrate the responses.
In video generation, the skill fetches arbitrary user-supplied URLs and then forwards the retrieved content to the remote API as uploaded files. This creates a server-side request behavior on the host running the skill and can be abused to access internal-only or otherwise unintended network resources, then exfiltrate the fetched content to the external service.
headers = _auth_headers(args.api_key)
if files_list:
response = requests.post(
url, data=data, files=files_list, headers=headers, timeout=VIDEO_TIMEOUT
)
else:
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
url, data=data, files=files_list, headers=headers, timeout=VIDEO_TIMEOUT
)
else:
response = requests.post(
url, data=data, headers=headers, timeout=VIDEO_TIMEOUT
)
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.
Powered By Longfor.AuraSpace
LICENSE:
This skill and its related documentation are protected by license terms. Unless otherwise permitted by applicable law or expressly authorized in writing, no individual or entity may use the skill beyond the scope expressly granted by the license. Without permission, the skill may not be copied, distributed, resold, reverse engineered, or used for any purpose outside the authorized scope. The skill is provided "as is", without warranties of any kind, express or implied, including but not limited to warranties of merchantability, fitness for a particular purpose, and non-infringement. To the maximum extent permitted by law, the licensor shall not be liable for any loss resulting from the use or inability to use this skill.
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.
Powered By Longfor.AuraSpace
LICENSE:
This skill and its related documentation are protected by license terms. Unless otherwise permitted by applicable law or expressly authorized in writing, no individual or entity may use the skill beyond the scope expressly granted by the license. Without permission, the skill may not be copied, distributed, resold, reverse engineered, or used for any purpose outside the authorized scope. The skill is provided "as is", without warranties of any kind, express or implied, including but not limited to warranties of merchantability, fitness for a particular purpose, and non-infringement. To the maximum extent permitted by law, the licensor shall not be liable for any loss resulting from the use or inability to use this skill.
This Python code sends the provided nickname to a remote HTTPS endpoint via an HTTP POST request. While the script purpose implies registration, there is no explicit disclosure in a prompt, print statement, or comment near execution that user input will be transmitted to an external service.
The script accepts an Agent API Key and places it into an Authorization header for outbound requests, but there is no explicit warning or note about the sensitivity of this credential beyond stating it is required for authentication. For a code file, sensitive credential use should have some visible disclosure, comment, or user-facing explanation.
The manifest says this skill provides text-to-image, image-to-image, and video generation with API key registration support. In addition to those generation operations, the code performs a remote version check and exits if the local skill is outdated, which is a separate control/update-enforcement behavior not reflected in the stated description.
No suspicious patterns detected.