T09 · Insecure Skill Coding Practices
- Location
scripts/tapd_client.py:59- Finding
OAuth Bearer Token Cached Without Restrictive File Permissions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a TAPD API integration, but it caches live OAuth tokens insecurely and includes examples that can change shared project data without strong safeguards.
Install only if you are comfortable giving this skill TAPD read/write access for the configured workspaces. Use least-privilege TAPD credentials, test in a non-production workspace first, avoid running bulk update examples without review, and protect or disable the token cache where possible.
scripts/tapd_client.py:59OAuth Bearer Token Cached Without Restrictive File Permissions
reference/examples.md:194Documentation Encourages Disclosure of OAuth Token Material
从行为上看,这段代码的主目的确实是 TAPD API 客户端,不存在明显的额外恶意或无关能力;它访问的资源也与声明一致,仅与 TAPD API 通信并在本地缓存 token。但声明中的“完整集成”“实现所有 API 模块和方法”“涵盖所有 TAPD 功能”明显夸大。代码虽然实现了不少模块和接口封装,但远不能从该片段证明是全量覆盖;而且模块数量与声明的 18 个并不吻合。更重要的是,_load_oauth_config 函数没有实际从配置文件读取 client_id/client_secret,却直接访问未初始化属性 self.client_id/self.client_secret,并引用 self.workspaces 等未定义内容,说明其宣称的完整 OAuth 配置支持并未真正实现。因此应判定为描述与实际行为存在实质性不匹配,属于过度声明功能范围。
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
CLIENT_SECRET="your-client-secret"
# 获取 access_token
ACCESS_TOKEN=$(curl -s -u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=client_credentials" \
"https://api.tapd.cn/tokens/request_token" \
| python3 -c "import json, sys; print(json.load(sys.stdin)['data']['access_token'])")
L734 的 docstring 明确说明该函数会“从 tapd.json 加载 OAuth 配置”,且 L735-L736 还构造了默认配置文件路径,但后续实现没有任何文件读取或解析逻辑。相反,L738 直接检查 self.client_id 和 self.client_secret,这与文档描述的“加载配置”行为相矛盾,属于主动性的意图-代码背离。
该技能说明从开头即以中文描述全部功能,且全文未提供语言切换、用户选择或适用地区范围说明。根据规则,若技能强制特定语言而无用户 opt-in 或明确合理的区域性约束,属于自然语言政策违规。
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.
./scripts/tapd-api.sh story list --status planning --limit 50
python3 scripts/tapd_client.py story create
--workspace 12345678
--name "新需求标题"
This markdown file contains all user-facing instructions in Chinese and does not indicate that the skill is China-specific or that users may choose another language. Under the policy rule, forcing a specific language without opt-in is a natural-language policy violation.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
安全设置:
chmod 600 tapd.json
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
安全设置:
chmod 600 tapd.json
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
安全设置:
chmod 600 tapd.json
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
安全设置:
chmod 600 tapd.json
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
安全设置:
chmod 600 tapd.json
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
1. **使用** tapd.json 或环境变量存储真实配置
2. **添加** tapd.json 到 .gitignore
3. **设置**文件权限 `chmod 600 tapd.json`
4. **避免**硬编码凭证到代码中
5. **定期**轮换 OAuth 密钥
6. **启用** IP 白名单(在 TAPD 开放平台)
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
1. **使用** tapd.json 或环境变量存储真实配置
2. **添加** tapd.json 到 .gitignore
3. **设置**文件权限 `chmod 600 tapd.json`
4. **避免**硬编码凭证到代码中
5. **定期**轮换 OAuth 密钥
6. **启用** IP 白名单(在 TAPD 开放平台)
The skill documents capabilities that read/write local files and make outbound network requests, but it declares no explicit tool scope or permissions. In an agent setting, this weakens user visibility and policy enforcement, increasing the chance that the skill accesses secrets or transmits project data without clear consent boundaries.
The documentation shows credentialed OAuth exchanges and API calls but does not clearly warn that client secrets, bearer tokens, and project data are transmitted to TAPD servers. In a skill ecosystem, users may treat examples as local-only operations and unintentionally expose sensitive credentials or business data to external services.
This example transmits OAuth client credentials to an external TAPD endpoint to obtain an access token. The network transmission is expected for the integration, but in a skill context it is security-relevant because it handles sensitive secrets and can expose them through logs, shell history, or misuse if users do not understand the outbound behavior.
CLIENT_SECRET="your-client-secret"
# 获取 access_token
ACCESS_TOKEN=$(curl -s -u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=client_credentials" \
"https://api.tapd.cn/tokens/request_token" \
| python3 -c "import json, sys; print(json.load(sys.stdin)['data']['access_token'])")
The skill communicates with an external TAPD domain, which means user data and authentication artifacts leave the local environment. That is normal for an API client, but it is still a real security concern when the skill does not pair the example with strong disclosures and scoped permissions.
# 获取 access_token
ACCESS_TOKEN=$(curl -s -u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=client_credentials" \
"https://api.tapd.cn/tokens/request_token" \
| python3 -c "import json, sys; print(json.load(sys.stdin)['data']['access_token'])")
# 调用 API
This API call sends a bearer token and workspace-scoped query to TAPD, exposing project metadata and potentially sensitive records to a remote service. The behavior is integral to the skill, but it should still be treated as a genuine external-transmission risk requiring clear consent and least-privilege controls.
curl -H "Authorization: Bearer $ACCESS_TOKEN"
"https://api.tapd.cn/stories?workspace_id=12345678&limit=10"
## 🔌 API 端点
The skill documents create and update operations against remote TAPD objects without a strong warning that these commands will modify production project data. In practice, users may run examples assuming they are harmless demos, causing unintended changes to requirements, tasks, or bugs.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
curl -H "Authorization: Bearer ACCESS_TOKEN" \
"https://api.tapd.cn/workspaces/projects"
返回:
These examples demonstrate creation of new stories and status-changing updates on remote TAPD records without telling users they will modify production project data. Because this is an agent skill intended for automation, omission of side-effect warnings makes accidental execution more likely and can lead to unauthorized or mistaken changes in shared workspaces.
The bulk update example performs repeated write operations against live TAPD records without any warning, confirmation step, dry-run mode, or sandbox guidance. In an automation/agent setting, users may run examples verbatim, causing unintended mass state changes to project data and workflow disruption.
The token cache section discusses direct cache inspection and credential handling without warning that the file contains live OAuth secrets. In practice, readers may expose tokens through console output, screenshots, shell history, or copied snippets, which can enable unauthorized TAPD API access if the token is reused before expiry.
The example explicitly instructs users to open the local token cache and print part of the access token, normalizing direct handling and display of sensitive credentials. In an agent skill context, this is dangerous because example code is often copied into terminals, logs, notebooks, or chat transcripts, increasing the chance that TAPD OAuth tokens are exposed beyond their intended scope.
The client persists the OAuth access token to a predictable file in the user's home directory without setting restrictive file permissions or giving the user control over secure storage. If the host is multi-user, backed up, synced, or otherwise exposed, a stolen token could allow unauthorized TAPD API access until expiry and possibly facilitate further project data access.