Back to skill

Security audit

Strava

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Strava read-only analysis helper, but its token refresh flow can expose full account access credentials in normal command output.

Review before installing. Use this only if you are comfortable giving the agent access to Strava activity data that may include private workouts, routes, timestamps, and heart-rate metrics. Do not run the refresh helper in logged terminals or shared agent sessions unless it is fixed to avoid printing full tokens, and store any Strava client secret, access token, and refresh token in a protected secret store or restricted-permission config file.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/refresh_token.sh:26
Finding

OAuth Access and Refresh Tokens Exposed in Standard Output

Content
View full analysis

Vulnerability Details

File Location: scripts/refresh_token.sh, lines 26–32
Vulnerability Type: Plaintext sensitive credential exposure
Risk Level: High

Vulnerable Code

bash
if [ -n "$NEW_ACCESS_TOKEN" ]; then
  echo "✓ Token refreshed successfully"
  echo "New access token: $NEW_ACCESS_TOKEN"
  echo "New refresh token: $NEW_REFRESH_TOKEN"
  echo "Expires at: $(date -r "$EXPIRES_AT" 2>/dev/null || date -d "@$EXPIRES_AT" 2>/dev/null || echo "$EXPIRES_AT")"
  echo ""
  echo "Update your config with:"
  echo "  STRAVA_ACCESS_TOKEN=\"$NEW_ACCESS_TOKEN\""
  echo "  STRAVA_REFRESH_TOKEN=\"$NEW_REFRESH_TOKEN\""

Technical Analysis

After a successful OAuth refresh, the script prints the complete access token and refresh token to standard output twice. OAuth bearer tokens must be treated as passwords because possession is sufficient for API authentication.

Standard output can be retained in agent transcripts, terminal-capture systems, CI/CD logs, process-supervisor logs, support bundles, or other centralized logging infrastructure. Consequently, systems and users that are authorized to view operational output—but are not authorized to access the Strava account—may obtain reusable credentials.

The refresh token presents the greater long-term risk because it can be exchanged for new access tokens. The access token immediately permits API access within its granted scope. The documented authorization flow requests activity:read_all, which may include private activity data.

Attack Path

  1. A user or agent configures valid Strava client credentials and a refresh token.
  2. The documented command invokes scripts/refresh_token.sh.
  3. The script sends the credentials to Strava's official OAuth endpoint and receives fresh tokens.
  4. Lines 27–32 write the complete access and refresh tokens to standard output.
  5. An agent transcript, CI logger, terminal recorder, process supervisor, or another output-capture mechanism retains the plaintex ...[truncated 1056 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove every statement that prints complete access or refresh tokens.
  2. Return only a generic success message and non-sensitive expiration information.
  3. Write refreshed credentials directly to an approved secret manager or a dedicated credential file with restrictive permissions, such as mode 0600.
  4. If automatic credential storage is unavailable, require a secure interactive workflow rather than exposing credentials through normal standard output.
  5. If partial token identification is operationally necessary, display only a short redacted suffix and never enough token material to permit authentication.
  6. Ensure CI/CD, agent, and process-supervisor configurations do not capture secret-bearing output.
  7. Avoid printing the complete OAuth response on failure, because future or unusual responses may contain sensitive fields.
  8. Revoke and rotate tokens that may already have appeared in logs or transcripts, and remove retained copies from logging systems where feasible.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (6)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill instructs the agent to use shell commands and curl, but the metadata does not declare shell/code-execution permissions. That mismatch weakens security review and policy enforcement because a host may permit broader behavior than users expect or fail to gate dangerous execution capabilities appropriately.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The stated purpose is data loading and analysis, but the documentation also includes OAuth token refresh flows that can emit newly issued access and refresh tokens to stdout. That is security-relevant behavior beyond simple analysis, and if an agent follows it naively, secrets may be exposed in logs, chat transcripts, or terminal history.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script prints freshly issued access and refresh tokens directly to stdout, which can expose credentials in terminal scrollback, shell history captures, CI logs, or process monitoring systems. Because the refresh token can be used to obtain future access tokens, this creates a real credential disclosure risk beyond normal token handling.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README explicitly instructs users to place long-lived Strava secrets and tokens into a local configuration file, but it does not warn that these values are sensitive credentials that can grant account access if the file is exposed. While documenting required configuration is normal, omitting handling guidance increases the chance of accidental leakage through backups, screenshots, dotfile syncing, or overly permissive file permissions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

The skill sends personally sensitive fitness data to Strava endpoints and encourages fetching profile, activity, and heart-rate related data, but provides no explicit privacy or data-sharing warning. In this context, omission can lead users to disclose health/location information without informed consent or understanding retention and third-party exposure.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

At this location, the script exposes both the new access token and new refresh token in cleartext output. This is dangerous because anyone with access to console output, logs, screenshots, or captured terminal sessions can reuse the tokens to access the associated Strava account and, with the refresh token, maintain ongoing access.

Content

Scanner excerpt · scripts/refresh_token.sh (reported line 25)May include surrounding context.

sh
if [ -n "$NEW_ACCESS_TOKEN" ]; then
  echo "✓ Token refreshed successfully"
  echo "New access token: $NEW_ACCESS_TOKEN"
  echo "New refresh token: $NEW_REFRESH_TOKEN"
  echo "Expires at: $(date -r "$EXPIRES_AT" 2>/dev/null || date -d "@$EXPIRES_AT" 2>/dev/null || echo "$EXPIRES_AT")"
  echo ""

Static analysis

No suspicious patterns detected.