T09 · Insecure Skill Coding Practices
- Location
references/vendor/feapder-1.9.2/feapder/core/spiders/task_spider.py:358- Finding
Arbitrary Code Execution Through Redis Task Deserialization
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This feapder helper is coherent, but it relies on an old crawler snapshot with unsafe Redis parsing and weak secret/storage warnings, so it needs review before use.
Use this only for feapder 1.9.2 work. Avoid shared or untrusted Redis for task queues and response caches unless the eval-based paths are patched or disabled, do not paste live session cookies into shell examples, keep database credentials out of shell history and source files, and test DB/task updates against non-production systems first.
references/vendor/feapder-1.9.2/feapder/core/spiders/task_spider.py:358Arbitrary Code Execution Through Redis Task Deserialization
references/vendor/feapder-1.9.2/feapder/network/request.py:523Arbitrary Code Execution Through Poisoned Redis Response Cache Entries
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
<!--
* @Author: Boris
* @Date: 2020-06-21 22:32:55
* @Description:
-->
# 命令行工具
命令行工具为**feapder**内置支持的,可方便快速的创建项目、爬虫、item、以及调试请求等,使用方法如下:
## 1.查看支持的命令行
打开命令行窗口,输入feapder
>feapder
feapder 1.1.3
Usage:
feapder <command> [options] [args]
Available commands:
create create project、feapder、item and so on
shell debug response
zip zip project
Use "feapder <command> -h" to see more info about a command
可见feapder支�
The code deserializes Redis task data with Python eval(), which executes arbitrary Python expressions rather than safely parsing structured data. If an attacker can influence the Redis zset contents, they can achieve arbitrary code execution in the spider process; in a crawler/framework context this is especially dangerous because task data is treated as operational input and may come from shared or externally populated queues.
def get_task_from_redis(self):
tasks = self._redisdb.zget(self._task_table, count=self._task_limit)
tasks = [eval(task) for task in tasks]
return tasks
def get_todo_task_from_mysql(self):
The cached-response retrieval path is presented as ordinary debugging cache logic, but it deserializes Redis data using eval(), creating a hidden code-execution sink. In a scraping framework, cache stores are often shared infrastructure, so treating cache content as trusted code is especially dangerous.
The code calls eval() on data read from Redis cache, which treats cached content as Python code rather than passive data. If an attacker can poison Redis, influence the cache key/value, or reach a shared Redis instance, this becomes arbitrary code execution in the crawler process.
log.info("无response缓存 重新下载")
response_obj = self.get_response(save_cached=save_cached)
else:
response_dict = eval(response_dict)
response_obj = Response.from_dict(response_dict)
return response_obj
This is the same dangerous sink as the eval() finding: unvalidated cached output is executed as Python code. Because the source is Redis rather than a compile-time constant, any compromise of cache contents can directly lead to remote code execution.
log.info("无response缓存 重新下载")
response_obj = self.get_response(save_cached=save_cached)
else:
response_dict = eval(response_dict)
response_obj = Response.from_dict(response_dict)
return response_obj
The skill describes code-generation and debugging workflows for web crawling, distributed workers, Redis/MySQL integration, render usage, and shell/debug commands, but it declares no explicit tool scope or permissions boundary. In an agent environment, that mismatch can let the skill be invoked in contexts where network or environment access is broader than intended, increasing the risk of unintended outbound requests, data access, or unsafe execution guidance.
The file instructs the skill to default to concise Chinese log messages and Chinese code comments. This is a natural-language locale policy constraint that forces a specific language unless the user asks otherwise, rather than offering a language choice or documenting a justified region-specific requirement.
These lines direct the skill to write log messages in Chinese by default and comments in Chinese by default. That is a clear language policy violation under the audit rules because it imposes a specific locale without opt-in or a documented necessity.
The interface metadata and default prompt force Chinese-language behavior without checking the user's language preference. This can override user expectations, degrade reliability, and in security-sensitive workflows increase the chance of misunderstanding instructions, code changes, or warnings.
The default prompt hard-codes invocation of the feapder skill and a broad set of actions (write, modify, debug), which can cause the skill to be selected in situations where the user's request is only loosely related. This is primarily a scope-control weakness: it can lead to incorrect routing, unexpected tool behavior, or reduced user control over how requests are handled.
The markdown explicitly says to default to Chinese runtime logs and Chinese comments, which imposes a specific language choice as a default policy. Under the stated policy rules, forcing a specific language without user opt-in is a natural-language policy violation.
This markdown file is in scope for vague-trigger checks, and the phrase "if the user only says 'write a feapder spider'" is a natural-language activation cue that may be too broad for reliable routing. It lacks explicit negative examples or tighter constraints beyond a subjective assessment that the request "looks like" a demo, which can cause unintended invocation or misclassification.
This markdown file introduces the skill as a powerful web-crawling framework and later shows a live request example, but it does not include any user-facing warning about scraping behavior that may affect third-party services or involve collection/transmission of external data. For markdown files, the rubric requires warnings when behavior could affect privacy or system integrity, and web crawling is such a case.
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.
feapder <command> [options] [args]
Available commands:
create create project、feapder、item and so on
shell debug response
zip zip project
The documentation instructs users to place MySQL credentials directly on the command line and persist them in shell profile environment variables, but gives no warning about credential exposure. Command-line arguments may be visible in shell history or process listings, and long-lived environment variables increase the chance of accidental leakage to logs, child processes, or shared environments.
The example demonstrates pasting a full curl command containing live Cookie headers into the shell debugging tool without any caution about session-token sensitivity. Users may reuse production session cookies, exposing authenticated sessions through terminal history, screenshots, shared docs, logs, or accidental transmission to unintended targets.
This markdown file includes examples for setting MySQL connection parameters, including username and password fields, but does not warn users that these values are sensitive credentials that should not be hardcoded or committed to source control. Under the markdown-specific warning rule, documentation that guides users to configure credentials should disclose the privacy/security implications when handling secrets.
This markdown file explains that each batch will reset non--1 tasks to 0 and re-fetch them, which can materially affect external systems and collected data scope. The surrounding documentation does not include a warning about the operational impact of reprocessing targets or the need to verify authorization and load implications before enabling this behavior.
This markdown section explains that scraped data will be automatically batch-inserted into a database and even names the destination table, but it does not clearly warn users that running the example can modify persistent data. For markdown files, SQP-2 applies when the skill description omits warnings about behaviors that could affect user data or system integrity.
Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.
# 关闭打点
metrics.close()
def join(self, timeout=None):
"""
重写线程的join
"""
The warning at L1082-L1084 says debug mode '不会更新任务状态及数据入库,仅用于调试' (will not update task status or store data), but the class still exposes update paths guarded only by the user-controlled _update_task flag. In update_task_state and update_task_batch at L1152-L1194, setting update_task=True causes real MySQL task-table updates, which directly contradicts the stated debug-mode behavior.
The warning at L245-L247 states that in debug mode '数据入库' will not occur, implying no database persistence. However, L253-L256 only switches to the console pipeline when save_to_db is false; when save_to_db is true, the class updates custom settings without disabling normal item pipelines, so data can still be persisted. This is an active contradiction between the documentation/warning and actual behavior.
This finding points to the same unsafe Redis task deserialization path: queued task values are parsed with eval() without any warning or trust boundary disclosure. The missing disclosure is not the core issue, but it does increase operational risk because users may assume Redis task contents are treated as data when they are actually executable input.
The warning explicitly says that in debug mode the spider will not update task status or persist data. However, the class accepts an update_task flag and both update_task_state and update_task_batch perform MySQL updates when that flag is enabled, so the documented intent contradicts actual behavior.
The debug log prints self.requests_kwargs, which can include headers, cookies, auth material, and proxies. This can leak session tokens or credentials into log files, monitoring systems, or support artifacts, expanding exposure beyond the runtime process.
Detected: suspicious.dynamic_code_execution