Back to skill

Security audit

Tender Analysis System

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent tender-monitoring purpose, but its setup can install persistent scheduled jobs and repeatedly run package installation without enough user control or rollback guidance.

Review this skill before installing. Only run cron_setup.sh if you intentionally want recurring background jobs, run it as a least-privileged user, inspect your crontab afterward, and avoid enabling external notifications until recipient addresses, webhooks, and sensitive tender data handling are clear. Prefer pinned dependencies in an isolated environment before scheduled use.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (3)

T06 · System Persistence

Error
Location
cron_setup.sh:7
Finding

Persistent Scheduled Execution Through User Crontab

Content
View full analysis
/dev/null | grep -v "tender_analyzer"; echo "0 * * * * $SCRIPT_PATH >> $(pwd)/logs/cron.log 2>&1") | crontab - # 每2小时重点汇报 (crontab -l 2>/dev/null; echo "0 */2 * * * $SCRIPT_PATH --report >> $(pwd)/logs/report.log 2>&1") | crontab - ``` ### Technical Analysis The setup script directly modifies the invoking user's crontab and installs two jobs that execute `run.sh` every hour and every two hours. These jobs survive the initiating process and future login sessions, establishing cross-session persistence. Periodic execution is related to the declared monitoring functionality, and the README explicitly instructs users to run this setup script. However, persistent modification of the user's scheduler is not necessary for one-time tender analysis and exceeds the minimum privileges required for ordinary execution. The operation also occurs without confirmation, a preview of the exact changes, or an uninstall mechanism. The scheduled command points to files in the project directory. Any process or account capable of replacing or modifying `run.sh` or `tender_analyzer.py` can cause attacker-controlled code to execute automatically under the account that installed the cron jobs. If setup is performed by a privileged account, the scheduled execution inherits that account's privileges. ### Attack Path 1. The user follows the installation instructions and executes `cron_setup.sh`. 2. The script writes two persistent entries into the user's crontab. 3. The cron daemon subsequently invokes the project-controlled `run.sh` without further user approval. 4. A party that can alter the project directory, repository update, `run.sh`, or `tender_analyzer.py` can place arbitrary commands in the scheduled execution path. 5. At the next ...[truncated 678 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
run.sh:11
Finding

Unpinned Dependencies Installed During Every Runtime Invocation

Content
View full analysis
/dev/null || pip install -q pyyaml requests 2>/dev/null ``` ### Technical Analysis The runtime script invokes `pip` on every execution and requests mutable, unpinned versions of `pyyaml` and `requests`. It does not use a lock file, version constraints, package hashes, an isolated virtual environment, or an explicitly controlled package index. Python package installation can execute package build and installation logic. Consequently, compromise of a configured package index, a malicious dependency release, unsafe local `pip` configuration, or a tampered package artifact could convert an ordinary scheduled run into code execution. The fallback from `pip3` to `pip` also makes interpreter selection ambiguous. Depending on the environment and account permissions, packages may be installed into a user-wide or system-wide Python environment. Because `cron_setup.sh` repeatedly invokes `run.sh`, this supply-chain exposure is recurring rather than limited to initial installation. ### Attack Path 1. The user runs `run.sh`, or a persistent cron entry starts it automatically. 2. The script invokes `pip3 install` and falls back to `pip install` if the first command fails. 3. Pip resolves package versions using the active environment and configured package indexes. 4. A compromised index, malicious release, manipulated pip configuration, or tampered artifact supplies hostile package installation code. 5. Pip executes that code with the privileges of the user running the script. 6. When invoked through cron, execution can occur unattended and recur on later schedules. ### Impact Assessment Successful exploitation provides code execution as the invoking user during package installation. This may expose files, environment var ...[truncated 452 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
cron_setup.sh:10
Finding

Non-Idempotent Cron Installation Causes Duplicate Unattended Jobs

Content
View full analysis
/dev/null | grep -v "tender_analyzer"; echo "0 * * * * $SCRIPT_PATH >> $(pwd)/logs/cron.log 2>&1") | crontab - # 每2小时重点汇报 (crontab -l 2>/dev/null; echo "0 */2 * * * $SCRIPT_PATH --report >> $(pwd)/logs/report.log 2>&1") | crontab - ``` `run.sh`: ```bash # 运行分析 echo "🔍 开始标书分析..." python3 tender_analyzer.py ``` `tender_analyzer.py`: ```python def main(): """主函数""" print("🚀 标书分析助手启动...") config = load_config() db_path = config.get('storage', {}).get('path', './data/tenders.db') db = TenderDatabase(db_path) analyzer = TenderAnalyzer(config) reporter = TenderReporter(config) # 获取最近2小时的标书 recent_tenders = db.get_recent_tenders(hours=2) # 生成汇报 summary = reporter.generate_summary(recent_tenders) print("\n" + "="*60) print(summary) print("="*60) # 保存汇报到文件 report_file = os.path.join(DATA_DIR, f"report_{datetime.now().strftime('%Y%m%d_%H%M')}.md") os.makedirs(DATA_DIR, exist_ok=True) with open(report_file, 'w', encoding='utf-8') as f: f.write(summary) print(f"\n✅ 汇报已保存: {report_file}") if __name__ == '__main__': main() ``` ### Technical Analysis The hourly installation command attempts to remove existing entries by filtering for the string `tender_analyzer`. However, the generated cron entry contains the path to `run.sh`, not `tender_analyzer`. The filter therefore does not match the entry it created. The two-hour entry has no deduplication logic at all. Every repeated execution of `cron_setup.sh` consequently adds more scheduled jobs. These duplicate jobs can run concurrently and repeatedly install dependencies, access the SQLite database, and g ...[truncated 1560 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (12)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README documents outbound notification channels such as Feishu webhooks and email, but it does not warn users that tender content, analysis results, or potentially sensitive procurement data may be transmitted to third-party services. In a skill focused on government, finance, telecom, transportation, and SOE tender analysis, this omission can lead to unintentional data exfiltration or compliance violations if users enable notifications without understanding where data is sent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The entire skill description, workflow, report template labels, and user-facing reporting behavior are presented only in Chinese, with no indication that users may opt into another language or locale. Under the policy for natural-language violations, forcing a specific language without user choice is a reportable issue unless clearly justified as region-specific; this file does not explicitly document such a constraint or opt-in.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
96% confidence
Finding

Reading and rewriting crontab to add an hourly job establishes persistence by causing the referenced script to run repeatedly without further user action. In an agent skill context, unattended scheduled execution is more dangerous because it can continue invoking skill behavior after initial installation, potentially masking ongoing activity from the user.

Content

Scanner excerpt · cron_setup.sh (reported line 11)May include surrounding context.

sh
echo "设置定时任务..."

# 每小时运行
(crontab -l 2>/dev/null | grep -v "tender_analyzer"; echo "0 * * * * $SCRIPT_PATH >> $(pwd)/logs/cron.log 2>&1") | crontab -

# 每2小时重点汇报
(crontab -l 2>/dev/null; echo "0 */2 * * * $SCRIPT_PATH --report >> $(pwd)/logs/report.log 2>&1") | crontab -

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script modifies the user's crontab immediately and persistently without any confirmation, dry-run mode, or clear warning that it is installing recurring tasks. This creates a persistence mechanism and can surprise users by causing unattended execution of run.sh and log writes long after the script exits.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
97% confidence
Finding

This second crontab modification installs an additional recurring task every two hours with a --report argument, expanding persistence and increasing execution frequency/surface area. Multiple scheduled jobs make the behavior harder to notice and easier to persist across sessions.

Content

Scanner excerpt · cron_setup.sh (reported line 14)May include surrounding context.

sh
(crontab -l 2>/dev/null | grep -v "tender_analyzer"; echo "0 * * * * $SCRIPT_PATH >> $(pwd)/logs/cron.log 2>&1") | crontab -

# 每2小时重点汇报
(crontab -l 2>/dev/null; echo "0 */2 * * * $SCRIPT_PATH --report >> $(pwd)/logs/report.log 2>&1") | crontab -

echo "✅ 定时任务已设置"
echo ""

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

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.

Content

Scanner excerpt · cron_setup.sh (reported line 19)May include surrounding context.

sh
echo "✅ 定时任务已设置"
echo ""
echo "任务列表:"
crontab -l | grep tender

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The top-level documentation states the program '定时抓取招标信息,智能分析,生成报告' (scheduled fetch of tender information, intelligent analysis, and report generation). In the actual code path, main() only loads config, reads recent tenders from SQLite, generates a simple summary, and writes it to a markdown file; no fetching logic or LLM/intelligent analysis is implemented.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring defines the skill entirely in Chinese and presents its functionality only in that language. This is a natural-language locale constraint with no visible opt-in, language selection, or justification that the skill is region-specific, so it may violate language/locale policy requirements.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

文档全文以中文编写,未说明该技能仅面向中文用户或中国区域场景,也未提供语言选择。按照语言/locale 政策,若技能实际上强制特定语言,应有明确的适用范围说明或用户选择机制。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

This manifest/config file uses Chinese labels, comments, and field descriptions throughout, which can amount to a language policy issue if the skill implicitly requires Chinese without user opt-in. There is no indication in the file that users may choose another language or that the locale restriction is explicitly documented as a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

Comments and printed status messages are written in Chinese only, which imposes a specific language on users without opt-in or fallback. This can violate language or locale policies when the skill is expected to be usable in a broader environment.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

generate_report is documented as '生成分析报告' (generate analysis report), but the body fills major sections with placeholder text such as '待LLM深度分析...' and does not perform any analysis. This is a documentation-to-code divergence rather than a missing implementation detail because the function name/docstring present the output as an actual analysis report.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.