T09 · Insecure Skill Coding Practices
- Location
milb_fetcher/fetcher.py:773- Finding
Untrusted Remote Data Written to Spreadsheet Formula Contexts
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill appears to be a real procurement-scraping tool, but it needs review because it writes untrusted web data into Excel reports without formula hardening and accepts implicit local configuration that can alter network routing and output paths.
Install only if you are comfortable with a tool that contacts the named procurement websites and saves an Excel report locally. Open generated spreadsheets carefully because remote website text is not formula-sanitized, and avoid running it from untrusted directories since a local .env file can change proxy and output settings.
milb_fetcher/fetcher.py:773Untrusted Remote Data Written to Spreadsheet Formula Contexts
pyproject.toml:6Unpinned Third-Party Dependencies Permit Unreviewed Package Updates
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
配置加载模块 (milb-fetcher)
按优先级读取 .env 配置,缺失时使用默认值:
1. ~/.config/milb-fetcher/.env (用户全局配置)
2. ./.env (当前运行目录,最高优先级)
"""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
配置加载模块 (milb-fetcher)
按优先级读取 .env 配置,缺失时使用默认值:
1. ~/.config/milb-fetcher/.env (用户全局配置)
2. ./.env (当前运行目录,最高优先级)
"""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
配置加载模块 (milb-fetcher)
按优先级读取 .env 配置,缺失时使用默认值:
1. ~/.config/milb-fetcher/.env (用户全局配置)
2. ./.env (当前运行目录,最高优先级)
"""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
配置加载模块 (milb-fetcher)
按优先级读取 .env 配置,缺失时使用默认值:
1. ~/.config/milb-fetcher/.env (用户全局配置)
2. ./.env (当前运行目录,最高优先级)
"""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
配置加载模块 (milb-fetcher)
按优先级读取 .env 配置,缺失时使用默认值:
1. ~/.config/milb-fetcher/.env (用户全局配置)
2. ./.env (当前运行目录,最高优先级)
"""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
配置加载模块 (milb-fetcher)
按优先级读取 .env 配置,缺失时使用默认值:
1. ~/.config/milb-fetcher/.env (用户全局配置)
2. ./.env (当前运行目录,最高优先级)
"""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
配置加载模块 (milb-fetcher)
按优先级读取 .env 配置,缺失时使用默认值:
1. ~/.config/milb-fetcher/.env (用户全局配置)
2. ./.env (当前运行目录,最高优先级)
"""
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
配置加载模块 (milb-fetcher)
按优先级读取 .env 配置,缺失时使用默认值:
1. ~/.config/milb-fetcher/.env (用户全局配置)
2. ./.env (当前运行目录,最高优先级)
"""
Loading configuration from the current working directory's .env file can allow untrusted local project directories to override application behavior, including proxy settings and output paths. In an agent context that may be executed inside user-controlled workspaces, this increases the risk of configuration injection and unintended routing of network traffic through attacker-specified infrastructure.
Dict: 合并后的配置字典
"""
candidates = [
Path.home() / '.config' / 'milb-fetcher' / '.env',
Path.cwd() / '.env',
]
config = {}
Including a .env from the current directory means whoever controls the working directory can influence runtime configuration. In this skill, that could steer requests through an attacker-controlled proxy or redirect file output, which is more dangerous because the tool fetches external data and may run in shared or semi-trusted agent workspaces.
"""
candidates = [
Path.home() / '.config' / 'milb-fetcher' / '.env',
Path.cwd() / '.env',
]
config = {}
for path in candidates:
The skill advertises capabilities consistent with file access, networking, and shell execution but does not declare any explicit tool scope or permission boundaries. That creates an authorization gap where a broadly triggered skill could perform sensitive actions without clear least-privilege constraints or user visibility.
The description includes broad trigger phrases such as '抓取商机', '查新', and '采集招标', which can overlap with ordinary user requests and cause the skill to activate unexpectedly. Because the skill performs network collection and file output, accidental invocation can lead to unrequested external access and local artifact creation.
The skill description and activation phrases are presented only in Chinese, and the trigger conditions are defined solely using Chinese phrases. This can amount to a language policy violation if the skill implicitly requires a specific language without documenting user choice or opt-in.
The standalone trigger list ('抓取、采集、爬虫、查新、每日商机') is highly ambiguous and lacks context boundaries, increasing the chance of matching unrelated conversations. In a skill with network and filesystem effects, this raises the risk of unintended automation and data collection.
This Python file contains natural-language docstrings and console output in Chinese, including the module description and test output strings. Under the policy, forcing a specific language without user opt-in or a clearly documented regional justification is a natural-language policy violation.
This code file contains user-facing natural-language content such as the module docstring and later help text entirely in Chinese. Under the policy, forcing a specific language without opt-in is a violation unless the skill offers language choice or clearly documents a justified regional constraint, which this file does not.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 获取当前时间戳
try:
result = subprocess.run(['date', '+%s%3N'], capture_output=True, text=True)
_t = result.stdout.strip()
except:
_t = str(int(datetime.now().timestamp() * 1000))
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 获取当前时间戳
try:
result = subprocess.run(['date', '+%s%3N'], capture_output=True, text=True)
_t = result.stdout.strip()
except:
_t = str(int(datetime.now().timestamp() * 1000))
The help text says --yesterday is the default and shows python fetcher.py as fetching yesterday, but main() leaves target_date = None and auto_latest = True unless date options are passed. That causes fetch_all_bidding to auto-detect latest dates for some sources and use today's date for another, contradicting the documented default behavior.
The skill writes Excel output to disk by default but does not clearly warn the user in the description that files will be created locally. This can surprise users, lead to unwanted storage of potentially sensitive procurement data, and reduce informed consent around persistent artifacts.
The test output shown in the main block uses only Chinese labels, which enforces a specific language for anyone running the file directly. There is no indication that users can choose a different language or that the restriction is intentionally justified.
The manifest describes a web-scraping and Excel-reporting tool for procurement notices. Calling subprocess.run(['date', '+%s%3N']) introduces process-execution capability that is unnecessary for this purpose, since the code already has a Python fallback for generating the same timestamp.
In _get_weain_latest_date, the skill again executes the system date command only to build a request timestamp. This expands the skill's capabilities beyond straightforward network fetching and file output, without being required by the stated procurement-fetching purpose.
The manifest description is written only in Chinese ("军工采购商机自动抓取工具"), which can create a language/locale policy issue if users are not given a choice or the locale restriction is not documented. The file provides no indication that this skill is intentionally limited to Chinese-speaking users or a specific region.
The manifest declares the requests dependency without any version bounds or pinning, so deployments may resolve to vulnerable or incompatible releases depending on environment and install time. Because this skill fetches remote content from external procurement sites, an outdated HTTP client could expose credential leakage, TLS/verification flaws, or other network-facing issues if a bad version is installed.
No suspicious patterns detected.