Back to skill

Security audit

9527 Github Trending

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says, but it needs review because it encourages insecure bot-token handling and can send webhook requests to arbitrary URLs.

Install only if you are comfortable with outbound requests to GitHub and your chosen messaging service. Do not put real bot tokens or webhook URLs directly in shell history or crontab; use environment variables or a protected secret file. In shared, server, or agent-hosted environments, restrict webhook destinations to approved Telegram, DingTalk, or WeCom endpoints before enabling push delivery.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
trending.py:165
Finding

Telegram Bot Token Exposure Through Command-Line Arguments and Cron Configuration

Content
View full analysis

Vulnerability Details

File Location: trending.py:165-166; insecure usage examples also appear in README.md:42, README.md:62-66, SKILL.md:36, and SKILL.md:40-44
Vulnerability Type: Sensitive credential exposure through process arguments, shell history, and persistent cron configuration
Risk Level: Medium

Vulnerable Code

python
parser.add_argument('--telegram', '-t', action='store_true', help='Push to Telegram')
parser.add_argument('--token', help='Telegram Bot Token')
parser.add_argument('--chat_id', help='Telegram Chat ID')

The documented invocation passes the credential directly on the command line:

bash
python3 trending.py --telegram --token YOUR_BOT_TOKEN --chat_id YOUR_CHAT_ID

The documented scheduled-task configuration also places the credential in the user's persistent crontab:

bash
# Edit crontab
crontab -e

# Add one line
0 9 * * * python3 /path/to/github-trending-daily/trending.py --telegram --token xxx --chat_id xxx

Technical Analysis

The application requires a Telegram bot token to invoke the Telegram Bot API, but it accepts that secret exclusively as a command-line argument in the documented workflow. Command-line credentials can be exposed through:

  • Process inspection utilities while the application is running.
  • Shell command history.
  • Process accounting, monitoring, or telemetry systems.
  • Job-management logs.
  • The user's persistent crontab when the documented scheduling example is followed.
  • Backups or administrative collection of cron configuration.

The cron mechanism is transparent, optional, and consistent with the declared daily-notification functionality. It is not hidden persistence and does not automatically install itself. However, embedding a long-lived credential in the cron command is not necessary to implement scheduled notifications and violates secure secret-management practices.

Attack Path

  1. A u ...[truncated 1309 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove or deprecate the --token command-line option for production use.
  2. Read the Telegram token from a dedicated environment variable or a permission-restricted secret file.
  3. For cron execution, reference a protected configuration or environment file rather than embedding the token in the crontab command.
  4. Restrict secret-file permissions to the executing user, such as mode 0600, and verify ownership before reading it.
  5. Document that users should not store tokens in shell history, crontab entries, source control, or general-purpose configuration files.
  6. Avoid including credentials in exceptions, debug output, telemetry, or logs.
  7. Recommend immediate Telegram token rotation if a real token has previously been stored in command history or crontab.
  8. Where feasible, use a service-specific secret manager supplied by the deployment environment.

T09 · Insecure Skill Coding Practices

Warning
Location
trending.py:117
Finding

Unrestricted Webhook Destination Allows Arbitrary Server-Side HTTP Requests

Content
View full analysis

Vulnerability Details

File Location: trending.py:117-155; the unrestricted argument is declared at trending.py:169
Vulnerability Type: Server-Side Request Forgery through an unvalidated webhook URL
Risk Level: Medium

Vulnerable Code

python
def send_dingtalk(message: str, webhook: str) -> bool:
    """Send to DingTalk"""
    data = {
        'msgtype': 'markdown',
        'markdown': {
            'title': 'GitHub Trending',
            'text': message
        }
    }

    try:
        req = urllib.request.Request(webhook, data=json.dumps(data).encode('utf-8'), headers={
            'Content-Type': 'application/json'
        })
        with urllib.request.urlopen(req, timeout=30) as response:
            result = json.loads(response.read().decode('utf-8'))
            return result.get('errcode', -1) == 0
    except Exception as e:
        print(f"DingTalk send failed: {e}")
        return False

def send_wecom(message: str, webhook: str) -> bool:
    """Send to WeCom"""
    data = {
        'msgtype': 'markdown',
        'markdown': {
            'content': message
        }
    }

    try:
        req = urllib.request.Request(webhook, data=json.dumps(data).encode('utf-8'), headers={
            'Content-Type': 'application/json'
        })
        with urllib.request.urlopen(req, timeout=30) as response:
            result = json.loads(response.read().decode('utf-8'))
            return result.get('errcode', -1) == 0
    except Exception as e:
        print(f"WeCom send failed: {e}")
        return False

The destination is accepted without validation:

python
parser.add_argument('--webhook', help='DingTalk/WeCom Webhook URL')

Technical Analysis

Both notification functions pass the user-supplied webhook value directly to urllib.request.Request and urllib.request.urlopen. The implementation does not:

  • Require H ...[truncated 2506 chars]
Remediation
View remediation

Remediation Suggestions

  1. Use separate destination validators for DingTalk and WeCom.
  2. Require the https scheme and reject URLs containing unexpected credentials, ports, fragments, or malformed hostnames.
  3. Allowlist the exact official webhook hostnames and expected path formats for each provider.
  4. Resolve the hostname and reject loopback, private, link-local, multicast, unspecified, and reserved IP address ranges for both IPv4 and IPv6.
  5. Revalidate all resolved addresses immediately before connection to reduce DNS-rebinding exposure.
  6. Disable automatic redirects, or validate the scheme, hostname, port, and resolved address at every redirect.
  7. Apply outbound firewall or proxy rules so the runtime can reach only GitHub and the explicitly supported notification APIs.
  8. If custom webhook destinations are a required feature, make that capability explicit and require an administrator-maintained allowlist rather than accepting arbitrary caller input.
  9. Add tests covering localhost, private IPv4 ranges, IPv6 loopback and local ranges, encoded IP representations, alternate ports, DNS rebinding scenarios, and redirects to prohibited destinations.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

The cron example embeds the Telegram token and chat ID directly in a persistent scheduled task, which can expose secrets through shell history, process listings, backups, or readable crontab files. Because cron runs automatically and repeatedly, compromised credentials could enable unauthorized message sending or reuse of the leaked token in other contexts.

Content

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

bash
# 编辑 crontab
crontab -e

# 添加一行
0 9 * * * python3 /path/to/github-trending-daily/trending.py --telegram --token xxx --chat_id xxx

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill documents network-capable behavior but does not declare any explicit tool scope or permissions boundary. This increases the risk of overbroad execution in agent environments because reviewers and users cannot clearly see or constrain the external connectivity the skill requires.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code sends the generated message to Telegram, DingTalk, and WeCom via HTTP requests. Although the functions have internal docstrings and success/failure prints, there is no explicit user disclosure that repository data and message content will be transmitted to third-party services when these options are enabled.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · trending.py (reported line 99)May include surrounding context.

python
def send_telegram(message: str, token: str, chat_id: str) -> bool:
    """发送到 Telegram"""
    url = f"https://api.telegram.org/bot{token}/sendMessage"
    data = {
        'chat_id': chat_id,
        'text': message,

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The README instructs users to send data to Telegram, 钉钉, and 企业微信 using bot tokens and webhook URLs, but it does not warn that these are third-party services or that credentials must be protected. This can lead users to paste secrets into shells, scripts, or screenshots and to transmit repository metadata externally without considering privacy or organizational policy.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation encourages sending results to external services such as Telegram, 钉钉, and 企业微信 without warning that data will leave the local environment or explaining how credentials should be handled. While the transmitted content appears low sensitivity in context, the omission can still lead to accidental disclosure of repository selections, usage patterns, or mismanaged secrets.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The example commands place bot tokens, chat IDs, and webhook URLs directly on the command line and in cron entries, which can expose secrets through shell history, process listings, job definitions, and operational logs. This is a practical credential-handling weakness that could allow unauthorized parties to send notifications, spam channels, or pivot into connected messaging workflows.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The request to GitHub Trending sets the Accept-Language header to 'en-US,en;q=0.5', which forces a specific language/locale preference. This is a natural-language policy concern because the file does not provide an opt-in, configuration option, or justification for imposing that locale.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.