T09 · Insecure Skill Coding Practices
- Location
templates/api-route-openai.ts.template:21- Finding
Unauthenticated Chat Endpoints Permit Abuse of Provider-Funded Inference
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a coherent OpenUI app-building purpose, but needs Review because its generated chat servers can expose your paid AI provider key to unauthenticated use unless you add access controls.
Before installing or using this skill for anything beyond local development, pin the CLI and package versions, review the generated backend before deployment, add real authentication and authorization to /api/chat, enforce rate limits, request-size limits, message-count/content limits, and provider spending caps, and make sure users understand that chat content and the generated system prompt are sent to the configured model provider.
templates/api-route-openai.ts.template:21Unauthenticated Chat Endpoints Permit Abuse of Provider-Funded Inference
templates/handler-go.go.template:88Unbounded Request Bodies and Message Arrays Enable Resource and Cost Exhaustion
SKILL.md:102Unpinned NPM and NPX Commands Execute Remotely Resolved Package Code
Referenced artifact was not completely inspected
2. Read `references/component-patterns.md` for examples matching the use case
Referenced artifact was not completely inspected
2. Read `references/component-patterns.md` for examples matching the use case
Referenced artifact was not completely inspected
Template: templates/api-route-anthropic.ts.template
Referenced artifact was not completely inspected
Template: templates/api-route-langchain.ts.template
Referenced artifact was not completely inspected
Run `scripts/validate.sh` (or `.ps1`) for automated checks.
Referenced artifact was not completely inspected
**Read `references/openui-lang-spec.md` for the full specification.**
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
get("messages", [])
api_messages = [{"role": "system", "content": system_prompt}]
for msg in messages:
api_messages.append({
"role": msg.get("role", "user"),
"content": msg.get("content", ""),
})
async def generate():
completion_id = f"chatcmpl-{uuid.uuid4().hex[:12]}"
stream = await client.chat.completions.create(
model=os.getenv("OPENAI_MODEL", "gpt-5.5"),
messages=api_messages,
stream=True,
)
async for chunk in stream:
delta = chunk.choices[0].delta if chunk.choices else None
finish_reason = chunk.choices[0].finish_reason if chunk.choices else None
if delta and delta.content:
line = json.dumps({
"id": completion_id,
"object": "chat.completion.chunk",
"choices": [{
"index": 0,
"delta": {"content": delta.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# -------------------------------------------------------------------------
# gem "rails", "~> 8.1"
# # Net::HTTP is in the standard library — no extra HTTP-client gem required.
# # Optional: load OPENAI_API_KEY etc. from a .env file in development.
# gem "dotenv-rails", groups: [:development, :test]
#
# Then: bundle install
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# -------------------------------------------------------------------------
# gem "rails", "~> 8.1"
# # Net::HTTP is in the standard library — no extra HTTP-client gem required.
# # Optional: load OPENAI_API_KEY etc. from a .env file in development.
# gem "dotenv-rails", groups: [:development, :test]
#
# Then: bundle install
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# -------------------------------------------------------------------------
# gem "rails", "~> 8.1"
# # Net::HTTP is in the standard library — no extra HTTP-client gem required.
# # Optional: load OPENAI_API_KEY etc. from a .env file in development.
# gem "dotenv-rails", groups: [:development, :test]
#
# Then: bundle install
The skill instructs use of npx @openuidev/cli without a pinned version, which causes execution of whatever package version is latest at runtime. If the upstream package is compromised or a breaking/malicious release is published, users may execute attacker-controlled code during scaffolding or prompt generation.
This command uses unpinned npx @openuidev/cli, so the exact code executed depends on the current registry state rather than a reviewed artifact. In an agent skill context, that is risky because the instruction encourages direct execution of remote package code as part of the workflow.
The skill tells users to run npx @openuidev/cli generate ... without pinning the package version, enabling arbitrary upstream changes to alter or compromise local execution. Because npx fetches and runs code, this is effectively a remote code execution trust boundary issue, even if it is common developer practice.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
|----------|-------------------|------------------|
| Gemini (Google) | `https://generativelanguage.googleapis.com/v1beta/openai/` | `gemini-2.5-flash` |
| OpenRouter | `https://openrouter.ai/api/v1` | `openai/gpt-4o` |
| xAI (Grok) | `https://api.x.ai/v1` | `grok-4` |
| DeepSeek | `https://api.deepseek.com` | `deepseek-chat` |
| Groq | `https://api.groq.com/openai/v1` | `llama-3.3-70b-versatile` |
| Mistral | `https://api.mistral.ai/v1` | `mistral-large-latest` |
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
| OpenRouter | `https://openrouter.ai/api/v1` | `openai/gpt-4o` |
| xAI (Grok) | `https://api.x.ai/v1` | `grok-4` |
| DeepSeek | `https://api.deepseek.com` | `deepseek-chat` |
| Groq | `https://api.groq.com/openai/v1` | `llama-3.3-70b-versatile` |
| Mistral | `https://api.mistral.ai/v1` | `mistral-large-latest` |
| Together | `https://api.together.ai/v1` | `meta-llama/Llama-3.3-70B-Instruct-Turbo` |
| Fireworks | `https://api.fireworks.ai/inference/v1` | `accounts/fireworks/models/llama-v3p3-70b-instruct` |
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
| xAI (Grok) | `https://api.x.ai/v1` | `grok-4` |
| DeepSeek | `https://api.deepseek.com` | `deepseek-chat` |
| Groq | `https://api.groq.com/openai/v1` | `llama-3.3-70b-versatile` |
| Mistral | `https://api.mistral.ai/v1` | `mistral-large-latest` |
| Together | `https://api.together.ai/v1` | `meta-llama/Llama-3.3-70B-Instruct-Turbo` |
| Fireworks | `https://api.fireworks.ai/inference/v1` | `accounts/fireworks/models/llama-v3p3-70b-instruct` |
| Ollama (local) | `http://localhost:11434/v1/` | `llama3.2` (any placeholder api key) |
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
| DeepSeek | `https://api.deepseek.com` | `deepseek-chat` |
| Groq | `https://api.groq.com/openai/v1` | `llama-3.3-70b-versatile` |
| Mistral | `https://api.mistral.ai/v1` | `mistral-large-latest` |
| Together | `https://api.together.ai/v1` | `meta-llama/Llama-3.3-70B-Instruct-Turbo` |
| Fireworks | `https://api.fireworks.ai/inference/v1` | `accounts/fireworks/models/llama-v3p3-70b-instruct` |
| Ollama (local) | `http://localhost:11434/v1/` | `llama3.2` (any placeholder api key) |
| LM Studio (local) | `http://localhost:1234/v1` | `mistral-7b-instruct-v0.3` (any placeholder api key) |
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
| Groq | `https://api.groq.com/openai/v1` | `llama-3.3-70b-versatile` |
| Mistral | `https://api.mistral.ai/v1` | `mistral-large-latest` |
| Together | `https://api.together.ai/v1` | `meta-llama/Llama-3.3-70B-Instruct-Turbo` |
| Fireworks | `https://api.fireworks.ai/inference/v1` | `accounts/fireworks/models/llama-v3p3-70b-instruct` |
| Ollama (local) | `http://localhost:11434/v1/` | `llama3.2` (any placeholder api key) |
| LM Studio (local) | `http://localhost:1234/v1` | `mistral-7b-instruct-v0.3` (any placeholder api key) |
This example again recommends executing an unpinned package via npx, making builds non-reproducible and exposing users to supply-chain compromise. In a skill that automates scaffolding and code generation, this increases the chance of silently propagating malicious outputs into a project.
The unpinned npx invocation for JSON schema generation has the same supply-chain and remote execution risk as the other occurrences. A malicious or compromised release could run arbitrary code on the developer machine and alter generated artifacts or exfiltrate local data.
This markdown file includes a Go backend example that makes direct HTTP calls to the OpenAI API and forwards chat contents, but the surrounding documentation does not explicitly warn readers that user-provided message data will be sent to an external provider. For markdown files, SQP-2 applies when the skill description omits warnings about behaviors affecting user data or privacy.
The document explains that system-prompt.txt is generated and injected server-side, but it does not clearly warn that this prompt content is included in requests to external LLM APIs alongside user messages. That omission matters because the prompt may contain proprietary component definitions or internal rules, which is a privacy and data-handling concern under the markdown-file criteria for SQP-2.
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.
# ── Check 10: CORS headers ──────────────────────────────────────────────────
# Only relevant when backend and frontend appear to be on different ports/origins
cors_hit=$(sgrep -rlE "(Access-Control-Allow-Origin|cors|CORS)" --include="*.ts" --include="*.js" --include="*.py" --include="*.go" . \
| grep -v node_modules | head -n1)
# Check if there's a separate backend config suggesting cross-origin setup
This route forwards the full messages array, along with the system prompt, to an external OpenAI service. While the network call is evident in code, there is no confirmation prompt, user-facing log, or inline disclosure indicating that user-provided content will be transmitted off-system.
The route sends modelMessages, derived from the request body, to OpenAI via streamText. While this network call is central to the route's function, the file contains no user-facing warning, confirmation, or disclosure that submitted content will be sent to a third-party model provider.
Detected: suspicious.exposed_secret_literal, suspicious.prompt_injection_instructions