Back to skill

Security audit

UniFuncs Deep Search

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a real deep-search API client, but it has under-disclosed background execution and optional public-sharing behavior that users should review carefully.

Install only if you are comfortable sending deep-search queries and related prompt content to UniFuncs with your API key. Avoid --push-to-share and --set-public unless you intentionally want results shared or public, and avoid custom --stream-file paths in shared directories. Be aware that report mode may continue running in the background after the visible command returns.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
deep-search-report.py:185
Finding

Unsafe User-Specified Stream File Handling Enables Local Disclosure and Symlink-Based File Modification

Content
View full analysis
Optional[str]: """Return stream file path, preferring user-specified path.""" if specified_path: abs_path = os.path.abspath(specified_path) parent_dir = os.path.dirname(abs_path) or "." if not os.path.isdir(parent_dir): raise UniFuncsDeepSearchError(f"Stream file directory does not exist: {parent_dir}") if not os.access(parent_dir, os.W_OK): raise UniFuncsDeepSearchError(f"Stream file directory is not writable: {parent_dir}") if not os.path.exists(abs_path): with open(abs_path, "w", encoding="utf-8"): pass return abs_path return create_temp_stream_file() ``` The returned path is subsequently reopened in append mode and populated with API response data: ```python temp_path = resolve_stream_file_path(stream_file_path) content_parts: list[str] = [] done = False started_at = time.monotonic() try: with urllib.request.urlopen(req, timeout=DEFAULT_REQUEST_TIMEOUT_SECONDS) as response: writer = open(temp_path, "a", encoding="utf-8") if temp_path else None try: while True: if time.monotonic() - started_at >= stream_timeout_seconds: break line = response.readline() if not line: done = True break decoded = line.decode("utf-8", errors="replace") if writer: writer.write(decoded) ``` ### Technical Analysis When `--stream-file` is supplied, the implementation validates the path and ...[truncated 2253 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (27)

Tainted flow: 'req' from os.environ.get (line 121, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · deep-search-create-task.py (reported line 131)May include surrounding context.

python
method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=DEFAULT_REQUEST_TIMEOUT_SECONDS) as response:
            body = response.read().decode("utf-8")
            return json.loads(body)
    except urllib.error.HTTPError as err:

Tainted flow: 'req' from os.environ.get (line 56, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · deep-search-query-task.py (reported line 62)May include surrounding context.

python
method="GET",
    )
    try:
        with urllib.request.urlopen(req, timeout=DEFAULT_REQUEST_TIMEOUT_SECONDS) as response:
            body = response.read().decode("utf-8")
            return json.loads(body)
    except urllib.error.HTTPError as err:

Tainted flow: 'req' from os.environ.get (line 340, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · deep-search-report.py (reported line 173)May include surrounding context.

python
method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=DEFAULT_REQUEST_TIMEOUT_SECONDS) as response:
            body = response.read().decode("utf-8")
            try:
                return json.loads(body)

Tainted flow: 'req' from os.environ.get (line 340, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · deep-search-report.py (reported line 355)May include surrounding context.

python
method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=DEFAULT_REQUEST_TIMEOUT_SECONDS) as response:
            body = response.read().decode("utf-8")
            try:
                return json.loads(body)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The description presents the skill as a general-purpose deep search capability for comprehensive information gathering. However, this code does not initiate searches or conduct investigations; it only polls or retrieves the result of a previously created Deep Search task via query_task. That is a materially narrower primary purpose than advertised. Additionally, the code depends on network access to the UniFuncs API and use of UNIFUNCS_API_KEY, which is inconsistent with the empty declared permissions/resources. While making an HTTP request is a supporting implementation detail, the undisclosed need for authenticated external API access is still a notable resource mismatch.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The code makes external HTTPS calls but apparently does not declare network capability in permissions metadata. In an agent ecosystem, hidden network capability is a real security concern because it enables silent transmission of user prompts and related data to third-party services without clear authorization boundaries.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The code makes external HTTPS calls but apparently does not declare network capability in permissions metadata. In an agent ecosystem, hidden network capability is a real security concern because it enables silent transmission of user prompts and related data to third-party services without clear authorization boundaries.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · SKILL.md (reported line 96)May include surrounding context.

md
parser.add_argument("--max-depth", type=int, help="Maximum research depth.")
    parser.add_argument("--domain-scope", type=str, help="Comma-separated domain allowlist.")
    parser.add_argument("--domain-blacklist", type=str, help="Comma-separated domain blocklist.")
    parser.add_argument("--output-prompt", type=str, help="Custom output prompt template.")
    parser.add_argument("--important-urls", type=str, help="Comma-separated important URLs.")
    parser.add_argument("--important-keywords", type=str, help="Comma-separated important keywords.")
    parser.add_argument("--important-prompt", type=str, help="Important prompt content.")

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · deep-search-create-task.py (reported line 43)May include surrounding context.

python
parser.add_argument("--max-depth", type=int, help="Maximum research depth.")
    parser.add_argument("--domain-scope", type=str, help="Comma-separated domain allowlist.")
    parser.add_argument("--domain-blacklist", type=str, help="Comma-separated domain blocklist.")
    parser.add_argument("--output-prompt", type=str, help="Custom output prompt template.")
    parser.add_argument("--important-urls", type=str, help="Comma-separated important URLs.")
    parser.add_argument("--important-keywords", type=str, help="Comma-separated important keywords.")
    parser.add_argument("--important-prompt", type=str, help="Important prompt content.")

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · deep-search-report.py (reported line 77)May include surrounding context.

python
parser.add_argument("--max-depth", type=int, help="Maximum research depth.")
    parser.add_argument("--domain-scope", type=str, help="Comma-separated domain allowlist.")
    parser.add_argument("--domain-blacklist", type=str, help="Comma-separated domain blocklist.")
    parser.add_argument("--output-prompt", type=str, help="Custom output prompt template.")
    parser.add_argument("--important-urls", type=str, help="Comma-separated important URLs.")
    parser.add_argument("--important-keywords", type=str, help="Comma-separated important keywords.")
    parser.add_argument("--important-prompt", type=str, help="Important prompt content.")

Lp1

High
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The code can spawn a new process via subprocess.Popen, but shell/process-execution capability is not declared. In agent settings, undeclared process execution materially expands the skill's power and is especially concerning here because it is used to detach ongoing activity from the immediate user interaction.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The code can spawn a new process via subprocess.Popen, but shell/process-execution capability is not declared. In agent settings, undeclared process execution materially expands the skill's power and is especially concerning here because it is used to detach ongoing activity from the immediate user interaction.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The code can spawn a new process via subprocess.Popen, but shell/process-execution capability is not declared. In agent settings, undeclared process execution materially expands the skill's power and is especially concerning here because it is used to detach ongoing activity from the immediate user interaction.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The CLI exposes options to push results to a share space and mark them public, which goes beyond a narrow 'information gathering' function. In context, search results may include sensitive user queries or collected data, so publication features materially increase disclosure risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The request payload can instruct the remote API to share and publicize results, enabling transmission of user-derived content beyond returning a search response. This is particularly risky because the skill's stated purpose is research, not distribution, so users may not anticipate publication of outputs.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest says to use the skill for "deep search, broad investigation, or in-depth topic coverage," which are relatively broad natural-language triggers and do not define clear exclusion conditions. This may cause the skill to be invoked for ordinary information requests rather than only for genuinely expensive deep-search tasks.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The documented flags --push-to-share and --set-public introduce a publication path that can expose generated reports outside the local execution context. In a research skill, results may contain sensitive user queries, proprietary summaries, or collected data, so making sharing/publication available without strong guardrails increases data leakage risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · deep-search-create-task.py (reported line 15)May include surrounding context.

python
import urllib.request
from typing import Any, Dict, Optional

CREATE_TASK_ENDPOINT = "https://api.unifuncs.com/deepsearch/v1/create_task"
DEFAULT_MODEL = "s3"
DEFAULT_REQUEST_TIMEOUT_SECONDS = 180

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · deep-search-query-task.py (reported line 16)May include surrounding context.

python
import urllib.request
from typing import Any, Dict, Optional

CREATE_TASK_ENDPOINT = "https://api.unifuncs.com/deepsearch/v1/create_task"
DEFAULT_MODEL = "s3"
DEFAULT_REQUEST_TIMEOUT_SECONDS = 180

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · deep-search-report.py (reported line 18)May include surrounding context.

python
import urllib.request
from typing import Any, Dict, Optional

CREATE_TASK_ENDPOINT = "https://api.unifuncs.com/deepsearch/v1/create_task"
DEFAULT_MODEL = "s3"
DEFAULT_REQUEST_TIMEOUT_SECONDS = 180

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The presence of --push-to-share and --set-public enables publishing results externally, which exceeds simple information retrieval and can expose sensitive user queries or generated content to a broader audience. In this skill context, that is more dangerous because deep-search tasks may include proprietary, personal, or confidential research topics.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The CLI exposes options that can publish data externally without an explicit warning about disclosure consequences at the point of use. This is risky because users may treat the tool as a private research utility while unintentionally making search outputs publicly accessible.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill starts a detached background worker to continue streaming after the apparent request lifecycle ends. This is dangerous in an agent context because it creates hidden ongoing execution, network use, and file writes that may outlive user awareness or platform supervision.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

The code spawns a detached background subprocess that re-executes the same script with user-influenced arguments and no user-visible confirmation. Although it does not invoke a shell and avoids classic command injection, it introduces persistence-like behavior and makes network/file activity continue after the main request flow, which is risky for an agent skill.

Content

Scanner excerpt · deep-search-report.py (reported line 324)May include surrounding context.

python
cmd.append("--push-to-share")
    if args.set_public:
        cmd.append("--set-public")
    subprocess.Popen(
        cmd,
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Background subprocess execution occurs without user-facing warning or confirmation at the moment it is started. Silent continuation of execution is risky because users may believe the operation ended while the skill keeps performing network requests and writing to disk.

Content

No source excerpt is available for this finding.