T09 · Insecure Skill Coding Practices
- Location
weather_report.py:49- Finding
Plaintext Credential Storage Misrepresented as Encryption
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This weather skill performs weather reporting, but it also reads local email credentials and can send reports to a hard-coded outside email address by default.
Review before installing. Treat TOOLS.md as plaintext, keep it out of version control, avoid wildcard API host allowlists, and only run the script with an explicit intended recipient and low-privilege dedicated credentials.
weather_report.py:49Plaintext Credential Storage Misrepresented as Encryption
weather_report.py:84Automatic Email Delivery to an Undisclosed Hard-Coded Recipient
SKILL.md:198Documentation Recommends Disabling QWeather Host Restrictions
The declared purpose is weather retrieval, but the documented behavior also includes reading workspace secrets from TOOLS.md and sending outbound email. This mismatch is security-relevant because users and policy engines may approve the skill expecting simple API lookups, while the actual behavior expands into credential handling and exfiltration-capable delivery channels.
The skill advertises network access and implicit file-reading behavior through its instructions, but it does not declare an explicit permission or allowed-tools scope. In an agent environment, missing scope declarations can cause overbroad execution authority and reduce reviewability, making it easier for the skill to access local files such as TOOLS.md and perform outbound requests without clear user visibility.
The description and title present the skill as explicitly Chinese-language and China-specific, with no indication that users may choose another language or locale. Under the policy rule, forcing a specific language without user opt-in is a natural-language locale policy violation unless clearly justified as region-specific compliance tooling, which is not stated here.
The document claims secrets in TOOLS.md are encrypted, but the example instructions show plain-text storage of API keys and email authorization codes. This creates a false sense of security that may lead users to store highly sensitive credentials unprotected in the workspace, where they can be read by local tools, other skills, or accidental disclosure mechanisms.
The script reads SMTP credentials from TOOLS.md even though the stated purpose is weather retrieval, expanding its privilege scope beyond what users would expect. Access to email credentials enables outbound messaging and potential misuse of a sensitive account if the skill is invoked in an untrusted context.
The script silently loads sensitive credentials from TOOLS.md with no meaningful runtime disclosure or consent flow. In an agent setting, hidden access to local secrets is dangerous because users may not realize the skill consumes and later uses credentials for external actions.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"""Open-Meteo API(免费,无需 Key)"""
def get_weather(self, city):
url = "https://api.open-meteo.com/v1/forecast"
params = {
"latitude": city["lat"],
"longitude": city["lon"],
The skill is described as fetching weather data, but it also sends email, which is a materially broader capability involving outbound communication to third parties. This increases risk because a user or platform may grant or trust the skill for data retrieval while it can also exfiltrate content through email, especially given the default recipient behavior.
The documentation presents TOOLS.md handling as a secure automatic-loading mechanism and later repeats that sensitive info is 'encrypted' there, but the only concrete mechanism shown is storing secrets in a local markdown file. This creates a misleading security narrative about how secrets are actually handled, which could cause users to overtrust the setup.
The documentation claims sensitive configuration comes from TOOLS.md, yet the code hardcodes a default recipient address. This creates undisclosed outbound data flow to a fixed third party, which is risky because generated reports may be emailed automatically even when the user did not specify a recipient.
The script sends city latitude/longitude to the Open-Meteo service to retrieve forecasts. While this is functionally expected for a weather script, the code provides no explicit disclosure that location data is sent to external services.
The script makes external requests to QWeather using a sensitive API key and city identifiers, but does not clearly disclose this outbound transmission to the user. Visible disclosure is recommended for network operations involving credentials or system configuration.