Back to skill

Security audit

Rss To Social

Security checks for vulnerabilities and agentic risk

Overview

This skill is not clearly malicious, but it overstates automatic social posting and requests high-impact account credentials without enough scoping or safeguards.

Review before installing. Use only trusted public feed URLs, run it with restricted network access if possible, do not provide Twitter or LinkedIn credentials unless the skill is updated to clearly implement and scope direct posting, and treat generated posts as drafts until you have explicit publication controls.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/rss_monitor.py:68
Finding
Unrestricted RSS Feed Retrieval Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/rss_monitor.py:68-91` **Vulnerability Type**: Server-Side Request Forgery through unvalidated feed URLs **Risk Level**: Medium ### Complete Code Snippet ```python def fetch_feeds(): """Fetch all RSS feeds and return new items""" history = load_posted_history() new_items = [] for feed_url in RSS_FEED_URLS: feed_url = feed_url.strip() if not feed_url: continue try: feed = feedparser.parse(feed_url) print(f"✓ Fetched: {feed.feed.get('title', feed_url)[:50]}") for entry in feed.entries[:10]: # Limit to 10 latest per feed link = entry.get('link', '') if link and not is_already_posted(link, history): new_items.append({ 'title': entry.get('title', 'No title'), 'link': link, 'summary': entry.get('summary', '')[:500], 'published': entry.get('published', ''), 'source': feed.feed.get('title', feed_url) }) except Exception as e: print(f"✗ Error fetching {feed_url}: {e}") ``` ### Technical Analysis The Skill reads feed locations from the `RSS_FEED_URLS` environment variable and passes each value directly to `feedparser.parse()`. It does not validate: - The URL scheme. - The destination hostname. - Resolved IP addresses. - Redirect destinations. - Whether the destination belongs to a loopback, private, link-local, reserved, or cloud metadata network. - Response size or request duration. Consequently, a party capable of controlling the environment variable can instruct the runtime to issue requests using the runtime's network position. The intended functionality only requires access to explicitly approved public RSS endpoints, so unrestricted access to arbitrary network destination ...[truncated 1931 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Accept only `https` feed URLs unless another scheme is explicitly required. 2. Parse and normalize each URL before use, rejecting embedded credentials, malformed hosts, and unexpected ports. 3. Resolve the hostname and reject all loopback, private, link-local, multicast, reserved, and unspecified IPv4 and IPv6 addresses. 4. Explicitly block known cloud metadata destinations, including link-local metadata addresses. 5. Validate every redirect destination using the same policy; do not rely only on validation of the original URL. 6. Prefer an explicit allowlist of approved feed domains where the deployment model permits it. 7. Use an HTTP client with defined connection and read timeouts, a maximum redirect count, and a strict response-size limit. 8. Restrict outbound traffic at the container or host level so the Skill can reach only approved public destinations. 9. Log rejected destinations without exposing credentials or other sensitive URL components. 10. Add tests covering direct private addresses, DNS names resolving to private addresses, IPv6 literals, alternate address representations, and public-to-private redirects. ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Unpinned Dependency Allows Unreviewed Future Package Versions<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1` **Vulnerability Type**: Non-reproducible third-party dependency resolution **Risk Level**: Low ### Complete Code Snippet ```text feedparser>=6.0.0 ``` ### Technical Analysis The dependency declaration establishes only a minimum version. A fresh installation may therefore select any later `feedparser` release available from the configured package index. This makes installations non-reproducible and allows dependency code that was not part of the audited project version to enter the runtime automatically. The reviewed package name does not show evidence of typosquatting or dependency confusion, and no malicious dependency was confirmed. The risk arises from permitting future, unreviewed versions rather than from demonstrated malicious behavior in the currently available package. Because `feedparser` processes externally supplied feed content and runs within the Skill process, defects or compromise in a subsequently resolved release would inherit the process's filesystem and network access. ### Attack Path 1. The Skill is installed in a new environment after a later compatible package version becomes available. 2. The package installer resolves that later version because the requirement permits every version at or above `6.0.0`. 3. The later release contains a security vulnerability, compromised code, or an incompatible behavioral change. 4. The dependency code executes when the Skill parses attacker-controlled or otherwise untrusted RSS content. 5. Any resulting impact occurs with the permissions and network access of the Skill process. This is a supply-chain hardening weakness rather than evidence that the named dependency is currently malicious. ### Impact Assessment A compromised or vulnerable future dependency could potentially access the same resources as the Python process, including: - Configured RSS endpoints and outbound network connectivity. - Files accessible to the ...[truncated 310 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `feedparser` to an exact version that has been reviewed and tested. 2. Generate a lock file or fully resolved requirements file covering transitive dependencies. 3. Require package hashes during installation, such as with pip's `--require-hashes` workflow. 4. Install exclusively from a trusted, explicitly configured package index. 5. Update dependencies through a controlled process that includes security review, automated tests, and vulnerability scanning. 6. Rebuild the lock file deliberately rather than allowing dependency versions to change during ordinary deployment. 7. Run the Skill as an unprivileged user with restricted filesystem and outbound network access to reduce the impact of any dependency compromise. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill makes strong claims about AI generation, automatic scheduling, and direct publishing to Twitter/LinkedIn, but the analyzed content does not substantiate those behaviors. This mismatch is dangerous because users may provide credentials or authorize automation under false assumptions about what the skill actually does, reducing informed consent and making later code changes harder to scrutinize.

Missing User Warnings

High
Confidence
94% confidence
Finding
The skill promotes autonomous posting to social accounts but does not prominently warn users that it may publish externally, act on a schedule, and use account credentials. In this context, silent or underexplained automation is risky because it can affect public-facing accounts, brand reputation, and privacy with little friction.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
Test mode claims that no posts will be saved, but it still calls `fetch_feeds()`, which updates `last_check` and writes `posted.json`. This hidden state change can suppress or alter future behavior, causing integrity issues in scheduling/deduplication and violating user expectations about dry-run safety.

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill documents capabilities that rely on environment access and persistent local state (for example API tokens and `.rss-to-social/posted.json`) but does not declare an explicit tool scope or permissions boundary. That omission makes the skill's effective access less transparent to users and reviewers, increasing the chance of over-broad execution or unexpected file/env access when installed.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill asks users to configure sensitive Twitter and LinkedIn tokens without any nearby guidance on secret handling, storage, rotation, or the privacy implications of direct posting. This can lead users to expose high-value credentials in insecure environments or grant posting power without understanding the consequences.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The trigger phrases are broad everyday instructions like 'Check RSS feeds and post latest content' and 'Start RSS monitoring and auto-posting every 4 hours,' which could be activated by normal conversation rather than deliberate invocation. In a skill that can publish externally, ambiguous triggers increase the risk of accidental activation and unintended posting workflows.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This code writes posting history to disk in `.rss-to-social/posted.json`, which affects local user data/state. Although the function has a docstring, there is no user-facing disclosure at the point of operation or in runtime output that the skill persists URLs and timestamps locally, so users may not realize data is being stored.

Tainted flow: 'history_file' from os.getenv (line 37, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
"""Save history of posted items"""
    ensure_data_dir()
    history_file = DATA_DIR / 'posted.json'
    with open(history_file, 'w') as f:
        json.dump(history, f, indent=2)

def get_url_hash(url):
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest describes a skill that monitors RSS feeds and publishes content to Twitter/LinkedIn. In the implementation, `send_to_openclaw` explicitly states it only outputs posts for review and the rest of the code treats that as completion, so the actual behavior is preparation/display rather than publication.

Natural-Language Policy Violations

Low
Confidence
77% confidence
Finding
The document is primarily in English but ends with a Chinese-only support section, without indicating language options or that multilingual content is intentional. This can violate language or locale consistency expectations for users who did not opt into Chinese content.

Unpinned Dependencies

Low
Category
Supply Chain
Content
feedparser>=6.0.0
Confidence
96% confidence
Finding
The dependency is specified as `feedparser>=6.0.0`, which allows installation of any future major or minor release and makes builds non-reproducible. This increases supply-chain risk and can unintentionally pull in vulnerable or breaking versions over time, especially in an automation skill that fetches external content and may run unattended.

Unverifiable Dependency: feedparser has 10 known advisory(ies) (CVE-2011-1157 (feedparser Cross-site Scripting vulnerability); CVE-2009-5065 (feedparser Cross-site Scripting vulnerability); CVE-2011-1158 (feedparser Cross-site Scripting vulnerability) +7 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
78% confidence
Finding
The manifest references `feedparser` without pinning a specific version, while the package has multiple known advisories across its history. Because the installed version is not fixed, there is no assurance that deployment will avoid affected releases; in a skill that ingests untrusted RSS content, parser-related flaws could be more relevant than in a purely internal tool.

Missing User Warnings

Low
Confidence
80% confidence
Finding
The script performs network access by fetching each configured RSS feed URL. While the script title suggests monitoring feeds, there is no explicit user warning that all URLs supplied via `RSS_FEED_URLS` will be contacted and their metadata processed, which is relevant for privacy and network-awareness.

Static analysis

No suspicious patterns detected.