Back to skill

Security audit

Zoho Social MCP

Security checks for vulnerabilities and agentic risk

Overview

This is mostly a coherent Zoho Social MCP helper, but it needs review because it combines credentialed social publishing with under-scoped GitHub issue/PR/merge instructions and ships without the advertised action catalog file.

Review before installing. Use the smallest Zoho profile that fits the task, keep social-admin and deleteSocialSchedule disabled unless specifically needed, treat the MCP URL as a password, and require explicit confirmation before any publish, schedule, delete, GitHub issue, PR, or merge action. Be aware that the shipped package is missing references/actions.jsonl, so catalog lookup helpers fail until that file is restored.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (16)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 40)May include surrounding context.

if [ -n "$ZOHO_SOCIAL_MCP_URL" ]; then echo "ZOHO_SOCIAL_MCP_URL is set"; else echo "ZOHO_SOCIAL_MCP_URL is not set"; fi

text

Treat `ZOHO_SOCIAL_MCP_URL` like a password. It contains Social access credentials.

## How to Get Your MCP URL

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents an end-user/agent-facing Zoho Social skill that should help perform Zoho Social tasks such as creating and scheduling posts, uploading media, and resolving entities like portals, brands, and channels. The supplied code does none of that. It is a standalone Python utility for rebuilding references/actions.jsonl from a manually copied UI dump. Its behavior is limited to parsing text, summarizing descriptions, merging with an existing catalog, marking removed actions, and writing JSONL output. While this supports maintaining an action catalog referenced by the broader skill, it does not implement the declared operational Zoho Social capabilities. Therefore the code chunk materially differs from the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents this as an actionable Zoho Social skill to be used whenever a task involves real Zoho Social operations such as creating posts, scheduling/publishing, uploading media, or resolving portals/brands/channels. The supplied code does not do any of that. It is a standalone local inspection/validation CLI for reference metadata files (actions.jsonl and profiles.json). Its capabilities are limited to loading local JSON, resolving inherited profiles, validating consistency, and printing/searching action/task/profile descriptions. While this supports understanding an action catalog and least-privilege profiles, it materially differs from the declared operational purpose and lacks the advertised execution capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description presents a functional Zoho Social operations skill that should help create, validate, schedule, or publish social posts and manage media/library resources. The supplied code does not implement any of those user-facing Zoho Social actions. Instead, it only resolves configuration for MCP endpoints and organization IDs, using CLI args, environment variables, and profile files. While profile handling is mentioned in the description, here it is the entire purpose of the code and it is generic across several Zoho services, not specifically a Zoho Social action skill. This is therefore a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a full Zoho Social operational skill with helpers and workflows for posting, scheduling, publishing, media handling, and entity resolution. The supplied code chunk does none of those things. It is strictly a test file for resolving the MCP endpoint URL from command-line arguments, profiles JSON, and environment variables, plus validating error behavior. While endpoint resolution may be a supporting utility for a Zoho Social MCP integration, this chunk’s primary purpose is configuration resolution testing, not executing or exposing the described Zoho Social capabilities. Therefore the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill describes use of environment variables, file access, network calls, and shell-based helpers, but it does not declare any explicit tool restrictions such as permissions or allowed-tools. In an agent environment, that ambiguity can cause the skill to be executed with broader capabilities than necessary, increasing the blast radius if the skill is misused or if downstream content becomes adversarial.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
Daily use is the discovery loop. Treat every reusable defect, missing capability, safer check, or useful simplification as a contribution.

1. Search open issues immediately with native `gh`; link a match or create one.
2. Include the need, sanitized evidence, expected behavior, and acceptance criteria. Never include MCP URLs, tokens, customer names, or live IDs.
3. If implementation is feasible now: issue → branch → code/docs/tests → PR → CI → merge.
4. If implementation is not feasible now: file the issue before finishing and return its URL.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/MULTI_ACCOUNT.md (reported line 27)May include surrounding context.

Profile file

Create ~/.config/zoho-mcp/profiles.json:

json
{

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/MULTI_ACCOUNT.md (reported line 64)May include surrounding context.

Lock down local files and never commit them:

bash
chmod 700 ~/.config/zoho-mcp
chmod 600 ~/.config/zoho-mcp/profiles.json

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/MULTI_ACCOUNT.md (reported line 65)May include surrounding context.

bash
chmod 700 ~/.config/zoho-mcp
chmod 600 ~/.config/zoho-mcp/profiles.json

Usage

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/social_client.py (reported line 50)May include surrounding context.

python
except EndpointResolutionError as exc:
        print(f"Error: {exc}", file=sys.stderr); raise SystemExit(1)
    command = ["mcporter", "call", f"{mcp_url}.{runtime_tool(tool)}", "--args", json.dumps(args, ensure_ascii=False)]
    try: result = subprocess.run(command, capture_output=True, text=True, timeout=timeout, check=False)
    except FileNotFoundError: return {"error": "mcporter executable not found"}
    except subprocess.TimeoutExpired: return {"error": "mcporter call timed out"}
    if result.returncode != 0: return {"error": result.stderr.strip() or "mcporter call failed"}

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/test_actions_lookup.py (reported line 46)May include surrounding context.

python
data = json.loads(PROFILES_PATH.read_text(encoding="utf-8"))
        self.assertEqual(data.get("version"), 1)
        self.assertEqual(data.get("service"), "social")
        result = subprocess.run(
            [sys.executable, str(LOOKUP_SCRIPT), "--validate"],
            capture_output=True,
            text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/test_actions_lookup.py (reported line 55)May include surrounding context.

python
self.assertIn("Validation OK", result.stdout)

    def test_lookup_cli_profiles_listing(self):
        result = subprocess.run(
            [sys.executable, str(LOOKUP_SCRIPT), "--profiles"],
            capture_output=True,
            text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/test_actions_lookup.py (reported line 66)May include surrounding context.

python
self.assertIn("social-admin", result.stdout)

    def test_lookup_cli_task_inspection(self):
        result = subprocess.run(
            [sys.executable, str(LOOKUP_SCRIPT), "--task", "media-asset-management"],
            capture_output=True,
            text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/test_actions_lookup.py (reported line 76)May include surrounding context.

python
self.assertIn("getSocialMediaLibrary", result.stdout)

    def test_lookup_cli_search_names_only(self):
        result = subprocess.run(
            [sys.executable, str(LOOKUP_SCRIPT), "--search", "draft", "--names-only"],
            capture_output=True,
            text=True,

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/mcp_endpoint.py (reported line 67)May include surrounding context.

python
def _option(args, name):
    return getattr(args, name, None) if args is not None else None


def _validate_url(value, source):

Static analysis

Detected: suspicious.obfuscated_code

Potential obfuscated payload detected.

Warn
Code
suspicious.obfuscated_code
Location
tests/test_social_helpers.py:105