Back to skill

Security audit

Morgana Mordred Security Sandbox

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly behaves like a local Ollama-based security classifier, but users should review it because prompts are sent to local AI endpoints by default and the install steps use unpinned dependencies and models.

Install only if you are comfortable running Ollama locally and sending analyzed prompts, which may contain incident details or secrets, to that local service. Prefer removing the unused pip dependency, pinning package and model versions or digests, and treating Gemma as enabled by default unless the code is changed.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (1)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:44
Finding

Unpinned and Unnecessary Third-Party Dependencies

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 44–51; duplicated in kit.md, lines 44–51
Vulnerability Type: Unverified third-party package and mutable model installation
Risk Level: Medium

Vulnerable Code

bash
# Install dependencies
pip install ollama

# Start Ollama server
ollama serve

# Pull embedding model
ollama pull nomic-embed-text
ollama pull gemma3:4b

Technical Analysis

The installation instructions fetch an unpinned Python package and mutable model artifacts without version constraints, checksums, signatures, or digest verification. Consequently, the effective installed components may change after the Skill has been audited.

The ollama Python package is also unnecessary for the current implementation: src/mordred_v4.1.py does not import it and instead accesses the local Ollama service through urllib.request. Installing an unused package needlessly expands the supply-chain attack surface.

This finding does not establish that the named package or models are currently malicious. The risk arises from allowing future or compromised upstream artifacts to be installed without integrity controls.

Attack Path

  1. An attacker compromises an upstream package or model distribution channel, or a mutable artifact is replaced with an unsafe release.
  2. A user follows the documented installation commands.
  3. pip retrieves the current unpinned package, while Ollama retrieves the current model artifacts.
  4. Malicious package installation behavior could execute under the installing user's privileges, or a manipulated model could produce attacker-influenced classifications.
  5. Any resulting access is bounded by the privileges of the user or environment performing the installation and running the affected component.

Impact Assessment

A compromised Python dependency could execute code with the installing user's privileges, potentially affecting files, credentials, processes, and network resources accessible t ...[truncated 364 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove pip install ollama, because the current Python implementation does not use that package.
  2. Document installation of the Ollama runtime through an authenticated and verified official distribution channel.
  3. Pin every required dependency and model to an immutable version or digest.
  4. Verify checksums or cryptographic signatures before installation where the distribution mechanism supports them.
  5. Record approved artifact hashes in the repository and fail installation when verification does not succeed.
  6. Use a locked dependency manifest and automated dependency scanning if a Python client dependency is introduced later.
  7. Run model services with least privilege and restrict their filesystem and network access.
  8. Apply the same corrected instructions to kit.md, which duplicates the affected commands.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (8)

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module presents itself as a 'Security Sandbox', which implies isolation and privacy, but the implementation sends user-supplied text to local HTTP model endpoints for embedding and generation. That mismatch can mislead users into submitting sensitive content under a false assumption of confinement, creating a real data-handling and trust issue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

User-provided text is sent to the Ollama embeddings API without any explicit disclosure, consent, or classification of sensitive input. In a security-oriented tool, users may paste secrets, incident details, or proprietary data, so silent transmission to another service increases privacy and data exposure risk even if the service is localhost.

Content

No source excerpt is available for this finding.

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · src/mordred_v4.1.py (reported line 23)May include surrounding context.

python
"""Génère un embedding via Ollama."""
    try:
        payload = {"model": model, "prompt": text}
        req = urllib.request.Request(
            'http://localhost:11434/api/embeddings',
            data=json.dumps(payload).encode('utf-8'),
            headers={'Content-Type': 'application/json'}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The full question is forwarded to a generation API with no explicit user notice, which can expose sensitive prompts or operational details to another service. Because this tool is framed as security analysis, the context makes it more likely users will submit confidential or high-risk content, increasing the practical severity.

Content

No source excerpt is available for this finding.

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · src/mordred_v4.1.py (reported line 237)May include surrounding context.

python
# =============================================================================
def ask_gemma(question: str, model: str = "gemma3:4b") -> str:
    payload = {"model": model, "prompt": f"Morgana Security: {question}\nRisk? CRITICAL HIGH MEDIUM LOW. One line.", "stream": False, "options": {"num_predict": 30, "temperature": 0.1}}
    req = urllib.request.Request('http://localhost:11434/api/generate', data=json.dumps(payload).encode('utf-8'), headers={'Content-Type': 'application/json'})
    try:
        with urllib.request.urlopen(req, timeout=60) as resp:
            return json.load(resp).get('response', '').strip()

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
78% confidence
Finding

The multilingual section explicitly states 'Chinese emergency → GARDIEN' and 'French questions → Supported', which implies differing handling based on language. Because this markdown does not explain or justify the locale/language constraints, it may reflect a language policy decision without user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The file's human-facing strings and documentation are presented in French throughout, including the top-level description and usage/help text, without indicating language choice or opt-in. Under the language/locale policy, forcing a specific language in user-facing behavior can be a policy concern when no alternative or selection mechanism is offered.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
71% confidence
Finding

The comment and surrounding logic imply embeddings are cached and reused, but the returned field embedding_used checks text[:50] against the cache while the cache key is the full text. This makes the code's documented cache/use semantics inaccurate and can misreport whether an embedding was reused.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.