Back to skill

Security audit

Einstein Research — Portfolio Risk Analyzer

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly performs portfolio risk analysis, but it handles sensitive financial data and gives under-disclosed investment action recommendations that should be reviewed before install.

Install only if you are comfortable giving the skill access to your portfolio holdings and having detailed reports saved locally. Use a private working directory, avoid shared or synced report folders, install dependencies in a virtual environment with pinned versions if possible, and treat its action items as informational risk analysis rather than personalized financial advice.

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)

T08 · Insecure Dependencies

Warning
Location
README.md:23
Finding

Unpinned Third-Party Dependencies Create a Supply-Chain Risk

Content
View full analysis

Vulnerability Details

File Location: README.md:23-24; scripts/portfolio_risk.py:34-42
Vulnerability Type: Unpinned and integrity-unverified package installation
Risk Level: Medium

Vulnerable Code

README.md:23-24:

bash
# Install dependencies
pip install yfinance numpy pandas scipy

scripts/portfolio_risk.py:34-42:

python
try:
    import yfinance as yf
except ImportError:
    print("ERROR: yfinance not installed. Run: pip install yfinance numpy pandas scipy")
    sys.exit(1)

try:
    from scipy import stats
except ImportError:
    print("ERROR: scipy not installed. Run: pip install scipy")
    sys.exit(1)

Technical Analysis

The project instructs users to install third-party packages without exact version constraints, cryptographic hashes, a lockfile, or an isolated environment. Consequently, the code that users install and execute may differ from the dependency versions originally tested or audited.

Python packages can execute code during installation and whenever imported. If a dependency release, maintainer account, package distribution channel, or transitive dependency is compromised, following the documented installation command could introduce attacker-controlled code. Even without malicious interference, unconstrained dependency upgrades may alter APIs or numerical behavior and undermine the integrity of financial calculations.

The package names shown are established packages rather than apparent typosquatting attempts, and no malicious dependency is present in the audited repository. The vulnerability is the absence of version and integrity controls.

Attack Path

  1. An attacker compromises a listed dependency, one of its transitive dependencies, or its package-publishing account.
  2. The attacker publishes a malicious version under the legitimate package name.
  3. A user follows the documented unconstrained pip install command.
  4. Package ...[truncated 703 chars]
Remediation
View remediation

Remediation Suggestions

  1. Add a reviewed dependency manifest with exact versions, such as requirements.txt or pyproject.toml with a generated lockfile.

  2. Pin direct and transitive dependencies to tested versions.

  3. Record cryptographic hashes and install with integrity enforcement, for example:

    bash
    python3 -m pip install --require-hashes -r requirements.txt
    
  4. Recommend installation inside a dedicated virtual environment rather than into the system Python environment.

  5. Use automated dependency vulnerability and provenance scanning in continuous integration.

  6. Review and deliberately update the lockfile instead of resolving unrestricted latest versions during installation.

  7. Remove ad hoc installation commands from runtime error messages and direct users to the locked installation procedure.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/portfolio_risk.py:789
Finding

Portfolio Reports Are Written Without Explicit Confidentiality or Symlink Protections

Content
View full analysis

Vulnerability Details

File Location: scripts/portfolio_risk.py:789-801
Vulnerability Type: Insecure handling of sensitive output files
Risk Level: Low

Vulnerable Code

python
# 13. Write outputs
os.makedirs(args.output_dir, exist_ok=True)
file_ts = datetime.now().strftime("%Y%m%d_%H%M%S")

json_path = os.path.join(args.output_dir, f"portfolio_risk_{file_ts}.json")
md_path = os.path.join(args.output_dir, f"portfolio_risk_{file_ts}.md")

with open(json_path, "w") as f:
    json.dump(report, f, indent=2, default=str)

md_report = format_markdown_report(report)
with open(md_path, "w") as f:
    f.write(md_report)

Technical Analysis

Generated reports contain financial information such as total portfolio value, ticker holdings, position weights, current prices, risk contributions, and estimated crisis losses. The output directory and files are created using the process umask and default filesystem permissions rather than explicit restrictive modes.

On a shared system with a permissive umask, reports may be readable by other local users. In addition, open(path, "w") follows symbolic links and truncates an existing destination. The timestamp-based filenames are predictable to the second. If an attacker can write to the selected output directory, the attacker could pre-create a matching symbolic link and cause the process to overwrite another file writable by the victim account.

Exploitation depends on local access to the output directory or permissive file permissions. The default relative reports directory will often be inside a user-controlled workspace, which limits practical exposure, but the command-line option permits selection of shared or untrusted directories.

Attack Path

Confidentiality path:

  1. The analyzer is run on a multi-user system with a permissive umask or in a shared output directory.
  2. JSON and Markdown reports are created with permissions that permit ...[truncated 1018 chars]
Remediation
View remediation

Remediation Suggestions

  1. Create the report directory with owner-only permissions and verify existing directory ownership and mode:

    python
    os.makedirs(args.output_dir, mode=0o700, exist_ok=True)
    
  2. Create report files with mode 0600 using os.open rather than relying on the process umask.

  3. Use O_EXCL to prevent overwriting existing destinations and O_NOFOLLOW where supported to reject symbolic links.

  4. Write through a securely created temporary file in the same directory, flush and synchronize it, and atomically rename it to the final destination.

  5. Reject output directories that are symbolic links, unexpectedly shared, or writable by untrusted users.

  6. Consider adding a cryptographically random filename component rather than relying only on a timestamp.

  7. Document that generated reports contain sensitive financial data and should not be stored in public repositories or shared directories.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (6)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The implicit triggers are broad and subjective, such as any user concern about downturns or asset allocation review, which can cause the skill to activate outside clearly expressed user intent. Overbroad activation can lead to unnecessary processing of sensitive portfolio data, tool invocation, or misleading workflow selection when a simpler informational response was intended.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill goes beyond descriptive risk analysis and generates prescriptive investment actions such as 'Go to 100% cash,' 'Reduce 50% of positions,' 'consider protective puts,' and hedge recommendations. In an agent setting, these recommendations can be surfaced as authoritative financial advice without suitability checks, compliance controls, or user risk profiling, creating a meaningful risk of harmful or inappropriate portfolio actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script writes detailed portfolio data, including holdings, weights, prices, valuations, and risk metrics, to JSON and Markdown files in a local reports directory by default. If the environment is shared, synced, backed up, or exposed through agent artifacts/logs, this can leak sensitive financial information without user awareness or consent.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.