T09 · Insecure Skill Coding Practices
- Location
scripts/setup-credentials.sh:13- Finding
Browser Session Token Exposed Through Agent Conversation and Process Arguments
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is for creating Dashform forms, but its authentication flow asks users to expose a live browser session cookie and caches account identifiers locally.
Review before installing. The main risk is not that the skill creates forms, but that it tells you to paste a live Dashform browser session cookie into the agent and uses it through a shell script. Only use this if you trust the environment and Dashform endpoint, understand that account identifiers will be cached locally, and have a way to revoke the session afterward. A safer version would use OAuth, a device-code login, or a scoped API token instead of a browser cookie.
scripts/setup-credentials.sh:13Browser Session Token Exposed Through Agent Conversation and Process Arguments
scripts/setup-credentials.sh:69Cached Personal and Tenant Identifiers Lack Explicit File-Permission Protection
The advertised purpose is form creation, but the actual workflow includes collecting a browser session token, deriving identity information, and caching credentials locally. This hidden expansion of scope is dangerous because users and agent operators may authorize the skill for form management while unknowingly enabling credential collection and local secret storage.
The skill instructs direct reading of .claude/skills/dashform/credentials.json, which is within the agent configuration area and likely to contain sensitive state. Accessing that path from a skill expands the skill's reach into privileged local context and can expose credentials or identity data unrelated to the immediate user request.
When the user asks to create a form, ALWAYS check for cached credentials first:
cat .claude/skills/dashform/credentials.json
userId, organizationId, and userName, proceed to Step 4The skill explicitly accesses credentials.json, indicating direct handling of credential-related material. In the broader context of also collecting session tokens and running local scripts, this creates a clear secret-exposure path through local files, shell execution, logs, and agent transcripts.
When the user asks to create a form, ALWAYS check for cached credentials first:
cat .claude/skills/dashform/credentials.json
userId, organizationId, and userName, proceed to Step 4The skill explicitly instructs the user to extract and send a raw session cookie from browser DevTools, which is effectively a bearer credential. Possession of that token can enable account takeover or unauthorized API access, and using an agent as the collection path expands exposure to logs, transcripts, and downstream tools.
The workflow combines two risky actions: prompting the user to reveal a browser cookie and then caching derived credentials locally for future reuse. That combination creates a persistent authentication foothold and increases the blast radius from a one-time disclosure into repeated unauthorized access if the local environment or transcripts are compromised.
The instructions ask the user to disclose a sensitive browser session token and state that credentials will be cached automatically, but they do not warn about token sensitivity, persistence, reuse, or revocation. This creates a strong risk of unsafe user behavior and long-lived compromise if the token is exposed or retained improperly.
This second direct read of the agent config directory again accesses credentials.json for operational use, reinforcing a pattern of retrieving sensitive local state from a privileged location. Repeated dependence on .claude/ makes the skill more dangerous because compromise of the skill or its scripts could expose persistent credential material.
Then read the cached credentials:
cat .claude/skills/dashform/credentials.json
Extract userId, organizationId, and userName for use in form creation.
This repeated access to credentials.json confirms the skill operationally depends on locally persisted credential data. That persistence makes compromise more damaging because an attacker or another process could reuse the stored values beyond the original session.
Then read the cached credentials:
cat .claude/skills/dashform/credentials.json
Extract userId, organizationId, and userName for use in form creation.
Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.
Before generating the form JSON configuration, ALWAYS read these files:
cat .claude/skills/dashform/references/SCHEMA.md
cat .claude/skills/dashform/references/API.md
Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.
Before generating the form JSON configuration, ALWAYS read these files:
cat .claude/skills/dashform/references/SCHEMA.md
cat .claude/skills/dashform/references/API.md
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# This script uses the MCP get_user_info tool to cache credentials
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CREDENTIALS_FILE="$SCRIPT_DIR/../credentials.json"
MCP_URL="https://getaiform.com/api/mcp"
echo "Dashform Credentials Setup..."
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# This script uses the MCP get_user_info tool to cache credentials
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CREDENTIALS_FILE="$SCRIPT_DIR/../credentials.json"
MCP_URL="https://getaiform.com/api/mcp"
echo "Dashform Credentials Setup..."
The skill invokes shell commands to read local files and run scripts, but it does not declare any tool scope or permission boundary. That mismatch increases the chance an agent will execute local file access and credential-handling actions without transparent user consent or least-privilege controls.
The skill directs the agent to read and later rely on a local credentials file in the agent configuration area. Even if the file only contains identifiers, this establishes undocumented secret/state management in a sensitive directory and normalizes local credential persistence for a task that should not require it.
This form collects personally identifiable information including full name, email, company, and job title, and also asks about dietary restrictions, which can reveal sensitive health-related information. Presenting the collection without any privacy notice, retention policy, consent language, or data-use explanation creates privacy and compliance risk and may cause users to disclose data without informed consent.
The form solicits an email address for follow-up but provides no visible privacy notice, purpose limitation, retention disclosure, or consent language near the field. This can lead to collection of personal data without adequate user awareness, increasing privacy, compliance, and trust risks if the example is reused as-is in production.
The documentation instructs users to provide a raw browser session token (better-auth.session_token) so the tool can derive user and organization credentials. Session tokens are highly sensitive bearer secrets; collecting and transmitting them through an MCP skill greatly expands the attack surface and is not necessary for normal form-authoring workflows if proper delegated auth is used. In this context, a compromised or misused token could allow account takeover or unauthorized access to organizational resources.
The docs normalize copying a browser session token into the tool for 'credential caching' without prominently warning that this value is equivalent to an authenticated session secret. That creates a phishing-like UX pattern where users may disclose reusable credentials to an intermediary system without understanding the risk, increasing the chance of accidental credential exposure or replay.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Test MCP server directly:
curl -X POST https://getaiform.com/api/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
echo ""
# Call MCP create_form tool
RESPONSE=$(curl -s -X POST "$MCP_URL" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d "{
This shell script sends merged form contents together with user and organization identifiers to an external HTTPS endpoint via curl. Although the script prints progress messages, it does not clearly disclose to the user that local form data and credential-derived identifiers will be transmitted off-host.
The script instructs the user to manually extract a live browser session cookie from DevTools and paste it into the script. Session cookies are authentication secrets; collecting them outside the browser materially increases account-takeover risk if the terminal history, process list, shell logs, or copied value are exposed. In the context of a form-management skill, asking for raw session cookies is unnecessarily dangerous and expands the trust boundary well beyond normal usage.
The script handles a highly sensitive session token and gives users step-by-step instructions to retrieve it from browser cookies, but it does not clearly and explicitly warn that the value will be transmitted to a remote API endpoint. Users may reasonably assume the token is only used locally, when in fact it is sent off-host for authentication, increasing the risk of unintentional secret disclosure. Because the secret is a session cookie, compromise can directly enable account access.
The script transmits user-supplied authentication material to an external service via curl. External transmission by itself can be legitimate, but here it carries a browser session token obtained through manual extraction, which substantially raises the impact of mistakes, interception through local logging, or endpoint misuse. In this skill context, that makes the transmission security-sensitive and deserving of stronger controls and disclosure.
echo "Fetching your user information via MCP..."
# Call MCP get_user_info tool
RESPONSE=$(curl -s -X POST "$MCP_URL" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d "{
The script writes credential-related account data to disk without clearly informing the user beforehand that local persistence will occur. Even though the cached file contains identifiers rather than the raw session token, undisclosed storage of account metadata can create privacy and operational risks, especially on shared systems or in source-controlled directories. The danger is elevated by the file name credentials.json, which implies sensitive authentication material and may attract mishandling.