Back to skill

Security audit

Mistral Agents Orchestrator

Security checks for vulnerabilities and agentic risk

Overview

The skill advertises a Mistral-only orchestrator but the code also uses other paid AI services and stores child-related story data with too little disclosure or control.

Review before installing. Only deploy this behind authentication, quotas, and clear retention controls, and disclose or remove the ElevenLabs, Tavily, Gemini, database, and prompt-cache behavior. Avoid running it in an environment where unrelated provider keys are present unless those integrations are intentionally enabled.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (2)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/orchestrator.py:236
Finding

Unauthenticated endpoints can consume privileged third-party services and persistent storage

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:10
Finding

Declared permissions omit third-party credentials, outbound services, and sensitive data flows

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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (21)

Tainted flow: 'ELEVENLABS_API_KEY' from os.environ.get (line 18, credential/environment) → httpx.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/orchestrator.py (reported line 101)May include surrounding context.

python
if not ELEVENLABS_API_KEY:
        return {"error": "ELEVENLABS_API_KEY not set"}
    try:
        r = httpx.post(f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
            headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
            json={"text": text, "model_id": "eleven_multilingual_v2",
                  "voice_settings": {"stability": 0.6, "similarity_boost": 0.8}},

Tainted flow: 'ELEVENLABS_API_KEY' from os.environ.get (line 18, credential/environment) → httpx.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/orchestrator.py (reported line 116)May include surrounding context.

python
if not ELEVENLABS_API_KEY:
        return {"error": "ELEVENLABS_API_KEY not set"}
    try:
        r = httpx.post("https://api.elevenlabs.io/v1/sound-generation",
            headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
            json={"text": prompt, "duration_seconds": min(duration_seconds, 22)},
            timeout=30)

Tainted flow: 'ELEVENLABS_API_KEY' from os.environ.get (line 18, credential/environment) → httpx.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/orchestrator.py (reported line 130)May include surrounding context.

python
if not ELEVENLABS_API_KEY:
        return {"error": "ELEVENLABS_API_KEY not set"}
    try:
        r = httpx.post("https://api.elevenlabs.io/v1/sound-generation",
            headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
            json={"text": f"Gentle lullaby music: {prompt}", "duration_seconds": min(duration_seconds, 22)},
            timeout=30)

Tainted flow: 'TAVILY_API_KEY' from os.environ.get (line 19, credential/environment) → httpx.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/orchestrator.py (reported line 144)May include surrounding context.

python
if not TAVILY_API_KEY:
        return {"error": "TAVILY_API_KEY not set"}
    try:
        r = httpx.post("https://api.tavily.com/search",
            json={"api_key": TAVILY_API_KEY, "query": query, "max_results": 3}, timeout=15)
        if r.status_code == 200:
            return {"results": [{"title": x.get("title",""), "snippet": x.get("content","")[:200]} for x in r.json().get("results",[])]}

Tainted flow: 'gemini_key' from os.environ.get (line 370, credential/environment) → httpx.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/orchestrator.py (reported line 408)May include surrounding context.

python
for i in range(min(len(scenes), 4)):
            art_prompt = img_prompts.get(f"scene_{i}", f"Dreamy watercolor: {scenes[i][:100]}")
            try:
                resp = hx.post(
                    f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent?key={gemini_key}",
                    json={"contents": [{"parts": [{"text": art_prompt}]}],
                          "generationConfig": {"responseModalities": ["TEXT", "IMAGE"]}},

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared purpose and required secret mention only Mistral orchestration, but the analyzed behavior reportedly includes additional third-party services, extra API keys, persistence, caching, and a domain-specific story pipeline. This mismatch is dangerous because it can hide the true attack surface, cause operators to grant insufficiently reviewed secrets and network access, and enable undisclosed data flows to external services or storage.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

A skill described as Mistral orchestration also loads unrelated ElevenLabs and Tavily credentials, enabling access to additional external services not justified by the stated purpose. Hidden credential dependencies enlarge blast radius, increase supply-chain trust requirements, and can enable unexpected data sharing and billing abuse.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill metadata presents this as a Mistral multi-agent orchestration capability, but the code also implements audio generation, web search, and later image-generation support. This scope expansion increases attack surface and can surprise deployers by causing external data transfers and costs beyond what the manifest implies.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code conditionally invokes Gemini to generate illustrations, which is materially outside the declared Mistral orchestration scope. This creates an undisclosed external dependency and transmits derived story content to Google, increasing privacy, cost, and policy risk without clear consent.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares environment and outbound network requirements in metadata but does not define an explicit tool scope such as permissions or allowed-tools. That creates an authorization gap where consumers may not clearly understand or constrain what the skill is allowed to access, increasing the chance of overbroad execution in hosts that rely on manifest-level scoping.

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/orchestrator.py (reported line 101)May include surrounding context.

python
if not ELEVENLABS_API_KEY:
        return {"error": "ELEVENLABS_API_KEY not set"}
    try:
        r = httpx.post(f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
            headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
            json={"text": text, "model_id": "eleven_multilingual_v2",
                  "voice_settings": {"stability": 0.6, "similarity_boost": 0.8}},

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/orchestrator.py (reported line 116)May include surrounding context.

python
if not ELEVENLABS_API_KEY:
        return {"error": "ELEVENLABS_API_KEY not set"}
    try:
        r = httpx.post(f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
            headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
            json={"text": text, "model_id": "eleven_multilingual_v2",
                  "voice_settings": {"stability": 0.6, "similarity_boost": 0.8}},

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/orchestrator.py (reported line 130)May include surrounding context.

python
if not ELEVENLABS_API_KEY:
        return {"error": "ELEVENLABS_API_KEY not set"}
    try:
        r = httpx.post(f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
            headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
            json={"text": text, "model_id": "eleven_multilingual_v2",
                  "voice_settings": {"stability": 0.6, "similarity_boost": 0.8}},

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/orchestrator.py (reported line 116)May include surrounding context.

python
if not ELEVENLABS_API_KEY:
        return {"error": "ELEVENLABS_API_KEY not set"}
    try:
        r = httpx.post("https://api.elevenlabs.io/v1/sound-generation",
            headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
            json={"text": prompt, "duration_seconds": min(duration_seconds, 22)},
            timeout=30)

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/orchestrator.py (reported line 130)May include surrounding context.

python
if not ELEVENLABS_API_KEY:
        return {"error": "ELEVENLABS_API_KEY not set"}
    try:
        r = httpx.post("https://api.elevenlabs.io/v1/sound-generation",
            headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
            json={"text": prompt, "duration_seconds": min(duration_seconds, 22)},
            timeout=30)

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/orchestrator.py (reported line 144)May include surrounding context.

python
if not ELEVENLABS_API_KEY:
        return {"error": "ELEVENLABS_API_KEY not set"}
    try:
        r = httpx.post("https://api.elevenlabs.io/v1/sound-generation",
            headers={"xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json"},
            json={"text": prompt, "duration_seconds": min(duration_seconds, 22)},
            timeout=30)

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/orchestrator.py (reported line 144)May include surrounding context.

python
if not TAVILY_API_KEY:
        return {"error": "TAVILY_API_KEY not set"}
    try:
        r = httpx.post("https://api.tavily.com/search",
            json={"api_key": TAVILY_API_KEY, "query": query, "max_results": 3}, timeout=15)
        if r.status_code == 200:
            return {"results": [{"title": x.get("title",""), "snippet": x.get("content","")[:200]} for x in r.json().get("results",[])]}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

User prompts and child identifiers are sent to Mistral and ElevenLabs during planning, story generation, and narration without any disclosure or consent handling in this file. Because the content may involve minors and personalized details, undisclosed third-party transmission is more sensitive than in a generic text-processing skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Scene-derived content and illustration prompts are sent to Gemini for image generation without user-facing notice. Even though the prompts are model-generated, they still encode story content tied to a child-focused workflow and therefore represent undisclosed external sharing.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The endpoint stores generated stories, child names, language, and cached media artifacts in a database, but persistence is not disclosed in the skill description. Undisclosed storage of child-associated content creates privacy, retention, and compliance risk, especially in a bedtime-story context involving minors.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The docstring states 'Direct chat with any Mistral Agent via Conversations API,' which implies arbitrary Mistral agent access. In practice, the code only accepts agent names found in the hardcoded AGENTS mapping and rejects all others as unknown.

Content

No source excerpt is available for this finding.