T09 · Insecure Skill Coding Practices
- Location
skill.py:145- Finding
Untrusted AI Output Controls Unattended Value-Bearing Blockchain Transactions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is openly designed to create prediction markets, but it gives unattended AI output authority to sign blockchain transactions and publish records without enough safeguards.
Install only after review. Use a dedicated low-balance test wallet, do not reuse a primary wallet key, add manual approval before each transaction, validate all LLM output strictly, set spend and rate limits, and avoid cron operation until there is a dry-run or review workflow.
skill.py:145Untrusted AI Output Controls Unattended Value-Bearing Blockchain Transactions
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
params = {"query": query, "count": limit}
try:
response = requests.get(url, headers=headers, params=params, timeout=10)
response.raise_for_status()
data = response.json()
tweets = data.get('tweets', []) or data.get('data', [])
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
params = {"query": query, "count": limit}
try:
response = requests.get(url, headers=headers, params=params, timeout=10)
response.raise_for_status()
data = response.json()
tweets = data.get('tweets', []) or data.get('data', [])
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
}
try:
response = requests.get(url, headers=headers, params=params)
response.raise_for_status()
data = response.json()
image_url = data['results'][0]['urls']['regular'] if data['results'] else ""
This code signs and submits on-chain transactions that open new markets and spend the contract's minimum deposit, creating irreversible external side effects. Because the transaction is driven by automated content collection and LLM-generated output, a mistake, prompt-manipulated input, or malicious trigger can directly cause financial loss and unauthorized market creation.
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
}
try:
resp = requests.post(url, headers=headers, json=data, timeout=10)
resp.raise_for_status()
result = resp.json()
print(f"Bubble registered successfully!")
The dependency pins web3 to version 7.14.1, which is reported as affected by CVE-2026-40072 involving SSRF through CCIP Read / OffchainLookup URL handling. If the skill processes attacker-influenced blockchain responses or contract interactions, this could cause outbound requests to attacker-controlled or internal endpoints, creating a meaningful server-side request forgery risk.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
1. Clone the repository
2. Install dependencies: pip install -r requirements.txt
3. Create .env file with your API keys (see .env.example)
4. Run: python skill.py
The skill loads a blockchain private key and prepares for wallet-controlled actions despite lacking any documented trust boundary, authorization model, or user approval flow. In an agent context, possession of a signing key is highly sensitive because compromise or misuse can directly spend funds and create irreversible on-chain effects.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
UNSPLASH_ACCESS_KEY = os.getenv("UNSPLASH_ACCESS_KEY")
if not all([TWITTERAPI_IO_KEY, ANTHROPIC_API_KEY, RPC_URL, PRIVATE_KEY, UNSPLASH_ACCESS_KEY]):
print("ERROR: Missing keys in .env")
exit(1)
client = Anthropic(api_key=ANTHROPIC_API_KEY)
The skill executes a fund-spending blockchain transaction automatically with no user confirmation, preview, or explicit consent. In an agent setting this is especially dangerous because it allows external data and model output to trigger irreversible financial actions without human review.
The dependency pins python-dotenv to 1.0.0, which is reported as affected by CVE-2026-28684 involving symlink following in set_key that can lead to arbitrary file overwrite. This becomes dangerous if the skill ever writes .env data to a path influenced by an attacker or operates in directories where an attacker can place symlinks.
The dependency pins requests to 2.32.3, which is associated with advisories including a .netrc credential leak via malicious URLs and other unsafe file-handling issues. In an agent skill context, where URLs or remote resources may be influenced by external input, this can expose credentials or enable unsafe local file interactions depending on how the library is used.
The skill explicitly describes automatic blockchain market creation and automatic account registration on an external service, but it does not warn users that running it will trigger real outbound actions affecting third-party systems and potentially on-chain state. This increases the risk of users executing the skill without understanding that it can create accounts, submit transactions, and generate unintended operational or financial consequences.
The documentation instructs users to provide an Ethereum wallet private key in a .env file without clearly warning that this is highly sensitive secret material that grants transaction authority over the wallet. Even though no hardcoded key is present, normalizing private-key entry without handling guidance can lead to credential theft, misuse, accidental commits, or use of an overprivileged wallet.
The skill recommends running on a schedule to continuously create new prediction markets, but it does not warn that unattended execution will repeatedly perform autonomous external actions. In this context, scheduled operation can amplify mistakes, spam third-party platforms, create duplicate or low-quality markets, and repeatedly spend operational resources without human review.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def get_hot_topics(category="crypto", limit=10):
since = (datetime.now() - timedelta(days=2)).strftime("%Y-%m-%d")
query = f"{category} (debate OR controversy OR hot OR trending) min_faves:100 since:{since} filter:has_engagement"
url = "https://api.twitterapi.io/twitter/tweet/advanced_search"
headers = {"x-api-key": TWITTERAPI_IO_KEY}
params = {"query": query, "count": limit}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def get_hot_topics(category="crypto", limit=10):
since = (datetime.now() - timedelta(days=2)).strftime("%Y-%m-%d")
query = f"{category} (debate OR controversy OR hot OR trending) min_faves:100 since:{since} filter:has_engagement"
url = "https://api.twitterapi.io/twitter/tweet/advanced_search"
headers = {"x-api-key": TWITTERAPI_IO_KEY}
params = {"query": query, "count": limit}
The skill sends collected tweet content and recent prediction history to an external LLM service without any disclosure, review, or filtering. While the source data is largely public, this still creates privacy, data-governance, and prompt-injection risks because untrusted content is used to drive later decisions and external actions.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
raise
def get_professional_image(question, category):
url = "https://api.unsplash.com/search/photos"
headers = {"Authorization": f"Client-ID {UNSPLASH_ACCESS_KEY}"}
params = {
"query": f"{category} finance betting prediction market professional illustration",
The code explicitly relies on a public unauthenticated workflow to create remote records. Any party who learns or guesses this endpoint can likely submit arbitrary market registrations, leading to spam, tampering, fraudulent entries, or operational abuse of the downstream system.
The code sends wallet address, market number, generated question, and related metadata to a public external API without any user-facing notice or consent flow. This can leak operational details and bind on-chain activity to an external service unexpectedly.
This line performs external transmission of generated market data to a third-party service that is described as public and unauthenticated. The risk is not mere network use, but the combination of public write access, weak trust boundaries, and sensitive operational metadata being sent off-platform.
}
try:
resp = requests.post(url, headers=headers, json=data, timeout=10)
resp.raise_for_status()
result = resp.json()
print(f"Bubble registered successfully!")
Data derived from untrusted external sources and LLM output is forwarded to a public remote workflow without strong validation or authentication. This creates a confused-deputy style risk where manipulated upstream content can cause unintended record creation, garbage data insertion, or downstream abuse of the public endpoint.
}
try:
resp = requests.post(url, headers=headers, json=data, timeout=10)
resp.raise_for_status()
result = resp.json()
print(f"Bubble registered successfully!")
No suspicious patterns detected.