Back to skill

Security audit

Civil Judgment Taiwan Vectorstore

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly purpose-aligned, but it deserves review because it can send full judgment text and identifying metadata to configurable HTTP services and can ingest/mislabel out-of-scope files.

Install only if you control the Ollama and Qdrant endpoints, preferably localhost or authenticated HTTPS. Check OLLAMA_URL and QDRANT_URL before running, use a dedicated run folder, expect persistent Qdrant collections plus local ingest_report.md, ingest_manifest.jsonl, and possibly issues.jsonl, and avoid mixed FJUD/FINT inputs unless you accept the known metadata mislabeling.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ingest.py:869
Finding

Configurable plaintext endpoints can expose judgment records and party information

Content
View full analysis
List[List[float]]: """Embed texts via Ollama /api/embeddings. Ollama endpoint: http://host:11434 """ url = ollama.rstrip("/") + "/api/embeddings" vecs: List[List[float]] = [] for t in texts: r = requests.post(url, json={"model": model, "prompt": t}, timeout=timeout) r.raise_for_status() data = r.json() emb = data.get("embedding") if not isinstance(emb, list): raise RuntimeError(f"Unexpected Ollama response: {data}") vecs.append(emb) return vecs ``` `scripts/ingest.py:899-908`: ```python def upsert_batched(client: QdrantClient, collection: str, points: List[qm.PointStruct], *, batch_size: int = 64) -> int: """Upsert points in batches to avoid Qdrant request payload size limits (default 32MB).""" if not points: return 0 total = 0 for i in range(0, len(points), batch_size): batch = points[i : i + batch_size] client.upsert(collection_name=collection, points=batch) total += len(batch) return total ``` `scripts/ingest.py:964-965`: ```python ap.add_argument("--ollama", default=os.environ.get("OLLAMA_URL", "http://localhost:11434")) ap.add_argument("--qdrant", default=os.environ.get("QDRANT_URL", "http://localhost:6333")) ``` Representative sensitive Qdrant payload from `scripts/ingest.py:1057-1078`: ```python doc_payload: Dict[str, Any] = { "point_id": doc_id, "source_run": source_run, "system": "FJUD", "title": title, "court": meta.get("court"), "court ...[truncated 4495 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
README.md:33
Finding

Setup instructions install mutable, unpinned third-party dependencies

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

A documented purpose/behavior mismatch is security-relevant because users may authorize execution believing the skill only ingests local HTML/PDF judgments, while the underlying implementation reportedly operates on an existing Qdrant collection and may delete/recreate collections via a rebuild path. Hidden destructive or materially different behavior undermines informed consent and can lead to data loss or unintended processing of already-ingested data.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 9)May include surrounding context.

md
PDF** files) into Qdrant. All parsing, chunking, and embedding logic lives in `scripts/ingest.py` — your job is to **run the script**, not to reimplement the p

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 80)May include surrounding context.

md
PDF** files) into Qdrant. All parsing, chunking, and embedding logic lives in `scripts/ingest.py` — your job is to **run the script**, not to reimplement the p

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 153)May include surrounding context.

md
PDF** files) into Qdrant. All parsing, chunking, and embedding logic lives in `scripts/ingest.py` — your job is to **run the script**, not to reimplement the p

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 156)May include surrounding context.

md
PDF** files) into Qdrant. All parsing, chunking, and embedding logic lives in `scripts/ingest.py` — your job is to **run the script**, not to reimplement the p

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 170)May include surrounding context.

md
PDF** files) into Qdrant. All parsing, chunking, and embedding logic lives in `scripts/ingest.py` — your job is to **run the script**, not to reimplement the p

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 197)May include surrounding context.

md
PDF** files) into Qdrant. All parsing, chunking, and embedding logic lives in `scripts/ingest.py` — your job is to **run the script**, not to reimplement the p

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill instructs the agent to access environment variables, read user-specified files, write reports/manifests, and contact local network services, yet it declares no explicit tool scope or permissions. This creates an authorization ambiguity where an agent may be allowed to perform broader actions than the user expects, increasing the risk of unintended file access or network operations.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation simultaneously says 'Taiwan civil court judgments only' and admits that FINT files are still ingested. That contradiction makes operator expectations unsafe and can cause out-of-scope legal documents to be embedded and stored despite stated restrictions, weakening governance and traceability controls.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill omits an explicit warning that it writes ingest_report.md and ingest_manifest.jsonl into the provided run folder. While lower severity than network disclosure, silent writes can still surprise users, alter working directories used by other tooling, or leave metadata artifacts in locations they did not expect.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · SKILL.md (reported line 83)May include surrounding context.

md
- **DO NOT** write your own HTML parsing, chunking, or embedding code. `ingest.py` handles all of this.
- **DO NOT** modify parsing/chunking logic casually. Only change heading detection or chunk fallback when the user explicitly asks to improve PDF/OCR robustness, and validate on a small sample before re-running a large batch.
- **DO NOT** call Qdrant or Ollama APIs directly. The script does this.
- **DO NOT** use `verify=False` or skip SSL verification for any HTTP request.
- **DO NOT** modify or delete files under `archive/`. Raw HTML is immutable source of truth.
- **DO NOT** change chunking defaults (`--max-chars`, `--overlap-chars`) unless the user explicitly asks.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill claims exclusivity to Taiwan civil judgments but later states that FINT files will also be ingested, merely mislabeled as FJUD. This is an input-validation and data-integrity issue: out-of-scope documents can enter the pipeline and be indexed under incorrect metadata, which can contaminate downstream retrieval, analytics, or compliance boundaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

This markdown file documents that 609 reasoning points are missing doc_url and that 201 source documents have no URL, but it does not include an explicit user warning about the resulting traceability gap or caution downstream users against relying on complete source-link coverage. Because doc_url is part of the documented traceability and retrieval contract, the omission weakens disclosure about data integrity impacts.

Content

No source excerpt is available for this finding.

External Transmission

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

python
def ollama_embed(text: str, *, ollama: str, model: str, timeout: int = 60) -> List[float]:
    url = ollama.rstrip("/") + "/api/embeddings"
    r = requests.post(url, json={"model": model, "prompt": text}, timeout=timeout)
    r.raise_for_status()
    data = r.json()
    emb = data.get("embedding")

External Transmission

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

python
def ollama_embed(text: str, *, ollama: str, model: str, timeout: int = 60) -> List[float]:
    url = ollama.rstrip("/") + "/api/embeddings"
    r = requests.post(url, json={"model": model, "prompt": text}, timeout=timeout)
    r.raise_for_status()
    data = r.json()
    emb = data.get("embedding")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code sends document text to the Ollama embeddings HTTP endpoint via requests.post, which transmits potentially sensitive judgment content off-process or off-host depending on configuration. Although the module docstring describes embedding and Qdrant ingestion, there is no inline user-facing warning, confirmation, or disclosure near the network transmission itself about sending document contents to external services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The script uploads structured payloads to Qdrant, and those payloads include local paths, case metadata, party information, and for chunk records the full chunk text. This is a safety-relevant data write over the network, but the code does not provide a clear inline warning or confirmation that these contents will be stored in the configured Qdrant service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The file contains natural-language descriptions of extraction rules keyed to Chinese legal connectives and court-specific Chinese terminology, such as 涵攝推理, 是故/因此/準此/從而, and 爭點. Because SQP-3 applies to all file types, this can be flagged as a locale/language policy concern when the skill behavior is effectively tied to a specific language/locale without an explicit justification or opt-in in the file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill omits an explicit warning that it writes ingest_report.md and ingest_manifest.jsonl into the provided run folder. While lower severity than network disclosure, silent writes can still surprise users, alter working directories used by other tooling, or leave metadata artifacts in locations they did not expect.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.