Back to skill

Security audit

Linkedin Humanizer

Security checks for vulnerabilities and agentic risk

Overview

This skill is a LinkedIn writing and audit helper with an optional detector-testing script that can send draft text to named third-party detector APIs when the user runs it with API credentials.

Install only if you are comfortable with a writing tool that may rewrite aggressively. Do not run the detector tester in API or manual mode on confidential drafts unless you are willing to send that text to the named external detector services; use --demo or local audit mode for private material.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (27)

Tainted flow: 'text' from sys.stdin.read (line 326, user input) → requests.post (network output)

Medium
Category
Data Flow
Content
if not key:
        return DetectorResult("GPTZero", None, "no API key (set GPTZERO_API_KEY)")
    try:
        r = requests.post(
            "https://api.gptzero.me/v2/predict/text",
            headers={"x-api-key": key, "Content-Type": "application/json"},
            json={"document": text},
Confidence
94% confidence
Finding
User-supplied text is transmitted to a third-party AI detector API without any explicit consent, warning, or data-classification guard. If users paste confidential drafts, client data, or regulated content, the tool can cause unintended external disclosure to multiple vendors.

Tainted flow: 'text' from sys.stdin.read (line 326, user input) → requests.post (network output)

Medium
Category
Data Flow
Content
if not key:
        return DetectorResult("Originality.ai", None, "no API key (set ORIGINALITY_API_KEY)")
    try:
        r = requests.post(
            "https://api.originality.ai/api/v1/scan/ai",
            headers={"X-OAI-API-KEY": key, "Content-Type": "application/json"},
            json={"content": text, "title": "detector-test"},
Confidence
94% confidence
Finding
The script forwards input text to Originality.ai, which creates a clear external data-transfer path for user content. In the context of a 'humanizer' skill likely used on drafts before publication, users may submit unpublished, proprietary, or sensitive material without understanding it is being sent off-platform.

Tainted flow: 'text' from sys.stdin.read (line 326, user input) → requests.post (network output)

Medium
Category
Data Flow
Content
if not key:
        return DetectorResult("ZeroGPT", None, "no API key (set ZEROGPT_API_KEY)")
    try:
        r = requests.post(
            "https://api.zerogpt.com/api/detect/detectText",
            headers={"ApiKey": key, "Content-Type": "application/json"},
            json={"input_text": text},
Confidence
94% confidence
Finding
Text from stdin or CLI is sent to another third-party detector, expanding the disclosure surface across multiple providers. Parallel submission to several vendors increases privacy risk because the same potentially sensitive content is replicated externally several times.

Tainted flow: 'text' from sys.stdin.read (line 326, user input) → requests.post (network output)

Medium
Category
Data Flow
Content
if not key:
        return DetectorResult("Sapling", None, "no API key (set SAPLING_API_KEY)")
    try:
        r = requests.post(
            "https://api.sapling.ai/api/v1/aidetect",
            json={"key": key, "text": text},
            timeout=30,
Confidence
95% confidence
Finding
This call sends both the user's text and the API credential to an external detector service, with no visible user-facing privacy disclosure. The main concern is not injection, but silent outbound transfer of possibly confidential user content to a third party.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill advertises capabilities that imply environment access, file writing, and network use, but it does not declare permissions or clearly gate those actions. In this context, that matters because the skill handles user-supplied draft text and references external detector APIs, creating a risk of silent data egress or unexpected side effects when users believe they are only getting local rewriting or audit behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill description frames detector testing as a sub-tool, but the referenced behavior includes transmitting full user text to multiple third-party AI detector services and supporting manual paste workflows to outside websites. That mismatch is dangerous because users may submit confidential drafts, DMs, or business content expecting local text cleanup, without realizing their content may be disclosed externally or pseudo-analyzed with fabricated demo scores.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The example rewrites generic input into a claim with a precise operational metric ('35k LinkedIn profiles through our system daily') that does not exist in the source and is not labeled as fictional. In a skill explicitly designed to make content appear more human and platform-ready, this encourages users to publish fabricated specificity, which can mislead audiences, create fraud/reputation risk, and normalize deceptive content generation.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The tool's core function is to submit user text to multiple external detector APIs, yet it does not clearly warn users about third-party data transmission or privacy consequences before doing so. In this skill context, users may be processing unpublished LinkedIn drafts, employer material, or client content, making silent sharing materially risky.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
Manual mode instructs users to paste content into third-party websites without any privacy or confidentiality warning. This can cause users to disclose sensitive drafts, internal communications, or regulated text outside approved channels.

Vague Triggers

Medium
Confidence
86% confidence
Finding
The auto-invocation note says the audit runs when `linkedin-post-writer` finishes a draft, but it does not define explicit gating conditions, scope, or user consent. In an agent setting, underspecified chaining can cause the sub-skill to activate on broader content than intended, leading to unintended processing, policy/style enforcement, or prompt-surface expansion across workflows.

Natural-Language Policy Violations

Medium
Confidence
78% confidence
Finding
The blocker rule hard-fails posts containing em dashes, en dashes, or double dashes, which imposes a rigid stylistic policy without any user opt-in or locale/context awareness. This is not a classic security flaw, but in an agent skill it can override user preferences, distort output, and create unnecessary or misleading rewrites when users did not request that specific house style.

External Transmission

Medium
Category
Data Exfiltration
Content
if not key:
        return DetectorResult("GPTZero", None, "no API key (set GPTZERO_API_KEY)")
    try:
        r = requests.post(
            "https://api.gptzero.me/v2/predict/text",
            headers={"x-api-key": key, "Content-Type": "application/json"},
            json={"document": text},
Confidence
96% confidence
Finding
This duplicate finding identifies the same GPTZero transmission path. The underlying issue remains external disclosure of user-provided content to a third-party service.

External Transmission

Medium
Category
Data Exfiltration
Content
if not key:
        return DetectorResult("Originality.ai", None, "no API key (set ORIGINALITY_API_KEY)")
    try:
        r = requests.post(
            "https://api.originality.ai/api/v1/scan/ai",
            headers={"X-OAI-API-KEY": key, "Content-Type": "application/json"},
            json={"content": text, "title": "detector-test"},
Confidence
96% confidence
Finding
This duplicate finding corresponds to the same Originality.ai outbound content submission. The risk is privacy and unintended data sharing, not code execution.

External Transmission

Medium
Category
Data Exfiltration
Content
if not key:
        return DetectorResult("ZeroGPT", None, "no API key (set ZEROGPT_API_KEY)")
    try:
        r = requests.post(
            "https://api.zerogpt.com/api/detect/detectText",
            headers={"ApiKey": key, "Content-Type": "application/json"},
            json={"input_text": text},
Confidence
96% confidence
Finding
This duplicate finding maps to the same ZeroGPT outbound request carrying user text. The presence of multiple duplicate alerts does not change the core risk of third-party disclosure.

External Transmission

Medium
Category
Data Exfiltration
Content
if not key:
        return DetectorResult("Sapling", None, "no API key (set SAPLING_API_KEY)")
    try:
        r = requests.post(
            "https://api.sapling.ai/api/v1/aidetect",
            json={"key": key, "text": text},
            timeout=30,
Confidence
96% confidence
Finding
This duplicate finding reflects the same Sapling content transmission. It is a true privacy-relevant issue because sensitive drafts may be sent to external infrastructure.

External Transmission

Medium
Category
Data Exfiltration
Content
if not key:
        return DetectorResult("GPTZero", None, "no API key (set GPTZERO_API_KEY)")
    try:
        r = requests.post(
            "https://api.gptzero.me/v2/predict/text",
            headers={"x-api-key": key, "Content-Type": "application/json"},
            json={"document": text},
Confidence
96% confidence
Finding
This duplicate finding identifies the same GPTZero transmission path. The underlying issue remains external disclosure of user-provided content to a third-party service.

External Transmission

Medium
Category
Data Exfiltration
Content
if not key:
        return DetectorResult("Originality.ai", None, "no API key (set ORIGINALITY_API_KEY)")
    try:
        r = requests.post(
            "https://api.originality.ai/api/v1/scan/ai",
            headers={"X-OAI-API-KEY": key, "Content-Type": "application/json"},
            json={"content": text, "title": "detector-test"},
Confidence
96% confidence
Finding
This duplicate finding corresponds to the same Originality.ai outbound content submission. The risk is privacy and unintended data sharing, not code execution.

External Transmission

Medium
Category
Data Exfiltration
Content
if not key:
        return DetectorResult("ZeroGPT", None, "no API key (set ZEROGPT_API_KEY)")
    try:
        r = requests.post(
            "https://api.zerogpt.com/api/detect/detectText",
            headers={"ApiKey": key, "Content-Type": "application/json"},
            json={"input_text": text},
Confidence
96% confidence
Finding
This duplicate finding maps to the same ZeroGPT outbound request carrying user text. The presence of multiple duplicate alerts does not change the core risk of third-party disclosure.

External Transmission

Medium
Category
Data Exfiltration
Content
if not key:
        return DetectorResult("Sapling", None, "no API key (set SAPLING_API_KEY)")
    try:
        r = requests.post(
            "https://api.sapling.ai/api/v1/aidetect",
            json={"key": key, "text": text},
            timeout=30,
Confidence
96% confidence
Finding
This duplicate finding reflects the same Sapling content transmission. It is a true privacy-relevant issue because sensitive drafts may be sent to external infrastructure.

External Transmission

Medium
Category
Data Exfiltration
Content
# Step 2: submit text for AI detection
        scan_id = f"detector-test-{abs(hash(text)) % 10**8}"
        r = requests.post(
            f"https://api.copyleaks.com/v2/writer-detector/{scan_id}/check",
            headers={
                "Authorization": f"Bearer {token}",
Confidence
97% confidence
Finding
This is the actual Copyleaks content submission endpoint, so user text is being transmitted externally here. Combined with other detector calls, this broadens the number of external processors receiving the same content.

External Transmission

Medium
Category
Data Exfiltration
Content
return DetectorResult("GPTZero", None, "no API key (set GPTZERO_API_KEY)")
    try:
        r = requests.post(
            "https://api.gptzero.me/v2/predict/text",
            headers={"x-api-key": key, "Content-Type": "application/json"},
            json={"document": text},
            timeout=30,
Confidence
95% confidence
Finding
This finding pinpoints the GPTZero URL directly, confirming an external service destination. The risk is still silent third-party transmission of user text in a content-processing workflow.

External Transmission

Medium
Category
Data Exfiltration
Content
return DetectorResult("Originality.ai", None, "no API key (set ORIGINALITY_API_KEY)")
    try:
        r = requests.post(
            "https://api.originality.ai/api/v1/scan/ai",
            headers={"X-OAI-API-KEY": key, "Content-Type": "application/json"},
            json={"content": text, "title": "detector-test"},
            timeout=30,
Confidence
95% confidence
Finding
This finding pinpoints the Originality.ai endpoint used for content scanning. It is a true data egress path for user text and therefore privacy-relevant.

External Transmission

Medium
Category
Data Exfiltration
Content
return DetectorResult("ZeroGPT", None, "no API key (set ZEROGPT_API_KEY)")
    try:
        r = requests.post(
            "https://api.zerogpt.com/api/detect/detectText",
            headers={"ApiKey": key, "Content-Type": "application/json"},
            json={"input_text": text},
            timeout=30,
Confidence
95% confidence
Finding
This confirms the ZeroGPT endpoint as another external recipient of submitted text. The multiplicity of vendors increases exposure if the input contains confidential information.

External Transmission

Medium
Category
Data Exfiltration
Content
return DetectorResult("Sapling", None, "no API key (set SAPLING_API_KEY)")
    try:
        r = requests.post(
            "https://api.sapling.ai/api/v1/aidetect",
            json={"key": key, "text": text},
            timeout=30,
        )
Confidence
95% confidence
Finding
This confirms the Sapling detector endpoint as an outbound data path for user content. In practice, this means drafts may leave the local environment without strong privacy signaling.

External Transmission

Medium
Category
Data Exfiltration
Content
# Step 2: submit text for AI detection
        scan_id = f"detector-test-{abs(hash(text)) % 10**8}"
        r = requests.post(
            f"https://api.copyleaks.com/v2/writer-detector/{scan_id}/check",
            headers={
                "Authorization": f"Bearer {token}",
                "Content-Type": "application/json",
Confidence
96% confidence
Finding
This confirms the Copyleaks writer-detector endpoint used to submit text. It is a real external transmission path and should be treated as a user-data disclosure event.

Static analysis

No suspicious patterns detected.