Back to skill

Security audit

Data Construction Skill

Security checks for vulnerabilities and agentic risk

Overview

This is a local dataset-construction skill with disclosed file reads and writes; the notable risks are ordinary data-handling robustness issues, not hidden or malicious behavior.

Install only for corpora you intend the agent to read and transform. Use a dedicated work directory, avoid pointing it at folders containing private or unrelated markdown, do not include the merge output as one of the merge inputs, and inspect validation and coverage JSON reports rather than relying only on command success.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/merge_jsonl.py:15
Finding

Input and Output Path Aliasing Can Silently Destroy JSONL Data

Content
View full analysis

Vulnerability Details

File Location: scripts/merge_jsonl.py, lines 15–23
Vulnerability Type: Unsafe file handling and destructive output aliasing
Risk Level: Medium

python
written = 0
with out.open('w', encoding='utf-8') as wf:
    for name in sorted(args.inputs):
        p = Path(name)
        if not p.exists() or not p.is_file():
            continue
        with p.open('r', encoding='utf-8') as rf:
            for line in rf:
                if line.strip():
                    wf.write(line.rstrip('\n') + '\n')
                    written += 1

Technical Analysis

The destination file is opened in w mode before the input files are opened. Opening an existing file in this mode immediately truncates it.

The script does not resolve and compare each input path against the output path. Consequently, the output can also appear in the input list through:

  • The same literal path
  • Equivalent relative and absolute paths
  • A symbolic link or another path resolving to the output
  • A wildcard that includes a previously generated merged file

If this occurs, the existing output is erased before the script attempts to read it. The affected input then contributes no records to the new merged file. Writing directly to the final destination also means an interruption can leave a partially written dataset.

Attack Path

  1. A user, automation job, or attacker who can influence command-line arguments includes the destination file among the inputs.
  2. The script resolves the output path and opens it with mode w.
  3. Existing contents of the destination are immediately truncated.
  4. The merge loop later opens the same file, or an alias of it, as an input.
  5. The input is empty or contains only data written earlier during the same merge.
  6. The script exits without reporting that source records were destroyed or omitted.
  7. Downstream validation or training may consume an incomple ...[truncated 510 chars]
Remediation
View remediation

Remediation Suggestions

  1. Resolve all input paths before opening the output and reject any input that resolves to the destination:
    python
    out = Path(args.output).resolve()
    inputs = [Path(name).resolve() for name in args.inputs]
    
    if out in inputs:
        raise ValueError("Output path must not also be an input path")
    
  2. Consider checking Path.samefile() for existing files to detect aliases and symbolic links.
  3. Write merged content to a securely created temporary file in the destination directory.
  4. Flush and synchronize the temporary file before atomically replacing the destination with Path.replace() or os.replace().
  5. Treat missing input files as errors unless skipping them is explicitly requested.
  6. Report the number of input files and records read from each file so unexpected omissions are visible.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/validate_qa_jsonl.py:113
Finding

Dataset Validator Exits Successfully When Blocking Validation Errors Are Present

Content
View full analysis

Vulnerability Details

File Location: scripts/validate_qa_jsonl.py, lines 113–229
Vulnerability Type: Fail-open validation and unreliable process status
Risk Level: Medium

python
with inp.open('r', encoding='utf-8') as f:
    for line_no, line in enumerate(f, start=1):
        line = line.strip()
        if not line:
            continue
        total += 1
        try:
            obj = json.loads(line)
        except Exception:
            malformed += 1
            issues.append({'line': line_no, 'issue': 'malformed_json'})
            continue

        missing = [k for k in COMMON_REQ if k not in obj]
        if missing:
            missing_required += 1
            issues.append({'line': line_no, 'issue': 'missing_required', 'fields': missing})
            continue

        sample_type = obj.get('sample_type')
        if sample_type not in VALID_SAMPLE_TYPES:
            invalid_sample_type += 1
            issues.append({'line': line_no, 'issue': 'invalid_sample_type', 'sample_type': sample_type})
            continue
python
result = {
    'input': str(inp),
    'total_lines': total,
    'sample_type_counts': dict(sample_type_counts),
    'malformed_json': malformed,
    'missing_required': missing_required,
    'empty_required': empty_fields,
    'invalid_sample_type': invalid_sample_type,
    'invalid_question_type': invalid_question_type,
    'invalid_reasoning_or_analysis_fields': invalid_reasoning_fields,
    'duplicate_exact_items': dup_items,
    'duplicate_normalized_questions': dup_questions,
    'duplicate_normalized_answers': repeated_answers,
    'placeholder_like_questions': placeholder_questions,
    'source_anchored_texts': source_anchored_texts,
    'citation_led_questions': citation_led_questions,
    'meta_like_answers_or_reasoning': meta_answers_or_reasoning,
    'generic_reasoning_steps': generic_reasoning,
    'issue
...[truncated 2178 chars]
Remediation
View remediation

Remediation Suggestions

  1. Define a documented set of blocking counters, including at minimum malformed JSON, missing required fields, empty required fields, invalid sample types, and invalid reasoning structures.
  2. Add an explicit validation result:
    python
    blocking_errors = (
        malformed
        + missing_required
        + empty_fields
        + invalid_sample_type
        + invalid_question_type
        + invalid_reasoning_fields
    )
    result['passed'] = blocking_errors == 0
    
  3. Return a nonzero process status when blocking errors are present:
    python
    import sys
    
    report.write_text(
        json.dumps(result, ensure_ascii=False, indent=2),
        encoding='utf-8',
    )
    print(json.dumps(result, ensure_ascii=False))
    sys.exit(0 if result['passed'] else 1)
    
  4. Separate warnings, such as repeated answers, from fatal schema violations.
  5. Update workflow documentation to require both a zero exit status and an explicit passed: true result.
  6. Add automated tests verifying that each blocking defect causes a nonzero exit status.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

If the implementation only extracts or serializes chunks from a single markdown file while claiming multi-file, resumable, fully audited supervision generation, users can make incorrect operational decisions based on false assurances. In a data pipeline, that can propagate incomplete corpus coverage and mislabeled readiness states into later stages such as model training or release.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

If the implementation only extracts or serializes chunks from a single markdown file while claiming multi-file, resumable, fully audited supervision generation, users can make incorrect operational decisions based on false assurances. In a data pipeline, that can propagate incomplete corpus coverage and mislabeled readiness states into later stages such as model training or release.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

If the implementation only extracts or serializes chunks from a single markdown file while claiming multi-file, resumable, fully audited supervision generation, users can make incorrect operational decisions based on false assurances. In a data pipeline, that can propagate incomplete corpus coverage and mislabeled readiness states into later stages such as model training or release.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill instructs reading and writing many files under a resumable work directory, but it declares no explicit tool scope or permission boundaries. In an agent environment, that can lead to over-broad filesystem access, accidental writes outside the intended workspace, and unclear operator expectations about what the skill is allowed to touch.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · reference.md (reported line 203)May include surrounding context.

json
{
  "sample_type": "case_application",
  "case": "A program stores usernames in a 16-byte buffer but accepts arbitrarily long strings without checking their length.",
  "question": "What risk does this design create, and why?",
  "analysis": [
    "The buffer has a fixed capacity of 16 bytes.",

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This file contains natural-language validation rules that explicitly target Chinese phrases alongside English-only pattern sets, but there is no surrounding comment, docstring, or argument indicating that the tool is intentionally limited to a Chinese/English dataset. That can create a language-policy issue because content quality judgments are tied to specific languages without documented user choice or justified regional scope.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.