Back to skill

Security audit

Granola Meeting Notes (MCP)

Security checks for vulnerabilities and agentic risk

Overview

This skill’s Granola meeting-note access is coherent, but its token refresh script handles sensitive OAuth credentials with unsafe endpoint trust and response handling that should be reviewed before use.

Install only if you trust the publisher and are comfortable granting access to private Granola meeting data. Before use, hardcode or allowlist the Granola token endpoint, avoid interpolating token values into Python source, restrict credential files to the owning user, and avoid enabling the optional cron refresh until those issues are fixed.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/refresh_token.sh:13
Finding

Unvalidated OAuth Token Endpoint Permits Credential Exfiltration and SSRF

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/refresh_token.sh:28
Finding

OAuth Response Fields Are Interpolated into Python Source, Enabling Code Injection

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (6)

Credential Access

High
Category
Privilege Escalation
Confidence
89% confidence
Finding

The skill explicitly handles OAuth secrets and instructs execution of a shell script that reads refresh tokens, contacts a token endpoint, and rewrites credential-bearing config files. Even though this is intended functionality, it creates a credential-handling pathway with shell execution and secret persistence, which is high risk if logs, files, subprocess arguments, or broader agent capabilities are exposed or misused.

Content

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

bash {baseDir}/scripts/refresh_token.sh

text

The script reads `config/granola_oauth.json`, posts to the token endpoint (`https://mcp-auth.granola.ai/oauth2/token`), and updates both `config/granola_oauth.json` and `config/mcporter.json` with the new access token.

Then retry the call. If refresh also fails, the user needs to re-authenticate manually via the OAuth flow above.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

sh
REFRESH_TOKEN=$(python3 -c "import json; print(json.load(open('$OAUTH_FILE'))['refresh_token'])")
TOKEN_ENDPOINT=$(python3 -c "import json; print(json.load(open('$OAUTH_FILE'))['token_endpoint'])")

RESPONSE=$(curl -s -X POST "$TOKEN_ENDPOINT" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token&refresh_token=${REFRESH_TOKEN}&client_id=${CLIENT_ID}")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares shell and file-write capable behavior but does not define any explicit tool scope or permission boundary. That makes it easier for an agent runtime to invoke powerful actions implicitly, including running token-refresh scripts and modifying local config files, which increases the blast radius if the skill is triggered unexpectedly or influenced by untrusted input.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The activation guidance is broad enough that the skill may be invoked for generic meeting-related requests, even when the user did not clearly intend access to Granola data. In context, this matters because the skill can query sensitive meeting notes and transcripts, so over-triggering can expose private organizational information unnecessarily.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

The script reads the token endpoint from a local JSON file and posts the refresh token to that URL without validating that it is an expected trusted HTTPS endpoint. If an attacker can tamper with granola_oauth.json, they can redirect the request to an attacker-controlled server and exfiltrate the refresh token, which may enable long-lived unauthorized access to meeting data.

Content

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

sh
REFRESH_TOKEN=$(python3 -c "import json; print(json.load(open('$OAUTH_FILE'))['refresh_token'])")
TOKEN_ENDPOINT=$(python3 -c "import json; print(json.load(open('$OAUTH_FILE'))['token_endpoint'])")

RESPONSE=$(curl -s -X POST "$TOKEN_ENDPOINT" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token&refresh_token=${REFRESH_TOKEN}&client_id=${CLIENT_ID}")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This shell script updates both granola_oauth.json and mcporter.json with fresh bearer credentials, which is a safety-relevant file write involving sensitive authentication data. While comments describe the behavior for developers, there is no user-facing disclosure, prompt, or explicit warning before modifying these files.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.