Back to skill

Security audit

Reputation courts practice search

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent paid Russian court-search skill, but it has review-worthy credential handling because the bundled REST client can send the API key to an arbitrary base URL and the setup encourages persistent local MCP authorization configuration.

Install only if you trust reputation.ru and need this paid legal-search service. Prefer OAuth where supported, avoid pasting OAuth tokens or callback URLs, review any MCP config edits before applying them, and do not set REPUTATION_BASE_URL unless it is exactly the intended HTTPS service endpoint.

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
SKILL.md:296
Finding

Unrestricted API Base URL Can Exfiltrate the Service Credential

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:296, 310, 337-347
Vulnerability Type: Unvalidated destination for authenticated network requests
Risk Level: Medium

Vulnerable Code

python
Base URL overridable via REPUTATION_BASE_URL (default https://api.reputation.ru).

BASE_URL = os.environ.get("REPUTATION_BASE_URL", "https://api.reputation.ru").rstrip("/")

def _request(method, path, *, params=None, body=None, expect="json", timeout=60):
    if not API_KEY:
        raise CourtApiError("REPUTATION_API_KEY is not set")
    url = BASE_URL + path
    if params:
        url += "?" + urllib.parse.urlencode(params)
    headers = {"Authorization": API_KEY}
    data = None
    if body is not None:
        data = json.dumps(body).encode("utf-8")
        headers["Content-Type"] = "application/json"
    req = urllib.request.Request(url, data=data, headers=headers, method=method)
    try:
        with urllib.request.urlopen(req, timeout=timeout) as resp:

Technical Analysis

The bundled REST client accepts REPUTATION_BASE_URL directly from the process environment without validating its scheme, hostname, port, or user-information component. _request() then attaches REPUTATION_API_KEY to every request through the Authorization header.

Consequently, anyone able to influence the environment used to launch the client can redirect authenticated requests to an arbitrary server. The override also permits plaintext HTTP, exposing the credential and request content to network interception. Because urllib.request.urlopen() supports redirects, authorization behavior across redirects should also be constrained explicitly rather than relying on implicit client behavior.

Sending the API key to the legitimate https://api.reputation.ru endpoint is necessary for the Skill’s declared functionality. Sending it to an unrestricted environment-selected destination exceeds that minimum requirement.

Attack Path

  1. An attacker, compromised wrapper ...[truncated 1373 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove the REPUTATION_BASE_URL override if custom deployments are not a required feature.
  2. If the override is required, parse it with urllib.parse.urlsplit() and enforce:
    • The https scheme.
    • An explicit allowlist of trusted hostnames, such as api.reputation.ru.
    • No embedded username or password.
    • No unexpected port.
    • An empty or explicitly approved base path.
  3. Construct URLs using validated components rather than direct string concatenation.
  4. Disable automatic redirects or implement a redirect handler that rejects cross-origin redirects. Never forward Authorization to a different origin.
  5. Fail closed with a clear error when endpoint validation fails.
  6. Keep the key in an environment variable or credential store and never print it in errors or diagnostic output.
  7. Add tests confirming that HTTP URLs, unapproved hosts, user-information components, unexpected ports, and cross-origin redirects are rejected.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (8)

MCP Config Access

High
Category
Agent Snooping
Confidence
95% confidence
Finding

The skill instructs the agent to access and modify local MCP configuration files such as .claude/mcp.json and ~/.cursor/mcp.json. Guidance that touches local config and credential-bearing integration settings can lead an autonomous agent to alter trusted execution environment state, introduce persistent external connections, or mishandle secrets without an explicit out-of-band approval boundary.

Content

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

md
| **Account sign-in (OAuth)** | the client supports OAuth for MCP **and** a person is at the keyboard | the user, in a browser |
| **API key** | any client, headless runs, REST, CI | you, with a key the user supplies |

MCP config lives in `.claude/mcp.json`, `~/.cursor/mcp.json`, the Claude Desktop
config, or your runtime's equivalent. Restart the client after editing it.

### 1a. MCP with account sign-in (OAuth)

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 · SKILL.md (reported line 85)May include surrounding context.

md
**You cannot complete this flow yourself.** It needs a person in a browser. If you are
running non-interactively, stop and say so: ask the user to authorize the server in their
client (Claude Code: `/mcp`; Cursor: MCP settings), then retry. **Never ask the user to
paste an authorization code, access token, or callback URL to you**, and never try to
drive the consent page yourself.

**Do not add `headers.Authorization` to an OAuth config.** Most clients skip the sign-in

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 · SKILL.md (reported line 268)May include surrounding context.

md
**You cannot complete this flow yourself.** It needs a person in a browser. If you are
running non-interactively, stop and say so: ask the user to authorize the server in their
client (Claude Code: `/mcp`; Cursor: MCP settings), then retry. **Never ask the user to
paste an authorization code, access token, or callback URL to you**, and never try to
drive the consent page yourself.

**Do not add `headers.Authorization` to an OAuth config.** Most clients skip the sign-in

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The argument hint requires a question in Russian, which imposes a language constraint on users. Elsewhere the document reinforces this with instructions like writing the query in Russian, but it does not explicitly present this as an opt-in choice or clearly justify the restriction as a region-specific compliance requirement.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
{
  "mcpServers": {
    "reputation-court-search": {
      "url": "https://api.reputation.ru/mcp"
    }
  }
}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% 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 · SKILL.md (reported line 84)May include surrounding context.

md
**You cannot complete this flow yourself.** It needs a person in a browser. If you are
running non-interactively, stop and say so: ask the user to authorize the server in their
client (Claude Code: `/mcp`; Cursor: MCP settings), then retry. **Never ask the user to
paste an authorization code, access token, or callback URL to you**, and never try to
drive the consent page yourself.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

The example explicitly places an API key in a static Authorization header inside MCP configuration. Embedding long-lived credentials in local config increases risk of credential leakage through file exposure, logs, backups, screenshots, or downstream tooling, and it may encourage agents to handle secrets directly.

Content

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

md
{
  "mcpServers": {
    "reputation-court-search": {
      "url": "https://api.reputation.ru/mcp",
      "headers": { "Authorization": "<your-api-key>" }
    }
  }