Back to skill

Security audit

Strava Python

Security checks for vulnerabilities and agentic risk

Overview

This Strava skill is mostly purpose-aligned, but it persists broad Strava OAuth credentials in a plaintext home-directory file without enough scoping or safeguards.

Review carefully before installing. Use a dedicated Strava API app, grant only scopes you are comfortable with, protect or replace ~/.strava_credentials.json with secure secret storage or owner-only permissions, and revoke the Strava authorization when done. Prefer an isolated Python environment and a pinned stravalib version.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
setup.py:31
Finding

Excessive Strava OAuth Scopes Violate Least Privilege

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
setup.py:22
Finding

Client Secret Is Collected Through an Echoing Terminal Prompt

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
setup.py:64
Finding

OAuth Credentials Are Stored in Plaintext Without Enforced Restrictive Permissions

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:9
Finding

Unpinned Third-Party Dependency Creates Supply-Chain Exposure

Content
View full analysis
Remediation
View remediation
--hash=sha256: ``` The Skill metadata and all installation documentation should reference the same pinned dependency policy. ]]>
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 (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The code substantially matches the core declared purpose of querying Strava data via Python/stravalib. It reads local credentials, connects to Strava, and retrieves recent activities, athlete stats, and the last activity. However, the description claims 'interactive setup,' which is not implemented here; the code only expects a preexisting credentials file and tells the user to run a separate setup script. The description also mentions 'workout data' broadly, while this chunk only exposes limited read-only queries. So this is a partial but material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

The skill explicitly states that OAuth credentials will be saved to ~/.strava_credentials.json, which introduces a sensitive local secret file. In agent or shared environments, predictable plaintext credential storage in the user's home directory increases the risk of accidental disclosure, unintended reuse by other tools, or theft if filesystem access is broader than expected.

Content

Scanner excerpt · SKILL.md (reported line 46)May include surrounding context.

md
This will:
   - Guide you through creating a Strava API app
   - Handle OAuth authentication
   - Save credentials to `~/.strava_credentials.json`

## Commands

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 76)May include surrounding context.

md
- `SKILL.md` - This file

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

Documenting an auto-generated credentials file at ~/.strava_credentials.json confirms the presence of a predictable secret-bearing artifact on disk. In the context of a skill that may have file read/write capabilities, this makes credential targeting easier and raises the danger of unauthorized access or exfiltration from a user's home directory.

Content

Scanner excerpt · SKILL.md (reported line 77)May include surrounding context.

md
- `strava_control.py` - Main controller script
- `setup.py` - Interactive setup wizard
- `SKILL.md` - This file
- `~/.strava_credentials.json` - Credentials (auto-generated)

## Notes

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

This code writes a credential bundle containing access_token, refresh_token, and client_secret to ~/.strava_credentials.json. Those values enable ongoing authenticated access, and inclusion of the refresh token and client secret makes compromise more severe because an attacker can refresh access and potentially maintain persistence.

Content

Scanner excerpt · setup.py (reported line 73)May include surrounding context.

python
'client_secret': client_secret
    }

    config_path = os.path.expanduser('~/.strava_credentials.json')
    with open(config_path, 'w') as f:
        json.dump(credentials, f, indent=2)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 86)May include surrounding context.

md
def load_credentials():
    """Load Strava credentials from config file"""
    config_path = os.path.expanduser('~/.strava_credentials.json')
    if not os.path.exists(config_path):
        print(f"❌ Credentials not found at {config_path}")
        print("Run the setup script first: python3 setup.py")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · strava_control.py (reported line 11)May include surrounding context.

python
def load_credentials():
    """Load Strava credentials from config file"""
    config_path = os.path.expanduser('~/.strava_credentials.json')
    if not os.path.exists(config_path):
        print(f"❌ Credentials not found at {config_path}")
        print("Run the setup script first: python3 setup.py")

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · README.md (reported line 28)May include surrounding context.

pip install stravalib

text

### 2. Create Strava API App

1. Go to https://www.strava.com/settings/api
2. Click **"Create App"**

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill advertises behavior that involves reading and writing local files, including storing OAuth credentials, but it does not declare any explicit tool scope or permissions. In an agent setting, undeclared filesystem capability reduces transparency and can allow broader file access than users or reviewers expect, especially when credentials are written to the home directory.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · setup.py (reported line 12)May include surrounding context.

python
print()

# Get credentials from user
print("First, create a Strava API app:")
print("1. Go to: https://www.strava.com/settings/api")
print("2. Click 'Create App'")
print("3. Fill in:")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script stores highly sensitive OAuth material and the Strava client secret in a plaintext file under the user's home directory. This creates unnecessary exposure because any local process, backup system, or other user with access to that file can reuse the tokens or secret to access the user's Strava data and maintain access via the refresh token.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script reads an OAuth access token from a local credentials file and uses it without any runtime disclosure or consent prompt. In an agent-skill context, this can cause a user to unknowingly expose or use sensitive account credentials, especially if the surrounding platform invokes the skill on the user's behalf.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill makes authenticated network requests to Strava APIs as soon as commands are run, but it does not clearly inform the user at execution time that external data will be transmitted. In an agent environment, undisclosed outbound access can surprise users and increase privacy risk by querying personal fitness data from a third-party service.

Content

No source excerpt is available for this finding.