Back to skill

Security audit

dpr_pro

Security checks for vulnerabilities and agentic risk

Overview

The skill appears purpose-built for RAGFlow administration, but it uses a powerful API key for uploads, updates, and deletions without enough destination and runtime guardrails.

Install only if you trust the configured RAGFlow server and can protect the RAGFLOW_API_KEY. Keep RAGFLOW_API_URL pinned to a trusted host, avoid using user-provided --base-url values, use least-privilege keys where possible, and verify exact dataset or document IDs before any delete operation.

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

Error
Location
scripts/common.py:113
Finding

Bearer Credential and Document Disclosure Through Unrestricted API Destinations

Content
View full analysis
str: base_url = ( cli_base_url or os.getenv("RAGFLOW_API_URL") or os.getenv("RAGFLOW_BASE_URL") or os.getenv("HOST_ADDRESS") or DEFAULT_BASE_URL ).strip() parsed = urllib.parse.urlsplit(base_url) if not parsed.scheme or not parsed.netloc: raise ConfigError("Invalid base URL. Use an absolute URL such as http://127.0.0.1:9380.") return base_url.rstrip("/") ``` `scripts/common.py:193-212`: ```python def request_json( url: str, api_key: str, *, method: str = "GET", body: bytes | None = None, content_type: str | None = None, accept: str = "application/json", ) -> dict[str, Any]: headers = {"Authorization": f"Bearer {api_key}"} if accept: headers["Accept"] = accept if content_type: headers["Content-Type"] = content_type request_obj = urllib.request.Request(url, headers=headers, data=body, method=method) try: with urllib.request.urlopen(request_obj, timeout=HTTP_TIMEOUT) as response: return decode_json_response(response.read()) ``` `scripts/upload.py:126-138`: ```python def upload_documents(dataset_id: str, file_paths: list[str], *, base_url: str, api_key: str) -> dict[str, Any]: missing = [path for path in file_paths if not Path(path).exists()] if missing: raise ConfigError("File(s) not found: " + ", ".join(missing)) boundary, body = _build_multipart(file_paths) url = f"{base_url}/api/v1/datasets/{dataset_id}/documents" request_obj = urllib.request.Request(url, data=body, method="POST") request_obj.add_heade ...[truncated 3595 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (26)

Tainted flow: 'request_obj' from os.getenv (line 208, 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 · scripts/common.py (reported line 211)May include surrounding context.

python
request_obj = urllib.request.Request(url, headers=headers, data=body, method=method)

    try:
        with urllib.request.urlopen(request_obj, timeout=HTTP_TIMEOUT) as response:
            return decode_json_response(response.read())
    except urllib.error.HTTPError as exc:
        body_bytes = exc.read()

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill metadata describes dataset/retrieval operations, but the body also includes model inventory functionality via /v1/llm/my_llms, which expands access beyond the declared purpose. Undeclared capability creep is dangerous because users and policy engines may authorize the skill for one data domain while it also exposes infrastructure or configuration intelligence.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill metadata describes dataset/retrieval operations, but the body also includes model inventory functionality via /v1/llm/my_llms, which expands access beyond the declared purpose. Undeclared capability creep is dangerous because users and policy engines may authorize the skill for one data domain while it also exposes infrastructure or configuration intelligence.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/upload.py list DATASET_ID --json

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/upload.py list DATASET_ID --json

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/upload.py list DATASET_ID --json

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/upload.py list DATASET_ID --json

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/upload.py list DATASET_ID --json

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/upload.py list DATASET_ID --json

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

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

md
- `GET /api/v1/datasets`
- `POST /api/v1/datasets`
- `PUT /api/v1/datasets/<dataset_id>`
- `DELETE /api/v1/datasets`
- `GET /api/v1/datasets/<dataset_id>/documents`
- `POST /api/v1/datasets/<dataset_id>/documents`
- `PUT /api/v1/datasets/<dataset_id>/documents/<document_id>`

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

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

md
- `GET /api/v1/datasets/<dataset_id>/documents`
- `POST /api/v1/datasets/<dataset_id>/documents`
- `PUT /api/v1/datasets/<dataset_id>/documents/<document_id>`
- `DELETE /api/v1/datasets/<dataset_id>/documents`
- `POST /api/v1/datasets/<dataset_id>/chunks`
- `DELETE /api/v1/datasets/<dataset_id>/chunks`
- `POST /api/v1/retrieval`

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
83% confidence
Finding

Chunk deletion is a destructive capability that appears in documented endpoints despite the skill stating chunk operations are out of scope. Because there are no corresponding chunk-deletion safety procedures like the dataset/document confirmation flow, this creates a realistic path to unintended destructive actions against indexed knowledge content.

Content

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

md
- `PUT /api/v1/datasets/<dataset_id>/documents/<document_id>`
- `DELETE /api/v1/datasets/<dataset_id>/documents`
- `POST /api/v1/datasets/<dataset_id>/chunks`
- `DELETE /api/v1/datasets/<dataset_id>/chunks`
- `POST /api/v1/retrieval`
- `POST /api/v1/chunk/retrieval_test`
- `GET /v1/llm/my_llms`

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/common.py (reported line 81)May include surrounding context.

python
def load_repo_env(repo_root: Path) -> None:
    env_path = repo_root / ".env"
    if not env_path.is_file():
        return

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/common.py (reported line 130)May include surrounding context.

python
def require_api_key() -> str:
    api_key = (os.getenv("RAGFLOW_API_KEY") or "").strip()
    if not api_key:
        raise ConfigError("RAGFLOW_API_KEY is not configured. Set it in the environment or in the repository .env file.")
    return api_key

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares operational behavior that relies on environment variables, file access, and network/API calls, but it does not declare any explicit tool scope or permission boundaries. This weakens reviewability and increases the chance that an agent can invoke sensitive capabilities without clear user- or platform-visible restrictions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The instruction says to use the skill when user intent matches the listed actions "in either Chinese or English," which imposes a language constraint in the skill's activation behavior. The file does not offer a user language choice or state that other languages are supported, so this is a natural-language locale policy concern.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill says it should not be used for chunk operations, yet it documents a chunk deletion endpoint in scope. Contradictory scope guidance around destructive operations is dangerous because an agent may still invoke deletion paths that reviewers believed were excluded.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The explicit conflict between 'do not use this skill for chunk editing' and the documented chunk endpoints creates ambiguous operational policy. Ambiguity around destructive APIs increases the risk of accidental or policy-bypassing deletion when the agent follows endpoint docs instead of higher-level scope text.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The delete_datasets function sends a DELETE request for one or more dataset IDs, which is a destructive operation. The code does not include a confirmation prompt, warning print/log message before execution, or inline comment/docstring disclosing the destructive action beyond the terse command name.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code issues a DELETE request to remove documents from a dataset, which is a destructive operation. While the CLI command name implies deletion, there is no confirmation prompt, pre-action warning, or explanatory comment/docstring in this file disclosing the irreversible effect before execution.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest description omits the model-listing feature documented later in the file, creating a scope disclosure gap. While not directly exploit code, this mismatch can mislead reviewers and users about what the skill can access and return.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/common.py (reported line 67)May include surrounding context.

python
return

    for stream_name in ("stdout", "stderr"):
        stream = getattr(sys, stream_name, None)
        if stream is None or not hasattr(stream, "reconfigure"):
            continue
        try:

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

At L057, _build_payload raises ConfigError, but that symbol is not imported anywhere in the file. This is not just incomplete documentation; the implementation for handling invalid dataset names diverges from the script's stated intent to create datasets reliably, because this path will fail with an unexpected NameError instead of the skill's normal ScriptError flow.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The manifest and argparse description frame this tool as a document-listing utility, but the code supports an --id filter that can be used to retrieve a single targeted document record from the dataset documents endpoint. This is a mild scope expansion beyond plain listing, even though it still stays within document-inspection behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code file performs a network request to the RAGFlow API via request_json(_build_documents_url(base_url, args), api_key), sending the dataset identifier and any provided filters such as keywords, document name, or document ID. While the CLI description states the script lists documents through the HTTP API, there is no explicit user-facing warning, confirmation, or logging at the point of transmission about sending user-supplied metadata to a remote service.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.