Back to skill

Security audit

OpenSETI

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real distributed SETI scanner, but it needs Review because it lets a remote coordinator direct network downloads and sends wallet/API/result data with limited disclosure.

Review before installing or running. This skill will contact a coordinator, store your wallet address locally, send your wallet and scan results over the network, and may run continuously if you choose that mode. Only use it if you trust the coordinator operator and are comfortable with wallet-linked activity; prefer a sandboxed environment and avoid custom coordinator URLs unless you control and trust them.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/openseti.py:301
Finding

Coordinator-Controlled Arbitrary URL Fetch Enables SSRF and Resource Exhaustion

Content
View full analysis

Vulnerability Details

File Location: scripts/openseti.py:301-311, called from scripts/openseti.py:407
Vulnerability Type: Server-Side Request Forgery from the client host, unrestricted outbound request, and unbounded download
Risk Level: High

Vulnerable Code

python
def download_work_unit(download_url):
    """Download work unit data"""
    try:
        # Handle relative URLs
        if download_url.startswith('/'):
            url = f"{COORDINATOR_URL}{download_url}"
        else:
            url = download_url
        
        res = requests.get(url, timeout=60)
        res.raise_for_status()
        return res.content
    except Exception as e:
        print(f"❌ Error downloading: {e}")
        return None

The function is reached using a URL supplied in the coordinator response:

python
data = download_work_unit(work['download_url'])

Technical Analysis

The coordinator controls work['download_url']. Absolute URLs are accepted without validating their scheme, hostname, resolved IP address, port, or destination network. The requests library also follows HTTP redirects by default, so validating only the initial string would not be sufficient.

A malicious or compromised coordinator could instruct the scanner to request:

  • Loopback services such as http://127.0.0.1:...
  • Private-network services on RFC1918 addresses
  • Link-local services, including cloud instance metadata endpoints
  • Unexpected non-coordinator Internet hosts
  • Extremely large responses intended to consume memory or bandwidth

The function uses res.content, which buffers the entire response in memory. The 60-second timeout limits request duration but does not impose a response-size limit. The downloaded content is not executed, which reduces the risk of remote code execution, but it is subsequently parsed and processed with NumPy.

This network authority exceeds the minimum privilege required to download radio-telescope work units from ...[truncated 1382 chars]

Remediation
View remediation

Remediation Suggestions

  1. Permit downloads only from an explicit allowlist of trusted HTTPS hostnames.
  2. Reject URLs containing credentials, non-HTTPS schemes, unexpected ports, or malformed hostnames.
  3. Resolve the hostname and reject loopback, private, link-local, multicast, reserved, and cloud metadata address ranges for both IPv4 and IPv6.
  4. Disable redirects with allow_redirects=False, or validate the destination after every redirect.
  5. Stream responses using stream=True and enforce a strict maximum size before buffering or analysis.
  6. Validate Content-Length when available, while still enforcing the limit during streaming.
  7. Apply separate connection and read timeouts.
  8. Prefer coordinator-relative, cryptographically authenticated work-unit identifiers rather than arbitrary URLs.
  9. Verify downloaded work units using a coordinator-provided hash and expected size.

Example defensive design:

python
res = requests.get(
    validated_url,
    timeout=(10, 30),
    allow_redirects=False,
    stream=True,
)

maximum_size = 2 * 1024 * 1024
data = bytearray()

for chunk in res.iter_content(chunk_size=65536):
    data.extend(chunk)
    if len(data) > maximum_size:
        raise ValueError("Work unit exceeds the permitted size")

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/openseti.py:26
Finding

Hardcoded Shared Coordinator API Credential

Content
View full analysis

Vulnerability Details

File Location: scripts/openseti.py:26, used at scripts/openseti.py:287-290 and scripts/openseti.py:320-331
Vulnerability Type: Hardcoded credential and ineffective shared-client authentication
Risk Level: Medium

Vulnerable Code

python
API_KEY = os.environ.get('OpenSETI_API_KEY', 'openseti_coordinator_v1_x8k3m2n7')

The embedded value is transmitted when requesting work:

python
res = requests.post(
    f"{COORDINATOR_URL}/api/work",
    json={'wallet': wallet, 'api_key': API_KEY},
    timeout=30
)

It is also transmitted when submitting results:

python
res = requests.post(
    f"{COORDINATOR_URL}/api/submit",
    json={
        'wallet': wallet,
        'api_key': API_KEY,
        'work_id': work_id,
        'anomaly_score': result['anomaly_score'],
        'classification': result['classification'],
        'detection_reasons': result['detection_reasons'],
        'processing_time_ms': result['processing_time_ms']
    },
    timeout=30
)

Technical Analysis

The default API key is embedded directly in distributed source code. Anyone who can inspect the Skill can recover and reuse it. An environment-variable override does not protect the published default value.

Because every default installation uses the same key, it cannot establish the identity of an individual client. If the coordinator relies on it for authorization, attackers can reproduce authorized requests outside the scanner. Combining the shared key with an arbitrary wallet address may permit forged work requests or fabricated result submissions, depending on server-side validation.

The scanner also sends the user's wallet address to the coordinator during registration, work retrieval, and result submission. Sending a wallet identifier is consistent with the declared token-reward functionality, but the documentation should clearly disclose that the coordinator can correlate the wallet with the user's IP address and ...[truncated 1131 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the embedded default credential and rotate or revoke the published key.
  2. Fail safely when no credential is configured rather than falling back to a shared secret.
  3. Issue unique, short-lived credentials after authenticated registration.
  4. Bind credentials to a specific account or wallet and support expiration and revocation.
  5. For wallet-based identity, use a nonce challenge signed by the wallet and verify the signature server-side.
  6. Validate that each submitted work ID was assigned to the authenticated client.
  7. Recompute or independently verify submitted analysis where rewards are involved.
  8. Apply rate limits and abuse monitoring per client, wallet, and source address.
  9. Store any issued local token with restrictive filesystem permissions.
  10. Document the coordinator operator, transmitted fields, retention policy, and wallet/IP correlation implications.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:68
Finding

Unpinned Runtime Dependencies Create Supply-Chain and Reproducibility Risk

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:68
Vulnerability Type: Unpinned third-party dependency installation
Risk Level: Medium

Vulnerable Code

bash
pip install numpy scipy requests

Technical Analysis

The installation instructions resolve mutable package versions from pip's configured package index. No version constraints, hashes, lockfile, isolated environment, or trusted index are specified.

The listed package names are established packages and there is no evidence in the audited project that they are intentionally malicious. However, an unpinned installation is not reproducible and may retrieve future releases that have not been reviewed with the Skill. Package installation may execute build-backend or installation logic under the invoking user's privileges.

The absence of dependency integrity controls also makes it harder to determine which versions were used when investigating a security incident or compatibility failure.

Attack Path

  1. A user follows the documented requirements and runs the supplied pip command.
  2. Pip resolves the latest available versions from its configured package source.
  3. A compromised package release, compromised package index, or unsafe index configuration supplies altered package content.
  4. Package build or installation logic executes with the user's permissions.
  5. The altered dependency can subsequently execute whenever the scanner imports requests or numpy.

This is a supply-chain exposure rather than evidence that the named dependencies are currently compromised.

Impact Assessment

A compromised dependency could execute code with the privileges of the user installing or running the scanner. This could affect local files, environment-accessible secrets, network activity, and scanner results. More commonly, uncontrolled version changes can produce incompatible or non-reproducible behavior. No direct privilege escalation beyond the invoking user's permissio ...[truncated 38 chars]

Remediation
View remediation

Remediation Suggestions

  1. Define reviewed dependency versions in a requirements or lock file.
  2. Include cryptographic hashes and install with pip install --require-hashes.
  3. Use a dedicated virtual environment rather than the system Python environment.
  4. Document the approved package index and avoid untrusted extra indexes.
  5. Add automated dependency vulnerability and provenance scanning.
  6. Review and deliberately update pinned versions on a controlled schedule.
  7. Where practical, use binary wheels from trusted sources and prohibit unexpected source builds.

Example documentation:

bash
python -m venv .venv
. .venv/bin/activate
python -m pip install --require-hashes -r requirements.txt
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • 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 (14)

Tainted flow: 'COORDINATOR_URL' from os.environ.get (line 25, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/openseti.py (reported line 264)May include surrounding context.

python
print(f"🛸 Registering wallet: {wallet[:8]}...{wallet[-4:]}")
    
    try:
        res = requests.post(
            f"{COORDINATOR_URL}/api/register",
            json={'wallet': wallet},
            timeout=30

Tainted flow: 'COORDINATOR_URL' from os.environ.get (line 25, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
98% confidence
Finding

The client sends both the user's wallet and an API key to a coordinator URL that can be overridden via the environment. If an attacker controls OpenSETI_COORDINATOR, they can redirect the client to an arbitrary server and harvest identifiers and credentials, and also feed back untrusted work metadata used later in the workflow.

Content

Scanner excerpt · scripts/openseti.py (reported line 287)May include surrounding context.

python
def get_work(wallet):
    """Request a work unit from coordinator"""
    try:
        res = requests.post(
            f"{COORDINATOR_URL}/api/work",
            json={'wallet': wallet, 'api_key': API_KEY},
            timeout=30

Tainted flow: 'url' from os.environ.get (line 306, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
99% confidence
Finding

The download URL comes from untrusted coordinator-controlled data and is fetched without origin validation. This creates an SSRF-style primitive and arbitrary outbound request capability, allowing a malicious coordinator to make the client connect to attacker-chosen hosts, including internal services, and potentially download extremely large or malicious payloads for resource exhaustion.

Content

Scanner excerpt · scripts/openseti.py (reported line 310)May include surrounding context.

python
else:
            url = download_url
        
        res = requests.get(url, timeout=60)
        res.raise_for_status()
        return res.content
    except Exception as e:

Tainted flow: 'COORDINATOR_URL' from os.environ.get (line 25, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
97% confidence
Finding

Results are submitted, along with wallet and API key, to a coordinator URL sourced from the environment. If that URL is attacker-controlled, the client will exfiltrate contributor identifiers, embedded credentials, and behavioral data to an arbitrary remote endpoint.

Content

Scanner excerpt · scripts/openseti.py (reported line 320)May include surrounding context.

python
def submit_result(wallet, work_id, result):
    """Submit analysis result"""
    try:
        res = requests.post(
            f"{COORDINATOR_URL}/api/submit",
            json={
                'wallet': wallet,

Tainted flow: 'COORDINATOR_URL' from os.environ.get (line 25, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/openseti.py (reported line 341)May include surrounding context.

python
def get_stats(wallet):
    """Get contributor stats"""
    try:
        res = requests.get(f"{COORDINATOR_URL}/api/stats", timeout=10)
        return res.json()
    except Exception as e:
        return {'error': str(e)}

Tainted flow: 'COORDINATOR_URL' from os.environ.get (line 25, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/openseti.py (reported line 349)May include surrounding context.

python
def get_leaderboard():
    """Get leaderboard"""
    try:
        res = requests.get(f"{COORDINATOR_URL}/api/leaderboard", timeout=10)
        return res.json()
    except Exception as e:
        return {'error': str(e)}

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented purpose is benign scientific scanning, but the behavior described by analysis includes undisclosed external coordinator access, wallet/token interaction, arbitrary remote-provided work units, and embedded credential use. A skill that fetches tasks from a remote service and executes analysis on them without transparent boundaries can be repurposed for data exfiltration, abuse of local resources, or covert participation in an untrusted network.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill advertises commands that imply network access, local execution, and likely local state changes, but it declares no explicit tool scope or permissions. That mismatch prevents informed consent and weakens containment, making it easier for a skill to access the network or modify files without clear disclosure to the user or platform.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill instructs users to register a Solana wallet and submit scan results to a network, but it does not warn that this creates outbound transmissions and on-chain association of activity with a wallet. That omission creates privacy and consent risks, especially because continuous scanning suggests persistent network communication and potentially long-lived tracking of contributions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

A hardcoded default API key is embedded in the client and automatically transmitted in coordinator requests. Embedded credentials are easily recoverable, cannot be meaningfully kept secret once distributed, and encourage silent credential reuse against whatever endpoint the client is pointed at.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/openseti.py (reported line 264)May include surrounding context.

python
print(f"🛸 Registering wallet: {wallet[:8]}...{wallet[-4:]}")
    
    try:
        res = requests.post(
            f"{COORDINATOR_URL}/api/register",
            json={'wallet': wallet},
            timeout=30

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

This request transmits wallet and API key to the coordinator to obtain work units. In the context of an environment-overridable backend and a bundled credential, that transmission becomes dangerous because it can leak credentials and user identifiers to attacker-controlled infrastructure.

Content

Scanner excerpt · scripts/openseti.py (reported line 287)May include surrounding context.

python
def get_work(wallet):
    """Request a work unit from coordinator"""
    try:
        res = requests.post(
            f"{COORDINATOR_URL}/api/work",
            json={'wallet': wallet, 'api_key': API_KEY},
            timeout=30

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

This submission sends wallet, API key, work ID, and analysis metadata externally. Given the trust issues in this client, that creates a practical exfiltration path to any attacker-controlled coordinator and can expose contributor identity and reusable service credentials.

Content

Scanner excerpt · scripts/openseti.py (reported line 320)May include surrounding context.

python
def submit_result(wallet, work_id, result):
    """Submit analysis result"""
    try:
        res = requests.post(
            f"{COORDINATOR_URL}/api/submit",
            json={
                'wallet': wallet,

Tainted flow: 'result' from requests.post (line 420, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/openseti.py (reported line 320)May include surrounding context.

python
def submit_result(wallet, work_id, result):
    """Submit analysis result"""
    try:
        res = requests.post(
            f"{COORDINATOR_URL}/api/submit",
            json={
                'wallet': wallet,

Static analysis

No suspicious patterns detected.