Back to skill

Security audit

FirstKnow — Portfolio Intelligence

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches its portfolio-alert purpose, but it asks for sensitive financial and messaging credentials, stores them plainly, and sends them to a custom backend with weak disclosure and controls.

Install only if you are comfortable sharing portfolio holdings, Telegram chat details, and a reusable Telegram bot token with the FirstKnow backend. Use a dedicated Telegram bot, rotate the bot token if you uninstall or suspect exposure, avoid reusing sensitive API keys, and verify how backend deletion and retention actually work before relying on it for private financial data.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (8)

other

Error
Location
scripts/register.js:27
Finding

Reusable Telegram Bot Credential Transmitted to a Third-Party Backend

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:122
Finding

Credentials Stored in Plaintext Without Restrictive File Permissions

Content
View full analysis
", "language": "", "timezone": "", "alert_level": "", "quiet_hours": {"start": "00:00", "end": "08:00"}, "delivery": { "method": "telegram", "chatId": "", "botToken": "" }, "api_base_url": "https://firstknow-backend.yuchen-9cf.workers.dev", "onboardingComplete": true } ``` It also duplicates secrets in an environment file: ```text ANTHROPIC_API_KEY= TELEGRAM_BOT_TOKEN= ``` The configuration writer does not specify a restrictive mode: ```javascript export function saveConfig(config) { ensureDataDir(); writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n'); } ``` ### Technical Analysis The Telegram bot token is duplicated in `~/.firstknow/config.json` and `~/.firstknow/.env`. The Anthropic API key is also stored in `.env`. Neither the instructions nor the helper code sets file mode `0600` or directory mode `0700`. The resulting permissions depend on the user's platform and umask. On permissively configured systems, other local users or processes may read these files. General configuration files are also more likely than dedicated secret stores to be copied into backups, diagnostics, indexing services, or support bundles. ### Attack Path 1. The user completes onboarding and the Agent writes the configuration and `.env` files. 2. The files are created using default permissions derived from the environment's umask. 3. Another local process, user, backup agent, or diagnostic tool reads the plaintext files. 4. The attacker extracts the Telegram bot token or Anth ...[truncated 425 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/lib.js:52
Finding

Configurable API Base Can Redirect Credential-Bearing Registration Requests

Content
View full analysis
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
prompts/analyze-impact.md:31
Finding

Untrusted News Content Is Inserted into Model Prompts Without Injection Defenses

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/update-portfolio.js:67
Finding

Portfolio and Settings Updates Lack Client-Side Authentication Evidence

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/handle-deep.js:15
Finding

Deep-Analysis Workflow Imports Missing and Non-Exported Modules

Content
View full analysis
0) { if (remaining.length <= 4096) { chunks.push(remaining); break; } let cut = remaining.lastIndexOf('\n\n', 4096); if (cut < 2000) cut = remaining.lastIndexOf('\n', 4096); if (cut < 2000) cut = 4096; chunks.push(remaining.slice(0, cut)); remaining = remaining.slice(cut).trimStart(); } } ``` No `scripts/analyze.js` file is present in the supplied project, and `deliver.js` does not export `deliverTelegram`. ### Technical Analysis The documented deep-analysis handler cannot load successfully because it imports a missing local module and a named export that is not provided. It also defines `https://api.firstknow.ai` as a fallback, whereas the rest of the project uses the Workers backend. This is primarily an integrity and reliability defect. It becomes security-relevant when users or maintainers attempt to repair the missing functionality by downloadi ...[truncated 896 chars]
Remediation
View remediation

other

Warning
Location
README.md:179
Finding

Privacy Documentation Omits Credential Transfer and Advertises an Unimplemented Deletion Operation

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/package.json:6
Finding

Dependency Installation Is Not Reproducible or Integrity-Pinned

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The manifest advertises portfolio news monitoring, but the body instructs the agent to collect Telegram credentials, store API keys, persist configuration, and register data with a backend. This mismatch can mislead users into authorizing a much more invasive workflow than the description suggests, undermining informed consent and making data exfiltration risks harder to detect.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

Then get the chat ID:

bash
curl -s "https://api.telegram.org/bot<TOKEN>/getUpdates" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result'][0]['message']['chat']['id'])" 2>/dev/null || echo "No messages found — send a message to your bot first"

Step 6: Save Config & Register

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill directs users to provide Telegram bot credentials, chat IDs, portfolio holdings, timezone, and potentially API keys, then stores and transmits them without a clear, prominent warning or consent flow. Because these are sensitive identifiers and secrets, the absence of explicit disclosure makes unauthorized or poorly understood data handling much more dangerous in context.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill instructs the agent to collect the user's Anthropic API key and store it in a local .env file alongside Telegram credentials. Collecting and persisting a powerful secret unrelated to basic alert delivery creates a significant credential-compromise risk if the host, filesystem, logs, or subsequent tools are exposed.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/handle-deep.js (reported line 21)May include surrounding context.

js
const FIRSTKNOW_DIR = join(homedir(), '.firstknow');
const DEFAULT_API_BASE = 'https://api.firstknow.ai';

// Load .env from ~/.firstknow/.env
loadDotenv({ path: join(FIRSTKNOW_DIR, '.env') });

function log(msg) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/handle-deep.js (reported line 22)May include surrounding context.

js
export const DATA_DIR = join(homedir(), '.firstknow');
export const CONFIG_PATH = join(DATA_DIR, 'config.json');
export const PORTFOLIO_PATH = join(DATA_DIR, 'portfolio.json');
export const ENV_PATH = join(DATA_DIR, '.env');

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/lib.js (reported line 13)May include surrounding context.

js
export const DATA_DIR = join(homedir(), '.firstknow');
export const CONFIG_PATH = join(DATA_DIR, 'config.json');
export const PORTFOLIO_PATH = join(DATA_DIR, 'portfolio.json');
export const ENV_PATH = join(DATA_DIR, '.env');

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill invokes shell commands, reads and writes local files, and performs network operations, yet declares no explicit tool scope or permissions boundary. This increases the chance that a host will grant broader capabilities than users expect, making sensitive actions like credential storage and external transmission less transparent and harder to audit.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest description says to use the skill when the user 'wants to set up stock monitoring, check portfolio news, or invokes /firstknow.' The first two conditions are broad natural-language intents rather than narrowly scoped trigger phrases, which increases the chance of unintended invocation during ordinary financial discussion.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill executes a host-platform detection shell command before normal operation, even though that is not necessary to provide portfolio news in a user-facing sense. Unnecessary environment probing expands the skill's behavioral scope and can be repurposed to fingerprint the runtime, enabling tailored misuse or bypasses in different environments.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
81% confidence
Finding

The skill instructs the agent to call the Telegram API with a bot token embedded in the URL to retrieve chat metadata. External transmission to a third-party service is expected for Telegram setup, but doing so with user-provided secrets and no constrained network policy or clear handling guarantees creates a real risk of secret leakage through logs, history, or accidental disclosure.

Content

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

Then get the chat ID:

bash
curl -s "https://api.telegram.org/bot<TOKEN>/getUpdates" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result'][0]['message']['chat']['id'])" 2>/dev/null || echo "No messages found — send a message to your bot first"

Step 6: Save Config & Register

Session Persistence

Medium
Category
Rogue Agent
Confidence
89% confidence
Finding

The skill persists user configuration, portfolio data, and later secrets under ~/.firstknow, creating durable local state beyond the session. Persistent storage of financial preferences and messaging credentials increases the blast radius of any later compromise of the agent environment or shared machine.

Content

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

Save config locally:

bash
mkdir -p ~/.firstknow

Write ~/.firstknow/config.json:

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest focuses on monitoring breaking news, filings, price moves, analyst actions, and providing deep analysis. This section goes further by requiring specific action items such as conditional buy recommendations and probabilistic best/base/worst-case portfolio prescriptions, which materially expands the skill from monitoring/intelligence into investment-advice-style guidance.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The sample alert includes highly personalized portfolio details such as specific holdings, allocation percentages, and price guidance, but it does not warn users about the sensitivity of this financial information or advise safe handling in messaging channels. In a skill designed to push alerts to Telegram 24/7, omission of privacy and data-handling guidance increases the risk of inadvertent exposure of sensitive investment data through screenshots, shared devices, compromised chats, or misconfigured bots.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The prompt explicitly provides the user's full portfolio to the model, which is sensitive financial data and may exceed what is necessary to analyze a single news event. Even if intended for personalization, exposing complete holdings increases privacy and data-minimization risk if the model output, logs, downstream integrations, or prompt history are accessible or retained.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The prompt states that content must be translated 'between English and Chinese' and further requires 'standard Chinese financial terminology,' which hard-codes a language/locale constraint. There is no user opt-in mechanism or documented justification that this skill is intentionally limited to that locale, so it conflicts with the policy against forcing a specific language without opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code sends portfolio-derived ticker symbols to a remote backend API when requesting the latest event. Even though ticker lists are not credentials, they are user portfolio data and can reveal investment interests or holdings patterns; this file performs that transmission without any visible consent, notice, or minimization control. In a financial-monitoring skill, that data is particularly sensitive because it can expose personal investment behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

The script delivers generated deep-analysis content to Telegram, a third-party messaging platform, without any user-facing warning in this file. That content is derived from the user's event context and portfolio, so sending it externally can disclose sensitive financial interests or analysis to another service, especially if chat IDs or Telegram accounts are shared or compromised.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This manifest/config file sets the language to "en" as a default with no indication of user choice, opt-in, or documented regional justification. The policy specifically calls out language or locale constraints as violations when they are imposed without user opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The saveConfig and savePortfolio functions write data to files under the user's home directory, but this file provides no confirmation prompt, user-facing log message, or explanatory comment/docstring disclosing that persistent local files are created or modified. For a shared utility module, these silent writes could affect user data without visible notice from this code.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The apiCall function sends HTTP requests to a remote backend, potentially transmitting user or system data in the request body, but the file contains no user-facing warning, confirmation, or explanatory comment describing this behavior. Because this is a generic utility function, the data transmission is not self-disclosed here.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency uses a caret range instead of an exact pinned version, so installs can drift to newer releases without explicit review. In a security-sensitive skill that handles portfolio intelligence and likely external APIs, this increases supply-chain risk and makes it harder to verify whether vulnerable or breaking versions are being deployed.

Content

Scanner excerpt · scripts/package.json (reported line 7)May include surrounding context.

json
"type": "module",
  "description": "FirstKnow skill scripts — onboarding, deep analysis, portfolio sync",
  "dependencies": {
    "@anthropic-ai/sdk": "^0.39.0",
    "dotenv": "^16.4.7"
  }
}

Unverifiable Dependency: @anthropic-ai/sdk has 2 known advisory(ies) (CVE-2026-34451 (Claude SDK for TypeScript: Memory Tool Path Validation Allows Sandbox Escape to ); CVE-2026-41686 (Claude SDK for TypeScript has Insecure Default File Permissions in Local Filesys)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
81% confidence
Finding

The manifest references @anthropic-ai/sdk without an exact version, and advisories exist for some releases of that package. Because the installed version cannot be verified from this manifest alone, there is a real risk that deployments may resolve to an affected version, which is more concerning here because the skill appears to perform AI-driven analysis and may process files, prompts, or local data.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The dotenv package is also specified with a floating caret range, which allows unreviewed patch/minor updates at install time. Even though dotenv is common and lower risk than more privileged libraries, leaving it unpinned still weakens build reproducibility and increases exposure to supply-chain compromise.

Content

Scanner excerpt · scripts/package.json (reported line 8)May include surrounding context.

json
"description": "FirstKnow skill scripts — onboarding, deep analysis, portfolio sync",
  "dependencies": {
    "@anthropic-ai/sdk": "^0.39.0",
    "dotenv": "^16.4.7"
  }
}

Static analysis

No suspicious patterns detected.