T09 · Insecure Skill Coding Practices
- Location
env-example.txt:1- Finding
Gitea credentials and confidential meeting content are transmitted over plaintext HTTP
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill matches a real meeting-minutes automation workflow, but it needs review because it can broadly scan and modify Gitea repositories and its default setup can send tokens and meeting data over plaintext HTTP.
Install only in the intended controlled AIFusion environment. Before use, change Gitea to HTTPS, use a repo-scoped bot token, add an explicit repository allowlist, run dependencies in a virtual environment with pinned versions, constrain commit-content input files to a controlled temp directory, and enforce valid meeting state transitions before remote writes. Rotate any token that was used with the supplied HTTP endpoint.
env-example.txt:1Gitea credentials and confidential meeting content are transmitted over plaintext HTTP
scripts/commit_content.py:147Caller-controlled file paths allow arbitrary local files to be uploaded to Gitea
scripts/gitea_utils.py:136Scanner enumerates every token-visible repository and exposes excessive meeting data
scripts/commit_content.py:203Content commit operation can bypass required meeting workflow states
setup.sh:12Unpinned dependencies are forcibly installed into the system Python environment
scripts/set_failed.py:34Unescaped meeting metadata permits HTML injection in notification emails
| Meeting topic | {topic} |
| Organizer | {organizer} |
| Project | {repo} |
The declared description is about a specific business workflow: post-meeting retrieval of Tencent Meeting transcripts/minutes, issue extraction, generation of draft artifacts, and organizer notification. The supplied code does none of those things. Instead, it implements a generic logging helper that reads an existing file from a Gitea repo, appends a JSON line, and writes it back. While committing files to Gitea could be a supporting detail in the broader skill, this chunk's actual purpose is persistent logging, which is not mentioned in the declared description and is materially different from the stated meeting-minute and issue-generation workflow. Therefore this code chunk does not accurately represent the declared purpose.
The description presents a post-meeting automation that fetches Tencent Meeting artifacts, performs AI issue extraction, writes draft_issue.md and other files, commits them, and notifies the organizer. The supplied code does none of those main actions. Instead, it is an inventory/scan step that traverses managed repositories, reads meetings/*/meta.yaml, computes whether meetings are ready for post-processing, groups them into A/B/C classes, and outputs structured JSON for downstream use. While scanning may be a supporting part of a larger workflow, this chunk materially differs from the declared purpose because its primary behavior is repository state discovery and classification, including email lookup and manual transcript recovery detection. It also references 'brief-sent' state despite the declaration saying pre-meeting brief scenarios are out of scope. Therefore this code chunk does not accurately match the declared description.
The declared description presents the skill as the main automated post-meeting processing pipeline: retrieve transcript and AI minutes from Tencent Meeting, extract issues, generate draft artifacts, commit them, and notify for review. The actual code chunk does none of those core tasks. Instead, it implements a narrow failure-path helper that marks a meeting as transcript-failed when transcript retrieval has timed out, writes a log, and prepares an email asking the organizer to manually upload the transcript. While this may be related to the broader meeting-minutes workflow, it is a materially different primary purpose and includes undeclared behavior (state transition to transcript-failed and manual remediation email generation). Therefore this code chunk does not accurately match the declared purpose.
There is a clear description-behavior mismatch. The declared purpose describes a downstream post-meeting content-processing pipeline: retrieve transcript/minutes, extract issues, generate files, commit them, and notify reviewers. The code shown instead implements a state gatekeeper that advances a meeting into waiting-transcript only after scheduled end time plus 20 minutes. While this could be part of a larger pipeline, the actual chunk’s primary function is status transition and safety validation, which is not represented in the declared description. It also lacks the main declared capabilities entirely: no Tencent Meeting access, no transcript retrieval, no issue extraction, no draft file generation, and no organizer notification. Therefore the code chunk does not accurately match the declared purpose.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-c-fetch-minutes"
ENV_FILE="$CONFIG_DIR/.env"
echo "🚀 设置 Skill-C (fetch_minutes)..."
echo ""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-c-fetch-minutes"
ENV_FILE="$CONFIG_DIR/.env"
echo "🚀 设置 Skill-C (fetch_minutes)..."
echo ""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-c-fetch-minutes"
ENV_FILE="$CONFIG_DIR/.env"
echo "🚀 设置 Skill-C (fetch_minutes)..."
echo ""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-c-fetch-minutes"
ENV_FILE="$CONFIG_DIR/.env"
echo "🚀 设置 Skill-C (fetch_minutes)..."
echo ""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-c-fetch-minutes"
ENV_FILE="$CONFIG_DIR/.env"
echo "🚀 设置 Skill-C (fetch_minutes)..."
echo ""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-c-fetch-minutes"
ENV_FILE="$CONFIG_DIR/.env"
echo "🚀 设置 Skill-C (fetch_minutes)..."
echo ""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-c-fetch-minutes"
ENV_FILE="$CONFIG_DIR/.env"
echo "🚀 设置 Skill-C (fetch_minutes)..."
echo ""
Without declared permissions the skill's intent is opaque and cannot be validated.
The manifest description is written entirely in Chinese and describes the skill behavior without indicating any user language choice or opt-in. Under the policy rule for natural-language violations, this is a locale/language constraint that appears implicit rather than documented as an optional or region-specific setting.
Comments and command descriptions intended for operators are written in Chinese, and the CLI usage/help text also uses Chinese for operational details. This imposes a specific language on users without opt-in or justification, which matches the language/locale policy violation category.
The usage block is what end users see when invoking the CLI, and its command explanations are only in Chinese. Because no language choice or documented locale limitation is provided, this is a natural-language policy violation under the locale rule.
The email instruction explicitly tells users to confirm by saying a fixed Chinese phrase: "确认 {meeting_dir} 的 issue". This imposes a specific language on the user, and the file does not offer a language choice or explain a justified region-specific requirement, which matches the locale-policy violation criteria.
This file contains functions that create and update repository files via Gitea API calls, which can modify user or project data remotely. Although the functions are named descriptively, there is no confirmation prompt, visible user disclosure, or warning in comments/docstrings for the destructive side effect of writing to a repository.
The function get_managed_repos enumerates all repositories visible to the provided Gitea token and filters them by presence of a meetings directory, which exceeds the narrowly described purpose of processing known meeting repositories. In a scheduled automation context, broad repository discovery expands the blast radius of a compromised or overprivileged token and enables unintended access mapping across the entire Gitea instance.
This code fetches and then writes log content to a remote repository API using authenticated HTTP requests, which can transmit user or system data contained in entry. There is no confirmation prompt, print/log disclosure, or inline warning indicating that runtime events are being sent off-host.
The script forces all time parsing and current-time comparisons to use Asia/Shanghai. This is a locale-specific behavior, and the file does not offer user opt-in or explain that the skill is intended only for a China-based environment.
The script emits organizer_email and attendee_emails for every matched meeting into its JSON output. That creates unnecessary exposure of personally identifiable information to any downstream consumer, logs, schedulers, or operators that can read task output, expanding the blast radius beyond the Gitea API call that originally required the data.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
if [ ! -f "$ENV_FILE" ]; then
cp "$SKILL_DIR/env-example.txt" "$ENV_FILE"
chmod 600 "$ENV_FILE"
echo ""
echo "📝 已创建配置文件:$ENV_FILE"
echo "请编辑该文件,至少填入:"
The comment on L5 is written only in Chinese, which imposes a specific language in natural-language content without offering an alternative or user opt-in. This can violate language/locale policy expectations for broadly usable skills or configuration examples.
The dependency is specified with a lower bound only, so builds may resolve to different versions over time. This weakens reproducibility and can silently introduce vulnerable or incompatible releases into an automation skill that fetches meeting data and writes artifacts to Gitea.
requests>=2.28.0
python-dotenv>=1.0.0
PyYAML>=6.0
pytz>=2023.3
Requests has multiple known advisories, and because the manifest does not pin a specific version, it is impossible to verify whether the installed release is affected. This skill likely performs outbound API calls and may handle authentication material, so an affected requests version could expose credentials or weaken transport security.
Detected: suspicious.dangerous_exec