Back to skill

Security audit

Omi Integration

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly an Omi recording sync tool, but it handles private transcripts and credentials with under-disclosed security risks, especially an unauthenticated public webhook path.

Review before installing. Use this only on a machine where storing private transcripts locally is acceptable, set a strong OMI_WEBHOOK_SECRET before exposing any webhook, avoid public ngrok exposure unless needed, restrict permissions on config and recording directories, validate any self-hosted backend URL before use, and treat the API key as plaintext despite the documentation's encryption claim.

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

T09 · Insecure Skill Coding Practices

Error
Location
webhook-server.py:16
Finding
Public Webhook Endpoint Accepts Unauthenticated Data-Writing Requests<![CDATA[ ## Vulnerability Details **File Location**: `webhook-server.py:16, 30-35, 112`; `setup-ngrok.sh:44-52`; `omi-webhook-handler.sh:29-40` **Vulnerability Type**: Missing authentication on a publicly exposed webhook **Risk Level**: High ### Vulnerable Code ```python # webhook-server.py WEBHOOK_PORT = int(os.environ.get('OMI_WEBHOOK_PORT', 8765)) WEBHOOK_SECRET = os.environ.get('OMI_WEBHOOK_SECRET', '') # Verify secret if configured if WEBHOOK_SECRET: auth_header = self.headers.get('Authorization', '') if auth_header != f'Bearer {WEBHOOK_SECRET}': self.send_error(401, 'Unauthorized') return ``` ```python # webhook-server.py server = HTTPServer(('0.0.0.0', WEBHOOK_PORT), OmiWebhookHandler) ``` ```bash # setup-ngrok.sh ngrok http $WEBHOOK_PORT --log=stdout > /tmp/ngrok.log 2>&1 & NGROK_PID=$! # Wait for ngrok to start sleep 3 # Get public URL from ngrok API NGROK_URL=$(curl -s http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url') ``` ```bash # omi-webhook-handler.sh RECORDING_ID=$(echo "$PAYLOAD" | jq -r '.data.id // .recording_id') CREATED_AT=$(echo "$PAYLOAD" | jq -r '.data.created_at // .created_at // now | strftime("%Y-%m-%dT%H:%M:%SZ")') DATE_DIR=$(echo "$CREATED_AT" | cut -d'T' -f1) REC_DIR="$STORAGE_DIR/$DATE_DIR/$RECORDING_ID" mkdir -p "$REC_DIR" # Save metadata echo "$PAYLOAD" | jq '.data // .' > "$REC_DIR/metadata.json" # Save transcript if available TRANSCRIPT=$(echo "$PAYLOAD" | jq -r '.data.transcript // .transcript // empty') if [[ -n "$TRANSCRIPT" ]]; then echo "$TRANSCRIPT" > "$REC_DIR/transcript.txt" fi ``` ### Technical Analysis Authentication is conditional on `OMI_WEBHOOK_SECRET` being non-empty. The default value is empty, and the supplied startup workflow does not require or automatically create a secret. Consequently, requests are accepted without authentication in the default configuration. The server binds to all network interfaces, and the documented ngrok workflow exposes the ser ...[truncated 1626 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Refuse to start unless a strong webhook secret or signing key is configured. - Authenticate every webhook request rather than treating authentication as optional. - Prefer Omi-supported HMAC signature verification over a static bearer token. - Compare signatures using a constant-time comparison function. - Include timestamps and event identifiers in signature validation to prevent replay attacks. - Bind the server to `127.0.0.1` when ngrok is the intended ingress mechanism. - Configure ngrok access controls where supported. - Apply request rate limits and reject repeated event identifiers. - Document secret generation and secure storage as mandatory setup steps. - Return an error without invoking the handler whenever authentication fails. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
omi-webhook-handler.sh:29
Finding
Untrusted Recording Identifiers Permit Directory Traversal<![CDATA[ ## Vulnerability Details **File Location**: `omi-webhook-handler.sh:29-40`; `omi-sync.sh:104-130` **Vulnerability Type**: Path traversal and arbitrary fixed-filename write **Risk Level**: High ### Vulnerable Code ```bash # omi-webhook-handler.sh RECORDING_ID=$(echo "$PAYLOAD" | jq -r '.data.id // .recording_id') CREATED_AT=$(echo "$PAYLOAD" | jq -r '.data.created_at // .created_at // now | strftime("%Y-%m-%dT%H:%M:%SZ")') DATE_DIR=$(echo "$CREATED_AT" | cut -d'T' -f1) REC_DIR="$STORAGE_DIR/$DATE_DIR/$RECORDING_ID" mkdir -p "$REC_DIR" # Save metadata echo "$PAYLOAD" | jq '.data // .' > "$REC_DIR/metadata.json" # Save transcript if available TRANSCRIPT=$(echo "$PAYLOAD" | jq -r '.data.transcript // .transcript // empty') if [[ -n "$TRANSCRIPT" ]]; then echo "$TRANSCRIPT" > "$REC_DIR/transcript.txt" fi ``` ```bash # omi-sync.sh RECORDING_ID=$(echo "$recording" | jq -r '.id') CREATED_AT=$(echo "$recording" | jq -r '.created_at') DATE_DIR=$(echo "$CREATED_AT" | cut -d'T' -f1) REC_DIR="$STORAGE_DIR/$DATE_DIR/$RECORDING_ID" mkdir -p "$REC_DIR" echo "Syncing: $RECORDING_ID" | tee -a "$LOG_FILE" # Save metadata echo "$recording" | jq '.' > "$REC_DIR/metadata.json" # Fetch full transcript TRANSCRIPT=$(curl -s -H "Authorization: Bearer $API_KEY" \ "$BACKEND_URL/recordings/$RECORDING_ID/transcript") if [[ -n "$TRANSCRIPT" ]] && [[ "$TRANSCRIPT" != "null" ]]; then echo "$TRANSCRIPT" | jq -r '.transcript // .text // .' > "$REC_DIR/transcript.txt" fi # Fetch summary if available SUMMARY=$(curl -s -H "Authorization: Bearer $API_KEY" \ "$BACKEND_URL/recordings/$RECORDING_ID/summary") if [[ -n "$SUMMARY" ]] && [[ "$SUMMARY" != "null" ]]; then echo "$SUMMARY" | jq -r '.summary // .' > "$REC_DIR/summary.md" fi ``` ### Technical Analysis The scripts insert externally supplied recording identifiers directly into filesystem paths. No allowlist validation, canonicalization, or containment check is performed. Shell quoting prevents word splitting but ...[truncated 1744 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Validate every recording ID with a strict allowlist, for example `^[A-Za-z0-9_-]{1,128}$`. - Reject null, empty, absolute, dot, and dot-dot path components. - Validate dates independently and require the exact `YYYY-MM-DD` format. - Resolve the candidate directory to a canonical path before writing. - Verify that the canonical path is strictly beneath the canonical storage root. - Perform the containment check for every write, not only during directory creation. - Apply the same validation to identifiers obtained from both webhooks and API responses. - Avoid following symbolic links within the recording hierarchy where possible. - Consider opening files using directory file descriptors and no-follow semantics in a non-shell implementation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
omi-sync.sh:56
Finding
Bearer API Key May Be Transmitted to an Insecure or Unintended Backend<![CDATA[ ## Vulnerability Details **File Location**: `omi-sync.sh:56-60, 86-87, 119-128` **Vulnerability Type**: Unvalidated credential transmission destination **Risk Level**: Medium ### Vulnerable Code ```bash API_KEY=$(cat "$API_KEY_FILE") if [[ -f "$BACKEND_URL_FILE" ]]; then BACKEND_URL=$(cat "$BACKEND_URL_FILE") fi ``` ```bash # Fetch recordings list RESPONSE=$(curl -s -H "Authorization: Bearer $API_KEY" \ "$BACKEND_URL/recordings?$TIME_FILTER") ``` ```bash # Fetch full transcript TRANSCRIPT=$(curl -s -H "Authorization: Bearer $API_KEY" \ "$BACKEND_URL/recordings/$RECORDING_ID/transcript") # Fetch summary if available SUMMARY=$(curl -s -H "Authorization: Bearer $API_KEY" \ "$BACKEND_URL/recordings/$RECORDING_ID/summary") ``` ### Technical Analysis Sending the bearer API key to the Omi backend is required for the declared synchronization function and is not covert exfiltration. The security weakness is that the destination is read verbatim from `~/.config/omi/backend_url` and used without validating its URL scheme or host. A value using plaintext HTTP exposes the bearer token to network interception. A value pointing to an unintended or attacker-operated HTTPS host sends the key directly to that host. The script provides no warning, destination confirmation, or host allowlist before transmitting the credential. Because a self-hosted backend is a declared feature, an absolute Omi-only host restriction may not be suitable. However, transport security and explicit trust establishment remain necessary. ### Attack Path 1. The backend configuration is accidentally set to an HTTP URL, copied from untrusted setup instructions, or modified by an actor able to alter the user’s configuration. 2. The user runs `omi-sync.sh`. 3. The script reads the API key from the local credential file. 4. `curl` sends the key in an `Authorization: Bearer` header to the configured destination. 5. An attacker-controlled host receives the key, or a network attacker ...[truncated 528 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Parse and validate `BACKEND_URL` before making any request. - Require HTTPS by default and reject plaintext HTTP. - Provide an explicit, separately named opt-in for development-only localhost HTTP endpoints. - Reject embedded URL credentials, fragments, control characters, and malformed URLs. - Warn the user and require explicit confirmation when first trusting a non-default backend host. - Store a fingerprint or normalized trusted origin and detect unexpected changes. - Protect `~/.config/omi` with mode 700 and configuration files with mode 600. - Use `curl --fail-with-body --show-error --proto '=https'` for production endpoints. - Document that self-hosted backends receive the same bearer credential and must be trusted. - Support narrowly scoped API keys and recommend immediate rotation after suspected disclosure. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
omi-webhook-handler.sh:7
Finding
Sensitive Webhook and Recording Content Is Stored with Unenforced Permissions<![CDATA[ ## Vulnerability Details **File Location**: `omi-webhook-handler.sh:7-17, 35-40`; `omi-sync.sh:8-12, 112-130`; `SKILL.md:114-119` **Vulnerability Type**: Plaintext sensitive-data storage and excessive logging **Risk Level**: Medium ### Vulnerable Code ```bash # omi-webhook-handler.sh STORAGE_DIR="$HOME/omi_recordings" WEBHOOK_LOG="$STORAGE_DIR/.webhook.log" mkdir -p "$STORAGE_DIR" # Read JSON payload from stdin PAYLOAD=$(cat) # Log webhook receipt echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] Webhook received" >> "$WEBHOOK_LOG" echo "$PAYLOAD" | jq '.' >> "$WEBHOOK_LOG" ``` ```bash # omi-webhook-handler.sh # Save metadata echo "$PAYLOAD" | jq '.data // .' > "$REC_DIR/metadata.json" # Save transcript if available TRANSCRIPT=$(echo "$PAYLOAD" | jq -r '.data.transcript // .transcript // empty') if [[ -n "$TRANSCRIPT" ]]; then echo "$TRANSCRIPT" > "$REC_DIR/transcript.txt" fi ``` ```bash # omi-sync.sh # Save metadata echo "$recording" | jq '.' > "$REC_DIR/metadata.json" # Fetch full transcript TRANSCRIPT=$(curl -s -H "Authorization: Bearer $API_KEY" \ "$BACKEND_URL/recordings/$RECORDING_ID/transcript") if [[ -n "$TRANSCRIPT" ]] && [[ "$TRANSCRIPT" != "null" ]]; then echo "$TRANSCRIPT" | jq -r '.transcript // .text // .' > "$REC_DIR/transcript.txt" fi # Fetch summary if available SUMMARY=$(curl -s -H "Authorization: Bearer $API_KEY" \ "$BACKEND_URL/recordings/$RECORDING_ID/summary") if [[ -n "$SUMMARY" ]] && [[ "$SUMMARY" != "null" ]]; then echo "$SUMMARY" | jq -r '.summary // .' > "$REC_DIR/summary.md" fi ``` ```markdown <!-- SKILL.md --> ## Privacy - All data stored locally - API key encrypted at rest - Self-hosted backend supported - No telemetry or tracking - Webhook payloads logged for debugging (optional) ``` ### Technical Analysis The handler unconditionally writes the complete webhook payload to `.webhook.log`, potentially duplicating transcripts, device information, identifiers, and other private metadata. Logging is not optional ...[truncated 1588 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Set `umask 077` at the beginning of every script that creates sensitive files. - Create `~/.config/omi` and `~/omi_recordings` with mode 700. - Enforce mode 600 on credentials, transcripts, metadata, summaries, indexes, and logs. - Disable full-payload logging by default. - Add an explicit debug configuration option for payload logging. - When debugging is enabled, redact transcripts, authorization data, identifiers, and other sensitive fields. - Implement log rotation, maximum log size, and retention limits. - Avoid duplicating full transcripts in both recording files and logs. - Correct the documentation to state that the API key is plaintext protected by filesystem permissions, unless actual encryption is implemented. - If encryption at rest is required, integrate an operating-system keychain or encrypted secret store rather than embedding a decryption key in the scripts. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
webhook-server.py:38
Finding
Webhook Server Reads Unbounded Request Bodies<![CDATA[ ## Vulnerability Details **File Location**: `webhook-server.py:38-39, 50-54` **Vulnerability Type**: Uncontrolled resource consumption **Risk Level**: Medium ### Vulnerable Code ```python # Read payload content_length = int(self.headers.get('Content-Length', 0)) payload = self.rfile.read(content_length) try: # Parse JSON data = json.loads(payload.decode('utf-8')) ``` ```python # Process via handler script result = subprocess.run( [str(HANDLER_SCRIPT)], input=payload, capture_output=True, timeout=30 ) ``` ### Technical Analysis The server trusts the client-provided `Content-Length` and reads that number of bytes without enforcing a maximum payload size. The complete body is held in memory, decoded, parsed as JSON, and then copied into a subprocess input buffer. The subprocess timeout limits handler execution time but does not limit the time spent waiting for the HTTP request body or the amount of memory allocated before the subprocess starts. The use of the single-threaded `HTTPServer` also means that one slow or oversized request can prevent normal webhook processing. When accepted, large payloads may additionally be written to the webhook log and recording files, increasing disk consumption. ### Attack Path 1. The webhook listener is reachable directly or through ngrok. 2. An attacker opens a connection and declares a very large `Content-Length`. 3. The server attempts to read the declared body without a size limit. 4. The attacker sends a large body to consume memory, or transmits it slowly to occupy the single server thread. 5. If the body is valid JSON and reaches the handler, it may also be copied to subprocess buffers and written to disk. 6. Legitimate webhook requests are delayed or rejected as resources are exhausted. ### Impact Assessment A remote client can degrade or deny webhook service availability through memory pressure, slow request delivery, or disk consumption. The impact is limited to resources ava ...[truncated 144 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Define a conservative maximum webhook size based on the expected Omi payload format. - Reject missing, negative, malformed, or oversized `Content-Length` values with HTTP 411 or 413 before reading the body. - Read the request incrementally while enforcing the same byte limit. - Configure socket read and connection timeouts to mitigate slow-client attacks. - Use a production HTTP server or reverse proxy with body-size, timeout, connection, and rate limits. - Authenticate requests before reading more body data than necessary. - Avoid retaining unnecessary copies of the payload in memory. - Limit log size and reject unexpectedly large transcript fields. - Consider a bounded worker pool so one slow request cannot block all legitimate webhook processing. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (34)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The declared purpose emphasizes synchronization from Omi/Limitless devices or services via API/webhooks, automatic transcript syncing, and processing/organization workflows. The actual code is a local inspection utility: it reads metadata.json and transcript.txt files under $HOME/omi_recordings, filters by date, and displays recording details. While this may be related to the broader Omi recordings domain, the code chunk’s primary behavior is materially different from the declared sync functionality and omits the advertised remote integration capabilities.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The code substantially aligns with the general theme of syncing Omi recordings and transcripts from an API to local storage, but the declared description overstates several capabilities. There is no webhook handling or trigger mechanism at all, only a command-line batch sync using a time filter. The storage layout is by date and recording ID, not by device. The script also does not meaningfully 'process recordings' beyond retrieving metadata/transcript/summary and writing files locally. These are material discrepancies in described behavior, so this should be flagged as a mismatch.

Natural-Language Policy Violations

High
Confidence
98% confidence
Finding
The documentation instructs users to save the API key as plaintext while elsewhere asserting it is encrypted at rest. This combination is dangerous because it both weakens credential protection and misleads users into underestimating the risk of credential theft, which could allow unauthorized access to recordings and transcripts via the Omi API.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The manifest says this skill syncs recordings from Omi AI wearables via API and webhooks, but this file documents a complete unified voice capture system spanning both Plaud and Omi device families with shared storage and search. That materially broadens the apparent purpose and behavior beyond an Omi-focused integration skill.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The instructions tell users to expose a webhook publicly and store transcript-bearing events without clearly warning that recordings and transcripts may traverse the public internet and could be sensitive. In a voice-capture skill, that omission is more dangerous because the payloads may contain private conversations, summaries, and metadata.

Session Persistence

Medium
Category
Rogue Agent
Content
**Configure in Omi app:**
1. Open Omi app → Settings → Developer
2. Create new webhook
3. Enter ngrok URL (e.g., `https://abc123.ngrok-free.app/omi/webhook`)
4. Select events: `recording.created`, `transcript.updated`
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
#### 5. Unified Index (`rebuild-index.sh`)

**Purpose:** Create searchable index of all recordings

**Output:** `~/voice_recordings/index.json`
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The setup instructions explicitly store device credentials and API keys in plaintext files using shell redirection, but do not warn users about the risk of shell history exposure, local compromise, backups, or accidental leakage. For a skill handling account credentials and transcript access, this materially increases the chance of credential theft and downstream access to sensitive recordings.

File System Enumeration

Medium
Category
Data Exfiltration
Content
**Check device config:**
```bash
ls -la ~/.config/voice-capture/plaud/notepin-work/
```

**Common issues:**
Confidence
60% confidence
Finding
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Session Persistence

Medium
Category
Rogue Agent
Content
**Step 1: Get your Omi API key**
- Go to https://omi.me/developer (or your self-hosted backend)
- Create API key
- Store it:
```bash
mkdir -p ~/.config/omi
Confidence
86% confidence
Finding
The README tells users to store a long-lived API key in plaintext on disk under ~/.config/omi/api_key. While common, persistent plaintext credential storage increases exposure if the local account, backups, logs, or filesystem are compromised, and this skill handles sensitive recording/transcript data that could be accessed through the API.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
mkdir -p ~/.config/omi
echo "YOUR_API_KEY" > ~/.config/omi/api_key
chmod 600 ~/.config/omi/api_key
```

**Step 2: Sync your recordings**
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
mkdir -p ~/.config/omi
echo "YOUR_API_KEY" > ~/.config/omi/api_key
chmod 600 ~/.config/omi/api_key
```

**Step 2: Sync your recordings**
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
mkdir -p ~/.config/omi
echo "YOUR_API_KEY" > ~/.config/omi/api_key
chmod 600 ~/.config/omi/api_key
```

**Step 2: Sync your recordings**
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README instructs users to expose a local webhook receiver to the public internet via ngrok for transcript delivery, but does not prominently warn that webhook payloads may contain highly sensitive audio-derived transcript data and metadata. In a voice-recording integration, internet exposure materially increases the risk of unauthorized access, interception, misconfiguration, or accidental disclosure, especially if webhook authentication/TLS validation is weak or left optional.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill describes capabilities that require network, shell, and environment access, but it does not declare any explicit tool scope or permission boundaries. That increases the risk of over-broad execution in agent environments, making it harder for users or platforms to constrain what the skill can access when handling sensitive recordings and API keys.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill omits a clear warning that syncing and webhook handling may download and store highly sensitive transcripts, summaries, and possibly audio to local disk. Users may enable it without understanding the privacy consequences, leading to unintended retention of meeting notes, personal conversations, or regulated data.

Session Persistence

Medium
Category
Rogue Agent
Content
1. Get your Omi API key from https://omi.me/developer or your self-hosted backend
2. Store it securely:
```bash
mkdir -p ~/.config/omi
echo "YOUR_API_KEY" > ~/.config/omi/api_key
chmod 600 ~/.config/omi/api_key
```
Confidence
86% confidence
Finding
The skill persists an API credential across sessions by writing it to a file in the user's home directory. Persistence of secrets is not inherently malicious, but in this context it increases exposure because the stored credential grants ongoing access to potentially sensitive recordings and transcripts if the host is compromised or shared.

Session Persistence

Medium
Category
Rogue Agent
Content
Configure your Omi app to send webhooks to your endpoint:
1. Open Omi app → Settings → Developer
2. Create new webhook
3. Enter your webhook URL
4. Select events: `recording.created`, `transcript.updated`
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The skill claims the API key is encrypted at rest, but the setup instructions store it in plaintext under ~/.config/omi/api_key. This creates a false sense of security and exposes a credential that can be read by other processes, backups, malware, or users if filesystem protections fail or are misconfigured.

External Transmission

Medium
Category
Data Exfiltration
Content
LOG_FILE="$STORAGE_DIR/.sync.log"

# Default backend URL
BACKEND_URL="https://api.omi.me/v1"

# Parse arguments
DAYS=30  # Default: sync last 30 days
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
LOG_FILE="$STORAGE_DIR/.sync.log"

# Default backend URL
BACKEND_URL="https://api.omi.me/v1"

# Parse arguments
DAYS=30  # Default: sync last 30 days
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
echo "Error: API key not found. Please run:"
  echo "  mkdir -p $CONFIG_DIR"
  echo "  echo 'YOUR_API_KEY' > $API_KEY_FILE"
  echo "  chmod 600 $API_KEY_FILE"
  exit 1
fi
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
echo "Error: API key not found. Please run:"
  echo "  mkdir -p $CONFIG_DIR"
  echo "  echo 'YOUR_API_KEY' > $API_KEY_FILE"
  echo "  chmod 600 $API_KEY_FILE"
  exit 1
fi
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
80% confidence
Finding
The script sends authenticated HTTP requests to fetch recordings and associated transcript/summary data from a remote backend. While this is core to syncing, the visible user messaging does not explicitly disclose that recording contents and related data will be retrieved from the remote service and written locally.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The script persists highly sensitive content including transcripts, summaries, and metadata to local disk, but provides no explicit consent prompt, retention control, or warning to the user about the privacy implications. In the context of wearable recording data, local storage can expose conversations, personal information, or confidential business content to other local users, backups, endpoint tooling, or later compromise of the host.

Static analysis

No suspicious patterns detected.