Back to skill

Security audit

Tg Search

Security checks for vulnerabilities and agentic risk

Overview

This skill transparently wraps a local Telegram search command, with some low-risk input-validation and external-dependency caveats.

Install only on a host where you trust the existing /usr/local/bin/tg_search tool and the Telethon session it uses. Treat searches as activity performed through that Telegram setup, and prefer adding local validation for the limit value before broad use.

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

Note
Location
run.py:10
Finding

Unvalidated Search Limit Passed to External Telegram Utility

Content
View full analysis

Vulnerability Details

File Location: run.py, lines 10–14
Vulnerability Type: Improper input validation
Risk Level: Low

python
query = sys.argv[1]
limit = sys.argv[2] if len(sys.argv) >= 3 else "10"

p = subprocess.run(
    ["/usr/local/bin/tg_search", query, limit],
    capture_output=True,
    text=True
)

Technical Analysis

The documentation defines limit as an integer with a maximum value of 50, but the wrapper neither converts it to an integer nor enforces an allowed range. Consequently, arbitrary strings, negative values, zero, and excessively large numeric values are forwarded unchanged to /usr/local/bin/tg_search.

Exploitability and resulting behavior depend on how the external utility validates this argument. That utility is outside the audited project, so its implementation could not be verified. This is not shell-command injection: subprocess.run receives an argument list and does not enable shell=True.

Attack Path

  1. Invoke the skill with a malformed, negative, or excessively large second argument, such as run.py crypto 999999999.
  2. run.py accepts the value without type or range validation.
  3. The value is passed unchanged as an argument to /usr/local/bin/tg_search.
  4. If the external utility does not enforce its own limits, it may perform an excessive search operation, consume unnecessary resources, or return an operational error.

Impact Assessment

A caller may be able to cause errors, excessive Telegram requests, unexpectedly large result processing, or local resource consumption. The issue does not directly grant additional operating-system privileges, expose credentials, or permit shell-command execution. Its scope is limited by validation and authorization controls implemented in the external tg_search executable and by Telegram-side restrictions.

Remediation
View remediation

Remediation Suggestions

Parse limit as an integer before invoking the external utility and enforce the documented range of 1 through 50. Reject non-numeric, zero, negative, and oversized values with a stable JSON error response.

python
try:
    limit = int(sys.argv[2]) if len(sys.argv) >= 3 else 10
except ValueError:
    print(json.dumps({"error": "limit must be an integer"}))
    sys.exit(1)

if not 1 <= limit <= 50:
    print(json.dumps({"error": "limit must be between 1 and 50"}))
    sys.exit(1)

p = subprocess.run(
    ["/usr/local/bin/tg_search", query, str(limit)],
    capture_output=True,
    text=True,
    timeout=30,
    check=False,
)

Retain list-based subprocess invocation without shell=True. Consider adding a timeout and output-size controls to limit resource consumption if the external process stalls or emits unexpectedly large output. The external utility should independently enforce the same range as defense in depth.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

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 · run.py (reported line 13)May include surrounding context.

python
query = sys.argv[1]
    limit = sys.argv[2] if len(sys.argv) >= 3 else "10"

    p = subprocess.run(
        ["/usr/local/bin/tg_search", query, limit],
        capture_output=True,
        text=True

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
72% confidence
Finding

The natural-language comment is written only in Russian and indicates expected usage without offering any language choice or documenting a justified locale constraint. This can conflict with language/locale policy when a skill implicitly assumes a specific language context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

This code invokes an external binary via subprocess, which is a safety-relevant operation for code files. While the file has an internal comment and error handling, it does not provide a user-facing disclosure, confirmation, or clear explanatory docstring/comment about what data is being sent to the external tool.

Content

No source excerpt is available for this finding.