Back to skill

Security audit

Humanizer

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to work as an offline AI-writing detector and rewriter, but it needs review because it is built to mask AI authorship signals, encourages persistent agent style changes, and has a terminal-output safety issue.

Review this before installing if you care about authorship transparency. Use it only for editing where it is appropriate to change style, not to conceal AI involvement in schoolwork, hiring materials, compliance filings, legal documents, or other contexts where authorship matters. Avoid enabling the always-on prompt templates unless you intentionally want a persistent style policy and know how to remove it. When analyzing untrusted text, prefer JSON output or a cautious terminal environment until terminal-control escaping is 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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
src/cli.js:372
Finding

Unsanitized Terminal Control Sequences in Analysis Output

Content
View full analysis

Vulnerability Details

File Location: src/cli.js:372-380; additional affected rendering paths include src/cli.js:414-436 and src/humanizer.js:340-362
Vulnerability Type: Terminal escape-sequence injection
Risk Level: Medium

Vulnerable Code

js
for (const match of finding.matches) {
  const loc = match.line ? `L${match.line}` : '';
  const preview =
    typeof match.match === 'string'
      ? match.match.substring(0, 80) + (match.match.length > 80 ? '...' : '')
      : '';
  lines.push(`      ${color.dim(loc)}: "${preview}"`);
  if (match.suggestion) {
    lines.push(`            ${color.green('→')} ${match.suggestion}`);
  }
}

The grouped suggestion formatter similarly prints matched input without sanitization:

js
for (const s of result.critical) {
  lines.push(`  ${color.red('●')} L${s.line}: ${color.bold(s.pattern)}`);
  lines.push(`    ${color.dim(truncate(s.text, 60))}`);
  lines.push(`    ${color.green('→')} ${s.suggestion}`);
}

The non-colored humanization formatter also includes the original match directly:

js
for (const s of result.critical) {
  lines.push(`  L${s.line}: [${s.pattern}] "${truncate(s.text, 60)}" [${s.confidence}]`);
  lines.push(`       → ${s.suggestion}`);
}

Technical Analysis

The CLI accepts text from an explicitly selected file or standard input. Pattern matches derived from that potentially untrusted text are interpolated directly into terminal reports. Truncating a string does not neutralize embedded C0/C1 control characters, ANSI Control Sequence Introducer sequences, or Operating System Command sequences.

Some detectors can return matches containing attacker-controlled trailing text rather than only a fixed vocabulary token. For example, the superficial -ing detector captures text through the remainder of a sentence. Consequently, an escape sequence placed within a detected passage can reach the terminal ...[truncated 2113 chars]

Remediation
View remediation

Remediation Suggestions

  1. Add a dedicated terminal-safe escaping function and apply it to every value derived from input text before terminal interpolation.
  2. Remove ANSI CSI, OSC, DCS, APC, PM, and SOS sequences, not merely the ESC byte.
  3. Escape remaining non-printable C0 and C1 characters into visible notation such as \x1b, while retaining only deliberately supported whitespace.
  4. Sanitize before truncation so truncation cannot split an escape sequence and leave a dangerous fragment.
  5. Apply the same protection to formatColoredReport, formatGroupedSuggestions, and formatSuggestions.
  6. Keep machine-readable JSON output separate from terminal-rendering functions. Document that consumers must treat analyzed text as untrusted.
  7. Add regression tests using CSI screen-clearing sequences, OSC 8 hyperlinks, OSC 52 clipboard sequences, carriage returns, backspaces, and embedded null bytes.
  8. Consider refusing terminal rendering of raw matches unless explicitly requested, or provide a safe mode that displays escaped byte representations.

A suitable design is:

js
function escapeTerminalText(value) {
  return String(value)
    .replace(/\x1B(?:\][^\x07\x1B]*(?:\x07|\x1B\\)|\[[0-?]*[ -/]*[@-~])/g, '')
    .replace(/[\x00-\x08\x0B-\x1F\x7F-\x9F]/g, (char) =>
      `\\x${char.charCodeAt(0).toString(16).padStart(2, '0')}`,
    );
}

const preview = escapeTerminalText(match.match).substring(0, 80);
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear mismatch between the description and the code. The description presents a text-processing skill focused on detecting and rewriting AI-generated prose. The actual code only exports ESLint configuration for JavaScript source and test files, including parser options, globals, rules, and ignore settings. It does not inspect user text, compute linguistic statistics, detect AI vocabulary patterns, or rewrite content. Its primary purpose is development tooling configuration, which is materially different from the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description describes a substantial natural-language processing feature set for detecting and humanizing AI-generated text. The actual code chunk is only a JavaScript test runner configuration for Vitest, defining globals and which test files to include. This is materially unrelated to the declared primary purpose and does not implement any of the described capabilities. Therefore, the description does not accurately represent the supplied code chunk.

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 109)May include surrounding context.

md
echo "Your text here" | node src/cli.js score

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
echo "Your text here" | node src/cli.js score

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
echo "Your text here" | node src/cli.js score

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
echo "Your text here" | node src/cli.js score

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
echo "Your text here" | node src/cli.js score

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
echo "Your text here" | node src/cli.js score

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
echo "Your text here" | node src/cli.js score

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README advertises humanize --autofix as applying 'safe auto-fixes' but does not clearly warn that it modifies the user's input content. Users may assume the operation is advisory only, which can lead to unintended overwrites, loss of authorial meaning, or accidental processing of sensitive text in workflows that expect analysis without mutation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README explicitly encourages users to bake a single anti-AI writing style into an agent's persistent system prompt or personality file, making it always-on rather than user-directed. That creates a scope/consent problem: the skill can silently override user-preferred tone, style, or communication norms across unrelated tasks, which is risky for agents expected to adapt to user intent.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The activation language is broad enough to trigger on ordinary editing or writing-improvement requests, which can cause the agent to rewrite text in ways that intentionally obscure AI provenance or alter user meaning without explicit consent. In provenance-sensitive contexts such as schoolwork, journalism, compliance, or hiring materials, this creates deception and policy-bypass risk rather than a mere UX issue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill is expressly designed to make AI-generated text appear human, yet it provides no warning about authorship masking, academic dishonesty, fraud, or alteration of provenance-sensitive documents. That omission materially increases misuse risk because users are not informed that the tool can facilitate deception in contexts where authorship and authenticity matter.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The style tip explicitly suggests adding first-person perspective such as 'I found' or 'In my experience' as a generic humanization tactic, without requiring that those statements be true or attributable to the actual author. In a tool designed to rewrite text to appear more human, this can encourage fabrication of personal experience or false authorship signals, which is especially risky in professional, academic, legal, or safety-sensitive writing.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The file explicitly labels the syllable estimator as an "English heuristic" and elsewhere uses its outputs to score text as more "AI-like" or "human-like." Because this locale-specific assumption is embedded in the analysis behavior without any user opt-in or clear documented justification in the file, it risks violating language/locale policy expectations for multilingual use.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

The comments state that certain words 'almost never appear in natural human writing' and are 'damning in groups,' which is a strong natural-language claim about acceptable language usage. Because the file encodes these judgments directly into a vocabulary database without any user opt-in, exception handling, or locale/context qualification, it risks enforcing a stylistic policy that can unfairly target legitimate human writing.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 41)May include surrounding context.

json
"url": "https://github.com/brandonwise/humanizer"
  },
  "devDependencies": {
    "@eslint/js": "^9.39.2",
    "eslint": "^9.0.0",
    "prettier": "^3.0.0",
    "vitest": "^3.0.0"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 42)May include surrounding context.

json
},
  "devDependencies": {
    "@eslint/js": "^9.39.2",
    "eslint": "^9.0.0",
    "prettier": "^3.0.0",
    "vitest": "^3.0.0"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 43)May include surrounding context.

json
"devDependencies": {
    "@eslint/js": "^9.39.2",
    "eslint": "^9.0.0",
    "prettier": "^3.0.0",
    "vitest": "^3.0.0"
  },
  "engines": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 44)May include surrounding context.

json
"@eslint/js": "^9.39.2",
    "eslint": "^9.0.0",
    "prettier": "^3.0.0",
    "vitest": "^3.0.0"
  },
  "engines": {
    "node": ">=18.0.0"

Unverifiable Dependency: vitest has 3 known advisory(ies) (CVE-2026-47429 (When Vitest UI server is listening, arbitrary file can be read and executed); CVE-2026-84373 (Vitest: Path Traversal / Arbitrary File Read via @vitest/mocker Redirect Mock); CVE-2025-24964 (Vitest allows Remote Code Execution when accessing a malicious website while Vit)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
78% confidence
Finding

vitest is flagged with known advisories, and the manifest's broad version range prevents verification that the installed version includes fixes. Although it is a devDependency, vulnerable test tooling can still expose developers or CI runners to file read or code execution risks if Vitest UI, mocker features, or related services are used in reachable environments.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The guide instructs writers to use straight quotes and to prefer commas and periods over em dashes, which imposes a specific writing convention as a blanket rule. This can function as a language/locale style constraint without offering user choice or documenting why that constraint is required.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.