T09 · Insecure Skill Coding Practices
- Location
references/config.md:1- Finding
Hardcoded Discord Webhook Credential
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly does what it says, but it ships a real-looking Discord webhook credential and tells agents to use it for external posting.
Review before installing. Do not use the bundled webhook; assume it is compromised, revoke or replace it, and provide your own webhook through a safer local secret mechanism. Run in an isolated Python environment and expect the skill to send scraped CNBC article content to Discord when invoked.
references/config.md:1Hardcoded Discord Webhook Credential
SKILL.md:143Unpinned Third-Party Dependency Installation
The documentation includes full Discord webhook URLs that appear live, which are effectively bearer secrets. Anyone who obtains them can post arbitrary messages to the associated Discord channel, abuse the integration, or use them as a covert exfiltration destination.
Embedding a live-looking webhook directly in examples encourages credential reuse and makes the secret immediately available to any reader or automated system parsing the document. This materially increases the chance of unauthorized posting, spam, channel compromise, and use of the webhook as an exfiltration sink.
The file exposes a live Discord webhook URL directly in repository content, which is effectively a secret that allows unauthenticated posting to a Discord channel. Anyone who obtains this URL can spam the channel, send misleading messages, abuse integrations, or force the webhook owner to rotate and remediate the credential.
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.
# CNBC Geopolitics Fetcher Skill
## Purpose
Fetches latest CNBC geopolitical news articles, extracts complete factual data (NO truncation), and posts each article individually to Discord with enhanced analyst/Polymarket-relevant context.
## What This Skill Does
1. **Scrapes** 5 latest CNBC articles on geopolitics (Iran, Middle East, oil markets, energy policy)
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.
# CNBC Geopolitics Fetcher Skill
## Purpose
Fetches latest CNBC geopolitical news articles, extracts complete factual data (NO truncation), and posts each article individually to Discord with enhanced analyst/Polymarket-relevant context.
## What This Skill Does
1. **Scrapes** 5 latest CNBC articles on geopolitics (Iran, Middle East, oil markets, energy policy)
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.
# CNBC Geopolitics Fetcher Skill
## Purpose
Fetches latest CNBC geopolitical news articles, extracts complete factual data (NO truncation), and posts each article individually to Discord with enhanced analyst/Polymarket-relevant context.
## What This Skill Does
1. **Scrapes** 5 latest CNBC articles on geopolitics (Iran, Middle East, oil markets, energy policy)
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.
# CNBC Geopolitics Fetcher Skill
## Purpose
Fetches latest CNBC geopolitical news articles, extracts complete factual data (NO truncation), and posts each article individually to Discord with enhanced analyst/Polymarket-relevant context.
## What This Skill Does
1. **Scrapes** 5 latest CNBC articles on geopolitics (Iran, Middle East, oil markets, energy policy)
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.
# CNBC Geopolitics Fetcher Skill
## Purpose
Fetches latest CNBC geopolitical news articles, extracts complete factual data (NO truncation), and posts each article individually to Discord with enhanced analyst/Polymarket-relevant context.
## What This Skill Does
1. **Scrapes** 5 latest CNBC articles on geopolitics (Iran, Middle East, oil markets, energy policy)
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.
# CNBC Geopolitics Fetcher Skill
## Purpose
Fetches latest CNBC geopolitical news articles, extracts complete factual data (NO truncation), and posts each article individually to Discord with enhanced analyst/Polymarket-relevant context.
## What This Skill Does
1. **Scrapes** 5 latest CNBC articles on geopolitics (Iran, Middle East, oil markets, energy policy)
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.
# CNBC Geopolitics Fetcher Skill
## Purpose
Fetches latest CNBC geopolitical news articles, extracts complete factual data (NO truncation), and posts each article individually to Discord with enhanced analyst/Polymarket-relevant context.
## What This Skill Does
1. **Scrapes** 5 latest CNBC articles on geopolitics (Iran, Middle East, oil markets, energy policy)
The skill is designed to fetch external content and send it to a Discord webhook, but the documentation does not clearly foreground that this transmits data to a third-party service. In an agent setting, that omission increases the risk of unintended exfiltration of fetched content or operator-provided context to an external endpoint.
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.
- Extracts: title, full article text, description metadata
- Falls back to regex extraction if Scrapling fails
### 3. Fact Extraction (NO Truncation)
- Splits article text into complete sentences
- Scans for 6 fact categories:
1. **Official**: Quoted statements with attribution (said/stated/announced)
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.
### 4. Market Impact Extraction
- Scans for energy, stocks, currency, analyst, Polymarket sentences
- Returns complete sentences (NO length limits)
- Categories: Energy, Stocks, Currency, Analyst, Polymarket
### 5. Discord Posting
The customization section instructs users to run the script with an --output argument to write results to output.md, but elsewhere the skill is consistently described as scraping CNBC articles and posting them to Discord. This is an active documentation-level divergence because it presents a concrete alternate behavior not supported by the stated skill intent in the rest of the file.
The skill explicitly instructs an LLM/agent to read a local config file for a webhook secret and use it to transmit data externally. That behavior normalizes secret retrieval and outbound posting without an approval boundary, which is risky in agentic environments where local files may contain sensitive credentials.
For plain text files, vague or missing trigger descriptions are in scope. This file provides article summaries only and does not define when the skill should activate, what phrases should invoke it, or any exclusions, leaving invocation behavior ambiguous.
This code performs outbound HTTP POST requests to a Discord webhook, transmitting scraped article content and URLs off-system. While the module docstring mentions posting to Discord, the runtime path that actually sends data provides no confirmation prompt or explicit user-facing warning at the point of transmission, which is the kind of disclosure this rule looks for in code files.
The script intentionally preserves full sentences from untrusted remote HTML and later incorporates them into Discord messages without effective size bounds. A malicious or malformed page could supply extremely long 'sentences,' causing oversized payloads, repeated failures, noisy output, or downstream denial-of-service behavior in the posting workflow.
# Split into sentences
sentences = re.split(r'(?<=[.!?])\s+', text)
# Find oil/energy sentences - NO length limit
for sent in sentences:
if any(x in sent.lower() for x in ['oil', 'crude', 'WTI', 'Brent', 'barrel', 'energy']):
if len(sent) > 20: # Only minimum length check
This branch appends full stock-related sentences from scraped content with no upper bound, contributing to unbounded message construction from untrusted input. In this skill context, remote publishers control the source text, so malformed or adversarially long text can degrade reliability and create output flooding or repeated posting errors.
impacts.append(f"Energy: {sent}")
break
# Find stock sentences - NO length limit
for sent in sentences:
if any(x in sent.lower() for x in ['S&P', 'NASDAQ', 'Dow', 'Stoxx', 'stock', 'market']):
if len(sent) > 20:
Currency-related sentences are copied verbatim from external content without a maximum length, creating the same unbounded output condition. Because the data comes from the network and is later sent to another network sink, this can amplify oversized or malformed input into operational failures.
impacts.append(f"Stocks: {sent}")
break
# Find currency sentences - NO length limit
for sent in sentences:
if any(x in sent.lower() for x in ['dollar', 'EUR', 'USD', 'currency', 'exchange']):
if len(sent) > 20:
Analyst/economic forecast snippets are accepted with only a minimum-length check and no maximum bound, so a single long sentence can balloon the outgoing message. In an automated posting pipeline, this can trigger repeated exceptions, partial delivery, or excessive resource use.
impacts.append(f"Currency: {sent}")
break
# Find analyst/economic forecast sentences - NO length limit
for sent in sentences:
if any(x in sent.lower() for x in ['analyst', 'economist', 'forecast', 'gdp', 'inflation', 'fed', 'interest rate', 'recession']):
if len(sent) > 20:
Prediction-market-related sentences are appended without length limits, again allowing untrusted remote content to control message size. The danger here is availability and output integrity rather than confidentiality: attackers can force noisy, broken, or oversized posts.
impacts.append(f"Analyst: {sent}")
break
# Find Polymarket/prediction market sentences - NO length limit
for sent in sentences:
if any(x in sent.lower() for x in ['polymarket', 'prediction', 'odds', 'probability', 'betting', 'market pricing']):
if len(sent) > 20:
The formatter uses complete market-impact strings and extracted facts 'as-is' from remote content, with no effective per-field truncation before assembling the outbound Discord message. Although there is a 2000-character check later, the split path is buggy and does not safely constrain arbitrary overlong fields, making output-flooding and reliability failures realistic.
# Market: use complete market impact string
market = article.get('market_impact', 'See article')
# Facts: use complete sentences as-is (NO truncation)
facts = article.get('hard_facts', ['No facts extracted'])[:5]
facts_text = ''
for f in facts:
This loop concatenates up to five unbounded fact strings into a single message body, allowing attacker-controlled remote text to dominate output size and break delivery. In this skill, the source is external HTML and the sink is a webhook, so unbounded concatenation directly affects availability and operational safety.
facts = article.get('hard_facts', ['No facts extracted'])[:5]
facts_text = ''
for f in facts:
# No truncation - use complete sentence as extracted
facts_text += f" - {f}\n"
# NEW FORMAT: Remove '### Article' and keep everything else
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.
# New format template - copy and paste the whole function below
def format_single_article(article):
"""Format a SINGLE article for Discord posting (one at a time) - NO TRUNCATION."""
if not article.get('title'):
return None
No suspicious patterns detected.