Fulcra Sleep Detective

Security checks across malware telemetry and agentic risk

Overview

This skill is not clearly malicious, but it asks an agent to collect and remember very sensitive health and calendar context automatically, with limited user-control guidance.

Review this before installing if you are comfortable giving an agent access to Fulcra health data, calendar context, and persistent health memory. Use it only in a private, trusted environment; avoid group/public channels; set a fixed trusted Fulcra CLI command; and define your own retention, deletion, and opt-in rules for calendar, CGM, nutrition, and conversation-derived health notes.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (31)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
from fulcra_api.core import FulcraAPI
    client = FulcraAPI()
    cli = shlex.split(os.environ.get("FULCRA_CLI_COMMAND", "uv tool run fulcra-api"))
    proc = subprocess.run(
        [*cli, "auth", "print-access-token"],
        capture_output=True,
        text=True,
Confidence
94% confidence
Finding
proc = subprocess.run( [*cli, "auth", "print-access-token"], capture_output=True, text=True, check=False, timeout=30, )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
from fulcra_api.core import FulcraAPI
    api = FulcraAPI()
    cli = shlex.split(os.environ.get("FULCRA_CLI_COMMAND", "uv tool run fulcra-api"))
    proc = subprocess.run(
        [*cli, "auth", "print-access-token"],
        capture_output=True,
        text=True,
Confidence
95% confidence
Finding
proc = subprocess.run( [*cli, "auth", "print-access-token"], capture_output=True, text=True, check=False, timeout=30, )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
from fulcra_api.core import FulcraAPI
    client = FulcraAPI()
    cli = shlex.split(os.environ.get("FULCRA_CLI_COMMAND", "uv tool run fulcra-api"))
    proc = subprocess.run(
        [*cli, "auth", "print-access-token"],
        capture_output=True,
        text=True,
Confidence
96% confidence
Finding
proc = subprocess.run( [*cli, "auth", "print-access-token"], capture_output=True, text=True, check=False, timeout=30, )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
from fulcra_api.core import FulcraAPI
    api = FulcraAPI()
    cli = shlex.split(os.environ.get("FULCRA_CLI_COMMAND", "uv tool run fulcra-api"))
    proc = subprocess.run(
        [*cli, "auth", "print-access-token"],
        capture_output=True,
        text=True,
Confidence
96% confidence
Finding
proc = subprocess.run( [*cli, "auth", "print-access-token"], capture_output=True, text=True, check=False, timeout=30, )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
from fulcra_api.core import FulcraAPI
    api = FulcraAPI()
    cli = shlex.split(os.environ.get("FULCRA_CLI_COMMAND", "uv tool run fulcra-api"))
    proc = subprocess.run(
        [*cli, "auth", "print-access-token"],
        capture_output=True,
        text=True,
Confidence
97% confidence
Finding
proc = subprocess.run( [*cli, "auth", "print-access-token"], capture_output=True, text=True, check=False, timeout=30, )

Tainted flow: 'cli' from os.environ.get (line 65, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
from fulcra_api.core import FulcraAPI
    client = FulcraAPI()
    cli = shlex.split(os.environ.get("FULCRA_CLI_COMMAND", "uv tool run fulcra-api"))
    proc = subprocess.run(
        [*cli, "auth", "print-access-token"],
        capture_output=True,
        text=True,
Confidence
97% confidence
Finding
proc = subprocess.run( [*cli, "auth", "print-access-token"], capture_output=True, text=True, check=False, timeout=30, )

Tainted flow: 'cli' from os.environ.get (line 154, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
from fulcra_api.core import FulcraAPI
    api = FulcraAPI()
    cli = shlex.split(os.environ.get("FULCRA_CLI_COMMAND", "uv tool run fulcra-api"))
    proc = subprocess.run(
        [*cli, "auth", "print-access-token"],
        capture_output=True,
        text=True,
Confidence
98% confidence
Finding
proc = subprocess.run( [*cli, "auth", "print-access-token"], capture_output=True, text=True, check=False, timeout=30, )

Tainted flow: 'STATE_PATH' from os.environ.get (line 50, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
def save_state(state):
    """Persist current state for next run's change detection."""
    os.makedirs(os.path.dirname(STATE_PATH), exist_ok=True)
    with open(STATE_PATH, 'w') as f:
        json.dump(state, f, indent=2, default=str)

def diff_insights(current_output, last_state):
Confidence
86% confidence
Finding
with open(STATE_PATH, 'w') as f:

Tainted flow: 'cli' from os.environ.get (line 93, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
from fulcra_api.core import FulcraAPI
    client = FulcraAPI()
    cli = shlex.split(os.environ.get("FULCRA_CLI_COMMAND", "uv tool run fulcra-api"))
    proc = subprocess.run(
        [*cli, "auth", "print-access-token"],
        capture_output=True,
        text=True,
Confidence
98% confidence
Finding
proc = subprocess.run( [*cli, "auth", "print-access-token"], capture_output=True, text=True, check=False, timeout=30, )

Tainted flow: 'cli' from os.environ.get (line 55, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
from fulcra_api.core import FulcraAPI
    api = FulcraAPI()
    cli = shlex.split(os.environ.get("FULCRA_CLI_COMMAND", "uv tool run fulcra-api"))
    proc = subprocess.run(
        [*cli, "auth", "print-access-token"],
        capture_output=True,
        text=True,
Confidence
98% confidence
Finding
proc = subprocess.run( [*cli, "auth", "print-access-token"], capture_output=True, text=True, check=False, timeout=30, )

Tainted flow: 'cli' from os.environ.get (line 32, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
from fulcra_api.core import FulcraAPI
    api = FulcraAPI()
    cli = shlex.split(os.environ.get("FULCRA_CLI_COMMAND", "uv tool run fulcra-api"))
    proc = subprocess.run(
        [*cli, "auth", "print-access-token"],
        capture_output=True,
        text=True,
Confidence
99% confidence
Finding
proc = subprocess.run( [*cli, "auth", "print-access-token"], capture_output=True, text=True, check=False, timeout=30, )

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill advertises no declared permissions while its described operation depends on shell access, environment access, and file read/write behavior. That mismatch prevents meaningful user consent and review, and is especially risky here because the skill handles highly sensitive health, biometric, calendar, and authentication-adjacent data.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The documented purpose is narrow sleep analysis, but the behavior expands into broad health monitoring, calendar ingestion, user profile/timezone retrieval, local persistence, and raw context dumping for LLM consumption. This creates a material transparency and scope-consent failure: users may authorize a sleep tool without realizing it collects and processes much wider sensitive personal data.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The script intentionally aggregates far more data than is necessary for a sleep-focused skill, including glucose, nutrition, workouts, steps, active energy, and calendar context. That over-collection materially increases privacy risk and the blast radius of any compromise, especially because the output is designed for downstream LLM reasoning and may be logged, stored, or forwarded.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
Calendar extraction exposes event titles, attendee presence, recurrence, and locations, which can reveal sensitive personal or business information unrelated to sleep. In the context of a health-analysis skill, this cross-domain enrichment is especially risky because it combines private health data with schedule metadata that can identify habits, employers, travel, or meetings.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The skill's implemented behavior expands well beyond sleep investigation into broad surveillance of nutrition, meetings, workouts, steps, HR/HRV, and persistent cross-run tracking. In this context, overcollection materially increases privacy risk because highly sensitive health and calendar data is aggregated and retained without clear necessity to the stated purpose.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
The code launches an external CLI to mint or retrieve an access token despite the skill being framed as a sleep-analysis tool. That capability broadens the attack surface and creates a credential-handling path that can be subverted, especially because the executable is environment-configurable.

Description-Behavior Mismatch

Medium
Confidence
85% confidence
Finding
The skill is presented as a sleep investigation tool, but the code broadens collection and analysis into HRV, blood glucose, nutrition, workouts, and calendar context. This scope expansion increases privacy risk and data sensitivity beyond the user’s likely expectation, which is especially concerning in a health-focused agent skill.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
The script accesses blood glucose and nutrition data and uses them for proactive alerts without a clear necessity for the stated sleep-analysis function. These categories are highly sensitive health data, so collecting and correlating them with calendar events materially increases privacy and profiling risk.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
A low-level timezone utility unexpectedly spawns an external CLI and retrieves authentication tokens as part of normal operation. This broadens the trust boundary and means innocuous-looking imports can trigger credential-handling behavior, increasing the chance of misuse, hidden side effects, and credential exposure in a widely reused helper.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README explicitly promotes correlation of highly sensitive health, biometric, calendar, and lifestyle data, but does not provide any meaningful privacy, retention, consent, or data-handling warning. In a health-focused skill, this omission increases the risk that users or deployers will enable broad data access without understanding exposure, secondary use, or compliance implications.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README encourages ingestion of biometrics, location, calendar, and other phone-collected context through a mobile app, yet gives no explicit warning about the privacy sensitivity or operational risks of aggregating those data sources. Combining these streams can reveal intimate behavioral patterns, routines, and health conditions, so omission of warnings and safeguards is materially risky in this context.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The auto-activation trigger is broad enough to run during ordinary discussion of sleep, energy, or health, which can cause the skill to ingest or surface sensitive health and calendar context without a clear, deliberate invocation. In this domain, unintended activation is more dangerous because the data involved is intimate, regulated-adjacent, and potentially far beyond what the user expected to reveal in casual conversation.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The blueprint instructs the agent to collect and persist highly sensitive health, medication, lifestyle, stress, and calendar-related data into a context file, but it does not require explicit informed consent, clear notice of what will be stored, retention limits, or user control over deletion. In a health-monitoring skill, this is especially dangerous because users may disclose protected-like personal information in what feels like ordinary conversation, creating a large privacy and compliance risk if the data is stored unexpectedly or exposed.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The 'immediately writes it to the context file' behavior creates covert persistence of sensitive health disclosures from casual chat without a mandatory user-facing warning at the moment of capture. Because this skill is explicitly designed to infer and retain intimate health context over time, silently converting ordinary conversation into durable biometric memory materially increases privacy harm and the chance of over-collection.

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal