Back to skill

Security audit

Build Protocol

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent long-form writing workflow, but it needs review because broad automatic activation can lead into publishing, uploading, moving, and archiving steps without an explicit approval gate.

Review before installing if you expect the skill to run automatically. Use it only when you want a heavyweight long-form production workflow, and require explicit confirmation before publishing, uploading, moving, archiving, or overwriting deliverables. Do not rely on the included audit script as a CI gate until its exit-status and zero-match handling are fixed.

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
references/audit-script-template.sh:31
Finding

Blocking Audit Failures Return a Successful Exit Status

Content
View full analysis
/dev/null || echo 0) if [ "$count" -lt "$MIN_PMID_PER_FILE" ]; then echo " ❌ $f: only $count citations" fail=$((fail+1)) else echo " ✅ $f: $count citations" fi done [ $fail -eq 0 ] && echo " → PASS ✅" fi ``` The script concludes as follows: ```bash echo "" echo "================================================" echo " Audit complete. Review ⚠️ warnings and ❌ failures." echo " ❌ blocks publishing. ⚠️ documented in errata." echo "================================================" ``` The same pattern is repeated across the citation-duplicate, anti-sycophancy, and H1 checks: failures are counted and displayed, but they are not propagated to the process exit status. ### Technical Analysis The audit script states that critical failures block publication, but it does not maintain a global blocking-failure status or execute `exit 1` when a blocking check fails. Each section either resets its local `fail` variable or merely prints a warning. The final command is a successful `echo`. Therefore, under normal execution, the script returns exit status zero even when it has printed one or more critical failure messages. This creates a mismatch between human-readable output and machine-readable status. CI systems, publication scripts, and AI agents commonly determine whether a quality gate passed by checking only the command exit status. Such consumers will interpret the audit as successful. Some checks, including length, gender balance, and safety-keyword coverage, do not increment a blocking counter at all. They therefore cann ...[truncated 1511 chars]
Remediation
View remediation
0 )); then printf 'Audit failed with %d blocking issue(s).\n' "$blocking_failures" >&2 exit 1 fi printf 'Audit passed with %d warning(s).\n' "$warnings" exit 0 ``` 5. Decide explicitly whether length and safety-keyword failures are blocking. Their implementation should match the policy stated in `SKILL.md`. 6. Add automated tests that invoke the script and assert: - Compliant input returns status 0. - Missing citations return a nonzero status. - Duplicate citations return a nonzero status. - Missing required H1 headings return a nonzero status. - Missing required critical reviews return a nonzero status. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/audit-script-template.sh:35
Finding

Zero-Match Handling Corrupts Numeric Audit Values

Content
View full analysis
/dev/null || echo 0) if [ "$count" -lt "$MIN_PMID_PER_FILE" ]; then echo " ❌ $f: only $count citations" fail=$((fail+1)) else echo " ✅ $f: $count citations" fi ``` Equivalent vulnerable patterns include: ```bash red=$(grep -c "🔴" "$f" 2>/dev/null || echo 0) green=$(grep -c "🟢" "$f" 2>/dev/null || echo 0) ``` ```bash h1=$(grep -c "^# " "$f" 2>/dev/null || echo 0) ``` ```bash male=$(grep -c "男性\|male" "$f" 2>/dev/null || echo 0) female=$(grep -c "女性\|female" "$f" 2>/dev/null || echo 0) ``` ```bash c=$(grep -ic "$kw" "$f" 2>/dev/null || echo 0) ``` ### Technical Analysis `grep -c` has two relevant behaviors when no lines match: 1. It prints `0` to standard output. 2. It returns exit status 1 to indicate that no match was found. Because the command uses `|| echo 0`, a zero-match result produces two zero values in the command substitution: ```text 0 0 ``` The resulting shell variable is not a valid scalar integer. A numeric expression such as: ```bash [ "$count" -lt "$MIN_PMID_PER_FILE" ] ``` can consequently emit an `integer expression expected` diagnostic and return an error instead of entering the intended failure branch. For the citation check, this means that a file with exactly zero citations can fail to increment the failure counter. The script may then print the section-level pass message because `fail` remains zero. Missing H1 headings can be mishandled in the same manner. In the anti-sycophancy check, a document with zero red markers and one or more green markers can cause the malformed red count to skip the `red == 0` branch. If the green count is valid and small enough that the comput ...[truncated 1779 chars]
Remediation
View remediation
/dev/null) || { status=$? if (( status > 1 )); then printf 'Unable to inspect %s\n' "$f" >&2 ((blocking_failures += 1)) count=0 fi } count=${count:-0} ``` 3. For simpler trusted local inputs, use: ```bash count=$(grep -c -- "PMID:" "$f" 2>/dev/null || true) count=${count:-0} ``` Apply the same correction to `red`, `green`, `h1`, `male`, `female`, and safety-keyword counts. 4. Validate numeric values before arithmetic: ```bash case "$count" in ''|*[!0-9]*) printf 'Invalid count for %s\n' "$f" >&2 ((blocking_failures += 1)) continue ;; esac ``` 5. Use arithmetic syntax after validation: ```bash if (( count < MIN_PMID_PER_FILE )); then ((blocking_failures += 1)) fi ``` 6. Add regression tests covering: - Zero matches. - Exactly one match. - Multiple matches. - Missing and unreadable files. - Filenames beginning with a hyphen. - Zero red markers with one or more green markers. - Zero H1 headings. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The metadata description says the skill can trigger implicitly on 'any long-form knowledge production,' which is overly broad and may cause the skill to activate for tasks the user did not explicitly intend to route through this workflow. Over-broad activation is risky because this skill includes operational steps like publishing, uploading, and file movement, so accidental invocation could push the agent into performing side-effecting actions without sufficiently clear user consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The workflow explicitly instructs the agent to 'Convert to docx + upload + VERIFY,' and elsewhere discusses moving files and archiving versions, but it does not require an explicit user warning or confirmation before taking those side-effecting actions. In skill context this is more dangerous because the protocol is designed for large, long-lived deliverables, so accidental publishing, uploading, or file reorganization could affect remote documents, delivery folders, or retained history in ways the user did not authorize.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The comment explicitly states that the gender-balance keywords are 'for Chinese', indicating a built-in locale assumption in the audit logic. This is a natural-language policy concern because the skill imposes a specific language context without offering user choice or clearly documenting a justified region-specific scope.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script states that the safety keywords are a 'medical example' and then embeds Chinese-language terms directly in the matching logic. This creates a fixed language/locale behavior that is not presented as optional or region-specific, which violates the language/locale policy guidance.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The example spec hard-codes both a protected characteristic target ('Asian adults') and a language requirement ('Chinese characters') without framing them as user-provided preferences or medically justified criteria. In a reusable sub-agent template, this can normalize demographic targeting and lead downstream agents to generate health-related content that inappropriately segments users by ethnicity or language, increasing risk of biased, non-consensual personalization.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

Using 'user will reference the deliverable long-term' as a trigger is subjective and difficult for an agent to infer reliably from user intent alone. This can cause mistaken activation of the skill, leading the agent to apply heavyweight workflow constraints or downstream side-effecting steps when the user only wanted ordinary writing help.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.