Back to skill

Security audit

Agresource

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it ships plaintext fallback credentials for an AgResource account and persistently stores authenticated newsletter content locally.

Do not install this version unless the embedded AgResource password has been removed, rotated, and invalidated everywhere it was distributed. If used after remediation, provide credentials only through a protected secret mechanism, confirm that local storage of subscribed newsletter content is acceptable, and review or disable screenshots, raw-content files, sentiment history, cron use, and any Telegram alert 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

Error
Location
scraper.js:15
Finding

Hardcoded AgResource Account Credentials in Scraper

Content
View full analysis

Vulnerability Details

File Location: scraper.js:15-16
Vulnerability Type: Hardcoded credentials and insecure secret management
Risk Level: High

Vulnerable Code

js
const AGRESOURCE_EMAIL = process.env.AGRESOURCE_EMAIL || 'brianppetty@yahoo.com';
const AGRESOURCE_PASSWORD = process.env.AGRESOURCE_PASSWORD || '4BrynnElizabeth';

The embedded credentials are later entered into the AgResource login form at scraper.js:123-129:

js
const emailField = await page.locator('input[type="email"], input[name="email"], #email').first();
await emailField.fill(AGRESOURCE_EMAIL);
await page.waitForTimeout(500);

// Find and fill password field
const passwordField = await page.locator('input[type="password"], input[name="password"], #password').first();
await passwordField.fill(AGRESOURCE_PASSWORD);

Technical Analysis

The scraper uses environment variables when available but silently falls back to a plaintext account email and password embedded in source code. Consequently, anyone with read access to the source package, repository history, backups, build artifacts, or distributed Skill archive can recover the credentials without executing the code.

This implementation contradicts the environment-only credential handling described in SKILL.md. The fallback also causes the scraper to authenticate as the embedded account whenever the expected environment variables are absent, which can lead to unintended account use in copied or redistributed deployments.

The hardcoded values must be treated as compromised because removing them from the current files does not remove them from existing archives or version-control history.

Attack Path

  1. An attacker obtains read access to the Skill package, source repository, build artifact, backup, or source mirror.
  2. The attacker opens scraper.js and extracts the plaintext email address and password from lines 15-16.
  3. The attacker submits those credentials directly to the AgResource authent ...[truncated 1019 chars]
Remediation
View remediation

Remediation Suggestions

  1. Immediately rotate the exposed password and invalidate all active sessions associated with the account.
  2. Remove all plaintext fallback credentials and require secret injection:
js
const AGRESOURCE_EMAIL = process.env.AGRESOURCE_EMAIL;
const AGRESOURCE_PASSWORD = process.env.AGRESOURCE_PASSWORD;

if (!AGRESOURCE_EMAIL || !AGRESOURCE_PASSWORD) {
  throw new Error(
    'AGRESOURCE_EMAIL and AGRESOURCE_PASSWORD environment variables are required'
  );
}
  1. Store credentials in a managed secret service or inject them through protected runtime environment variables.
  2. Remove the credentials from version-control history, release archives, backups, mirrors, and previously distributed Skill packages where feasible.
  3. Add automated secret scanning to pre-commit, CI, and release workflows.
  4. Use a dedicated least-privilege service account if the external platform supports one.
  5. Ensure error messages and diagnostic logs never print credential values.
  6. Consider enabling multi-factor authentication and monitoring the account for unauthorized access.

T09 · Insecure Skill Coding Practices

Error
Location
historical_scraper.js:16
Finding

Hardcoded AgResource Account Credentials in Historical Scraper

Content
View full analysis

Vulnerability Details

File Location: historical_scraper.js:16-17
Vulnerability Type: Hardcoded credentials and insecure secret management
Risk Level: High

Vulnerable Code

js
const AGRESOURCE_EMAIL = process.env.AGRESOURCE_EMAIL || 'brianppetty@yahoo.com';
const AGRESOURCE_PASSWORD = process.env.AGRESOURCE_PASSWORD || '4BrynnElizabeth';

The historical scraper later enters these values into the login page at historical_scraper.js:208-211:

js
await page.locator('input[type="email"], #email').first().fill(AGRESOURCE_EMAIL);
await page.waitForTimeout(500);
await page.locator('input[type="password"], #password').first().fill(AGRESOURCE_PASSWORD);
await page.waitForTimeout(500);

Technical Analysis

The historical scraper independently duplicates the same plaintext credential fallback found in the primary scraper. Environment variables therefore do not provide meaningful secret isolation: whenever they are missing, the program automatically authenticates with credentials exposed in its source.

Duplication increases the chance that remediation will be incomplete. Correcting only the primary scraper would leave the secret recoverable and operational in this file. Source readers can retrieve the password statically, while running the script without environment configuration causes unintended authentication as the embedded user.

Because the secret has been distributed as source code, it must be considered compromised even if the fallback is subsequently removed.

Attack Path

  1. An attacker obtains the project source, a packaged Skill, repository history, a backup, or a mirror.
  2. The attacker inspects historical_scraper.js:16-17.
  3. The attacker copies the embedded email address and password.
  4. The attacker authenticates directly to the AgResource service using those credentials.
  5. If valid, the attacker accesses resources and functionality available to the affected account.
  6. Alternatively, a person running this sc ...[truncated 703 chars]
Remediation
View remediation

Remediation Suggestions

  1. Rotate the exposed password immediately and revoke existing sessions.
  2. Delete both plaintext fallback values and fail closed when credentials are unavailable:
js
const AGRESOURCE_EMAIL = process.env.AGRESOURCE_EMAIL;
const AGRESOURCE_PASSWORD = process.env.AGRESOURCE_PASSWORD;

if (!AGRESOURCE_EMAIL || !AGRESOURCE_PASSWORD) {
  throw new Error(
    'AGRESOURCE_EMAIL and AGRESOURCE_PASSWORD environment variables are required'
  );
}
  1. Centralize credential loading in one validated configuration module so all scrapers follow the same policy.
  2. Provision credentials through a protected secret manager or runtime secret injection mechanism.
  3. Purge the exposed values from repository history and distributed artifacts.
  4. Add secret-scanning controls to prevent future commits and releases containing passwords.
  5. Use a dedicated account with only the permissions required to read newsletters.
  6. Enable available multi-factor authentication, access alerts, and account activity monitoring.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (15)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 7)May include surrounding context.

md
- **Scraper:** `scraper.js` (Playwright/Node.js)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script embeds fallback login credentials directly in code, including a plaintext password. This creates an immediate secret exposure risk: anyone with access to the file can use the account, and the scraper gains authenticated access beyond a simple public scraping role. In this skill context, the capability is especially risky because it automates login to a remote paid/private service and then stores retrieved content locally.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
100% confidence
Finding

The script contains hardcoded fallback credentials for an authenticated third-party service, including a plaintext password. If the code is shared, logged, or reused in another environment, anyone with access to the source can impersonate the account and access subscribed or private newsletter content; the skill context makes this especially dangerous because it automates authenticated access to proprietary data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explicitly states it will use stored credentials and persist scraped newsletter summaries to a user directory, but it does not clearly warn the user about privacy, retention, or where sensitive content may be stored. This creates a real data-handling risk because proprietary newsletter content and account-linked access can be used or retained without informed user consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill says it will send Telegram alerts based on newsletter content but does not clearly warn that derived information is transmitted to an external messaging platform. Even if only summaries are sent, this can expose proprietary trading-relevant information or user activity to a third party without explicit consent.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The top-level comment claims newsletters are scraped once to avoid duplicates, implying persistent deduplication. In reality, deduplication is implemented only with an in-memory Set for the current execution, while the code always writes output files based on date and never checks existing saved newsletters before scraping or overwriting them.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script silently consumes and submits account credentials to a remote site without any explicit user-facing disclosure or consent checkpoint. In an agent skill context, this matters because a user or operator may not realize the skill performs authenticated actions on their behalf, increasing the risk of unintended account use and policy violations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The scraper fetches content from a remote authenticated service and stores the results locally, but it does not clearly warn the user that account data will be retrieved and persisted. In this context, that increases risk because the content may be proprietary, sensitive, or subject to licensing restrictions, and silent collection/storage reduces informed user control.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The top-level doc comment describes a scraper that logs in and extracts newsletter content. However, later code analyzes market sentiment, stores sentiment history, and generates daily/weekly/monthly summary JSON artifacts, which is a materially broader function than simple scraping.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The scraper saves a full-page screenshot of authenticated content to local disk, which may capture proprietary reports, account details, or other sensitive information beyond the intended extracted text. In this skill, the content is accessed after login and stored under a persistent user-home directory, increasing the chance of unintended disclosure to other local users, backup systems, or later processes.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The inline comments indicate separate extraction of CBOT grain prices and speculative/fund positioning. Yet the returned object sets 'positions' to 'grainPrices' rather than the extracted speculative positioning, contradicting the documented intent of that field and potentially misleading downstream consumers.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code persistently writes scraped newsletter content and summaries to markdown files in the user's home directory without notice or data-minimization controls. Because the source material is authenticated and potentially proprietary, local persistence can create a secondary copy that is easier to leak via backups, multi-user access, endpoint compromise, or accidental sharing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code accesses persisted user data under ~/clawd/memory/agresource/sentiment_history.json and later reads it to influence analysis results. There is no confirmation prompt, user-facing log/print, or warning in the file docstring indicating that local historical data from the user's home directory will be consulted.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script writes both a markdown summary and raw content text files into a directory under the user's home folder. Although it logs filenames after saving, there is no prior warning or documentation that potentially sensitive subscribed content will be persisted locally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

Persistently storing sentiment history and derived summary files creates a durable behavioral dataset that may reveal proprietary market signals or user activity patterns over time. The derived data is less sensitive than raw scraped content, but it still expands the data footprint and can aid reconstruction of private analysis if exposed.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.