T09 · Insecure Skill Coding Practices
- Location
account-management/SKILL.md:48- Finding
Authentication Tokens and API Keys Exposed Through Console Output
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This ModelsLab skill set is openly about API automation, but it includes agent-driven account, API-key, team, and billing flows that can handle payment cards and spend money with too little warning or control.
Install only the specific ModelsLab skills you need, not the full bundle. Do not paste real payment-card numbers, passwords, bearer tokens, or production API keys into agent conversations or logs. Prefer hosted Stripe Checkout/payment links, short-lived least-privilege tokens, spending limits, sandbox accounts, and explicit human confirmation before billing, team, password, or API-key changes. If using webhooks, add real signature/shared-secret validation and match callbacks to server-side request records.
account-management/SKILL.md:48Authentication Tokens and API Keys Exposed Through Console Output
billing-subscriptions/SKILL.md:83Raw Payment-Card Data Is Routed Through Agent Context
webhooks/SKILL.md:50Webhook Handlers Trust Unauthenticated Callback Payloads
sdk-usage/SKILL.md:20Mutable and Unpinned Third-Party Installation Commands
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- Sign up or log in to ModelsLab programmatically
- Create and manage API keys for generation endpoints
- Update user profile, password, or social links
- Manage access tokens (list, revoke, switch team accounts)
- Invite, update, or remove team members
- Build agent workflows that need account bootstrapping
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def refresh_token(token, token_expiry="1_month"):
"""Refresh/rotate the current access token.
The old token is revoked and a new one is issued.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def refresh_token(token, token_expiry="1_month"):
"""Refresh/rotate the current access token.
The old token is revoked and a new one is issued.
The headless payment example submits raw card details to Stripe without a prominent warning that the code path handles highly sensitive payment data and may trigger strict security and compliance obligations. In an agent workflow, this creates a serious risk of accidental collection, logging, retention, or misuse of cardholder data.
The skill's purpose is to send chat completions to an external LLM endpoint, which by design can leak user prompts, system instructions, and conversation context to a third party. In an agent setting, this is more dangerous because users may pass operational context, hidden instructions, or tool outputs that were not intended to leave the environment.
# ModelsLab Chat/LLM Generation
Send chat completions to 60+ LLM models through a single OpenAI-compatible endpoint.
## When to Use This Skill
The skill instructs users to send prompts, image URLs, API keys, and webhook endpoints to a third-party API without a prominent disclosure that this data leaves the local environment. This creates a real data-handling and privacy risk because users may unknowingly submit sensitive content or infrastructure details to an external provider.
This duplicate finding identifies the same third-party transmission in the text-to-3D function. The main concern is user unawareness that prompts and credentials are leaving the environment and being processed by an external vendor.
Returns:
URL of the 3D model file
"""
response = requests.post(
"https://modelslab.com/api/v6/3d/text_to_3d",
json={
"key": api_key,
This duplicate finding identifies the same third-party transmission in the text-to-3D function. The main concern is user unawareness that prompts and credentials are leaving the environment and being processed by an external vendor.
Returns:
URL of the 3D model file
"""
response = requests.post(
"https://modelslab.com/api/v6/3d/text_to_3d",
json={
"key": api_key,
The polling request sends the API key and request ID to the provider's fetch endpoint. This is lower impact than content submission, but it still represents credential and job-metadata transmission to a third party and should be disclosed as part of the service interaction model.
start_time = time.time()
while time.time() - start_time < timeout:
fetch = requests.post(
f"https://modelslab.com/api/v6/3d/fetch/{request_id}",
json={"key": api_key}
)
The image-to-3D section encourages supplying image URLs but does not warn that the URL and the image content it references will be accessed and processed by an external service. This can expose private images, signed URLs, internal object locations, or sensitive product/media assets to a third party without explicit user awareness.
This duplicate finding covers the same image-to-3D external transmission. The security relevance comes from third-party access to supplied asset locations and content, especially where users might pass private media URLs.
Returns:
URL of the generated 3D model
"""
response = requests.post(
"https://modelslab.com/api/v6/3d/image_to_3d",
json={
"key": api_key,
This duplicate finding covers the same image-to-3D external transmission. The security relevance comes from third-party access to supplied asset locations and content, especially where users might pass private media URLs.
Returns:
URL of the generated 3D model
"""
response = requests.post(
"https://modelslab.com/api/v6/3d/image_to_3d",
json={
"key": api_key,
This duplicate finding covers the webhook submission path, where callback endpoint details are disclosed to an external provider. The risk increases if webhook endpoints are internal, unauthenticated, or reveal environment structure.
def generate_3d_with_webhook(prompt, api_key, webhook_url, track_id):
"""Generate 3D model and receive results via webhook."""
response = requests.post(
"https://modelslab.com/api/v6/3d/text_to_3d",
json={
"key": api_key,
This duplicate finding covers the webhook submission path, where callback endpoint details are disclosed to an external provider. The risk increases if webhook endpoints are internal, unauthenticated, or reveal environment structure.
def generate_3d_with_webhook(prompt, api_key, webhook_url, track_id):
"""Generate 3D model and receive results via webhook."""
response = requests.post(
"https://modelslab.com/api/v6/3d/text_to_3d",
json={
"key": api_key,
This duplicate finding covers batch submission to the external API. Repeated transmission of prompts and webhook metadata broadens the privacy footprint and can unintentionally expose multiple sensitive assets or project details at once.
# Submit all requests
for i, prompt in enumerate(prompts):
response = requests.post(
"https://modelslab.com/api/v6/3d/text_to_3d",
json={
"key": api_key,
This duplicate finding covers batch submission to the external API. Repeated transmission of prompts and webhook metadata broadens the privacy footprint and can unintentionally expose multiple sensitive assets or project details at once.
# Submit all requests
for i, prompt in enumerate(prompts):
response = requests.post(
"https://modelslab.com/api/v6/3d/text_to_3d",
json={
"key": api_key,
The README instructs users to run npx skills without pinning a specific package version, which can cause execution of whatever package version is currently resolved from the registry at install time. That creates a supply-chain risk where a compromised upstream release or unexpected breaking change could be executed automatically in a privileged local development context.
This example again promotes npx skills with no version pinning, so users may fetch and execute an unreviewed latest package at runtime. In agent/tooling ecosystems, this increases exposure to malicious package publication, account takeover of the package owner, or accidental unsafe updates.
An unpinned npx skills command in documentation normalizes downloading and executing mutable remote code. Because these commands are intended to install agent skills, compromise could affect local credentials, source code, or downstream agent behavior.
The README advertises account management, billing, subscription, payment, wallet, and API key operations as agent skills without any warning about financial or account-impacting consequences. In an agent context, users may grant these skills broad autonomy, leading to unauthorized spending, account changes, key creation/rotation, or privilege expansion through routine prompting mistakes or prompt injection.
The installation section repeats an unpinned npx skills command, preserving the same supply-chain execution risk. Users commonly copy-paste README installation commands, so unsafe examples materially increase the chance of exploitation.
This command installs specific skills but still relies on an unpinned npx skills bootstrap, meaning the primary executable remains mutable. The narrower skill selection does not reduce the core risk of fetching arbitrary latest code for execution.
Although this example targets specific agents, it still executes npx skills without version control. In multi-agent environments, compromise could propagate unsafe skills or altered tooling into several development environments at once.
The getting-started section instructs users to install all skills through an unpinned npx skills command, maximizing blast radius because it combines mutable code execution with broad skill installation. If the package or dependency chain were compromised, users could unknowingly onboard multiple unsafe capabilities at once.
The example prompts explicitly encourage actions like creating accounts/API keys and funding wallets, but provide no cautionary language or approval boundary. Because users often copy example prompts directly into autonomous agents, this can normalize high-risk actions without informed consent, increasing the likelihood of accidental purchases, credential sprawl, or unauthorized account creation.