Back to skill

Security audit

ck-rag-skill

Security checks for vulnerabilities and agentic risk

Overview

This RAGFlow knowledge-base skill does what it says, but it ships reusable session credentials and sends user questions over plaintext HTTP to a fixed internal endpoint.

Review this before installing. Use only in a trusted internal environment after rotating the exposed token and session cookie, moving credentials to secure per-user configuration, using HTTPS, and avoiding a shared conversation ID. Do not send secrets or sensitive operational details through it until those issues are fixed.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/query_ragflow.py:18
Finding

Hardcoded reusable credentials and user queries transmitted over plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: scripts/query_ragflow.py, lines 18-20 and 68-80
Vulnerability Type: Hardcoded secrets and plaintext transmission of sensitive data
Risk Level: High

Vulnerable Code

python
API_URL = "http://172.28.20.46:30001/v1/conversation/completion"
AUTHORIZATION = "IjQxYThhZGYyMDZlYjExZjFhZDE1ODJkYzljOWQ1YmJmIg.aYvfEw.ElppYHks0F5ETowUlvqA1Th-XHE"
COOKIE = "session=.elxVyzOegCAMAMC_dHagCgh8hIDaRleQyfh3jYmD4w13Qh5dWt4ZEizixBmNxgsbKkbknKkcxcy43siB/MyNqkb5CONuTR2yyWQKbarxVe7a9dNywRHnEaYvfEw66dir-0J0wYtii0IOGJ11861RtRtxp4"
python
headers = {
    "Authorization": AUTHORIZATION,
    "Content-Type": "application/json",
    "Cookie": COOKIE
}

response = requests.post(
    API_URL,
    json=payload,
    headers=headers,
    stream=True,
    timeout=120
)

Technical Analysis

The source code contains a reusable authorization token and session cookie. Anyone with read access to the Skill package, source archive, logs containing the source, or a copied installation can recover and reuse these credentials.

The endpoint uses http:// rather than HTTPS. The authorization token, session cookie, and the complete user question in payload are therefore transmitted without transport encryption or server authentication. A network-positioned attacker can observe or modify the request and streamed response.

Sending user questions to RAGFlow is necessary for the declared functionality, but embedding reusable credentials and using plaintext HTTP exceed the minimum security exposure required to perform that function.

Attack Path

  1. An attacker obtains read access to the Skill package or intercepts traffic on the path to 172.28.20.46:30001.
  2. The attacker extracts the hardcoded authorization token and session cookie from the source or plaintext request headers.
  3. The attacker submits requests to the RAGFlow API under the compromised session.
  4. I ...[truncated 754 chars]
Remediation
View remediation

Remediation Suggestions

  1. Immediately revoke and rotate the exposed authorization token and session cookie.
  2. Remove all credentials from the repository and its retained history.
  3. Load credentials from environment variables or an approved secret manager:
    python
    import os
    
    API_URL = os.environ["RAGFLOW_API_URL"]
    AUTHORIZATION = os.environ["RAGFLOW_AUTHORIZATION"]
    COOKIE = os.environ["RAGFLOW_SESSION_COOKIE"]
    
  4. Require an https:// endpoint and retain certificate verification. Do not suppress TLS verification.
  5. Replace browser session cookies with a purpose-specific, least-privilege API credential where supported.
  6. Use short-lived, revocable credentials scoped only to the required knowledge base and query operation.
  7. Add secret scanning to CI and prevent credentials from being committed.
  8. Clearly notify users that their questions are sent to an external RAGFlow service, and avoid submitting secrets or unrelated private data.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/quick_test.py:13
Finding

Diagnostic client duplicates credentials and transmits them over plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: scripts/quick_test.py, lines 13-16 and 57-70
Vulnerability Type: Hardcoded secrets and insecure network transport
Risk Level: High

Vulnerable Code

python
API_URL = "http://172.28.20.46:30001/v1/conversation/completion"
AUTHORIZATION = "IjQxYThhZGYyMDZlYjExZjFhZDE1ODJkYzljOWQ1YmJmIg.aYvfEw.ElppYHks0F5ETowUlvqA1Th-XHE"
COOKIE = "session=.elxVyzOegCAMAMC_dHagCgh8hIDaRleQyfh3jYmD4w13Qh5dWt4ZEizixBmNxgsbKkbknKkcxcy43siB/MyNqkb5CONuTR2yyWQKbarxVe7a9dNywRHnEaYvfEw66dir-0J0wYtii0IOGJ11861RtRtxp4"
CONVERSATION_ID = "0e18393f0b6042f2bbf6b391c82835d1"
python
headers = {
    "Authorization": AUTHORIZATION,
    "Content-Type": "application/json",
    "Cookie": COOKIE
}

start_time = time()

try:
    response = requests.post(
        API_URL,
        json=payload,
        headers=headers,
        stream=True,
        timeout=60
    )

Technical Analysis

The pre-scan warning is confirmed. The diagnostic script contains the same reusable token and session cookie as the production query client and sends both to a plaintext HTTP endpoint.

A simple diagnostic query requires network access, but it does not require credentials to be embedded in distributable source code. Duplicating the secrets across files also increases the number of locations that must be secured and rotated.

Attack Path

  1. An attacker reads the diagnostic script from a deployment, source package, backup, or repository copy.
  2. The attacker extracts the authorization token and session cookie.
  3. The attacker replays them directly against the RAGFlow API.
  4. Alternatively, an attacker on the network path captures the plaintext request when the diagnostic test runs.
  5. The compromised credentials remain usable until they expire or are revoked.

Impact Assessment

The attacker may impersonate the embedded RAGFlow session and exercise all permissions gran ...[truncated 316 chars]

Remediation
View remediation

Remediation Suggestions

  1. Revoke and rotate the exposed credentials.
  2. Remove credential constants from the diagnostic script.
  3. Share a secure configuration loader with the primary client rather than duplicating secret values.
  4. Require HTTPS with certificate verification for diagnostic and production requests.
  5. Prefer a credential-free health endpoint for connectivity tests.
  6. If an authenticated functional test is necessary, use a dedicated, short-lived test token with minimal read-only permissions.
  7. Ensure diagnostic output never prints request headers, cookies, or tokens.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/query_ragflow.py:23
Finding

Fixed conversation identifier causes shared server-side context across invocations

Content
View full analysis

Vulnerability Details

File Location: scripts/query_ragflow.py, lines 23-62
Vulnerability Type: Insufficient session isolation
Risk Level: Medium

Vulnerable Code

python
# Fixed conversation_id, preserving conversational context
CONVERSATION_ID = "0e18393f0b6042f2bbf6b391c82835d1"
python
payload = {
    "conversation_id": CONVERSATION_ID,
    "messages": [
        {
            "content": "你好! 我是你的助理,有什么可以帮到你的吗?",
            "role": "assistant"
        },
        {
            "id": f"msg_{int(timestamp())}",
            "content": question,
            "role": "user",
            "files": [],
            "conversationId": CONVERSATION_ID
        }
    ]
}

Technical Analysis

Every invocation uses the same conversation identifier. If RAGFlow associates server-side history or metadata with this identifier, independent users and sessions are not isolated.

Preserving context can be legitimate within one user conversation, but globally reusing a single identifier exceeds what is necessary. The implementation has no per-user binding, reset mechanism, or indication that server-side access controls prevent one caller's context from influencing another caller.

The same fixed identifier is also duplicated in scripts/quick_test.py, allowing diagnostic requests to enter the production conversation context.

Attack Path

  1. One user submits crafted or sensitive content through the Skill.
  2. The server stores or associates that content with the fixed conversation identifier.
  3. A diagnostic run or a later query from another user reuses the same identifier.
  4. RAGFlow may use prior context when generating the later response.
  5. The later user may receive a response influenced by, or disclosing information from, the previous interaction.

This path depends on RAGFlow retaining context for the supplied identifier, which the Skill documentation explicitly s ...[truncated 386 chars]

Remediation
View remediation

Remediation Suggestions

  1. Generate a cryptographically random conversation identifier for each independent user session.
  2. Bind conversation identifiers to authenticated users on the server and verify ownership on every request.
  3. Do not use the production conversation identifier in diagnostic scripts.
  4. Provide an explicit reset operation and define server-side retention limits.
  5. For stateless knowledge-base retrieval, omit conversation history entirely if the API supports that mode.
  6. Add tests confirming that one user's query history cannot affect another user's results.

T08 · Insecure Dependencies

Note
Location
TROUBLESHOOTING.md:145
Finding

Troubleshooting guidance installs an unpinned third-party dependency

Content
View full analysis

Vulnerability Details

File Location: TROUBLESHOOTING.md, lines 145-150
Vulnerability Type: Unpinned dependency installation
Risk Level: Low

Vulnerable Code

bash
# Install dependency
pip3 install requests

# Verify installation
python3 -c "import requests; print(requests.__version__)"

Technical Analysis

The installation command resolves the newest available requests distribution at execution time. No reviewed version, lock file, package hash, isolated environment, or approved package index is specified.

The package name is legitimate and there is no evidence that this project intentionally installs a malicious dependency. Nevertheless, the unpinned command produces non-reproducible installations and exposes users to future compromised, incompatible, or unexpectedly changed releases.

Attack Path

  1. A user follows the troubleshooting instructions.
  2. pip resolves requests and its transitive dependencies from the configured package index.
  3. If an index, maintainer account, dependency release, or local package-source configuration is compromised, an affected distribution may be downloaded.
  4. Package installation or subsequent import executes attacker-controlled code with the privileges of the user running pip3.

This is a supply-chain hardening weakness; no current package compromise was established during the audit.

Impact Assessment

Exploitation could execute code with the privileges of the user performing the installation. If the command is run in a privileged environment, the impact could extend to that environment. Under normal non-root use, impact is limited to the user's account and associated virtual environment.

Remediation
View remediation

Remediation Suggestions

  1. Define dependencies in a version-controlled requirements file or project manifest.
  2. Pin a reviewed version and use hashes, for example:
    text
    requests==<reviewed-version> --hash=sha256:<verified-hash>
    
  3. Generate and review a lock file that includes transitive dependencies.
  4. Install inside a dedicated virtual environment rather than the system Python environment.
  5. Use an approved package index or internal mirror and retain TLS certificate verification.
  6. Add automated dependency vulnerability and integrity scanning to the release process.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill material also instructs connectivity testing and remote endpoint probing, which is materially different from a narrow KB-answering function. In an agent context, such hidden diagnostic/network behavior can be abused for unintended recon or can mislead operators about the true scope of outbound actions.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill material also instructs connectivity testing and remote endpoint probing, which is materially different from a narrow KB-answering function. In an agent context, such hidden diagnostic/network behavior can be abused for unintended recon or can mislead operators about the true scope of outbound actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill instructs sending user questions and conversation context to an external API but does not provide a clear privacy notice, consent step, or data-minimization guidance. Because the skill mentions reusing conversation context, there is elevated risk of leaking sensitive user or prior-session information to the remote service.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script contains hardcoded authentication material directly in source code, including an authorization token and session cookie. If this file is shared, committed, or exposed through logs or repositories, anyone with access can reuse those credentials to access the RAGFlow service and potentially impersonate the intended user.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill describes invoking both a local Python script and remote HTTP API but does not declare any tool scope or permission boundaries for shell/network use. This increases the chance of overbroad execution in an agent environment, where routine help requests could trigger outbound requests or command execution without explicit governance.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger conditions are very broad, covering general technical questions, troubleshooting, operations guidance, and many related scenarios. Overbroad triggering is risky because it can cause frequent invocation of a networked, shell-capable skill for ordinary requests, unnecessarily sending user content to an external service and expanding the attack surface.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The guide explicitly instructs users to open browser developer tools and copy live Authorization and Cookie values, but it provides no warning that these are secrets equivalent to session credentials. This encourages unsafe handling of bearer tokens/session cookies and increases the chance of credential leakage through notes, terminals, chat logs, screenshots, or shell history.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The troubleshooting guide instructs users to send Authorization and Cookie credentials in a direct curl request to an HTTP endpoint, which is clear external transmission of sensitive authentication material. Because the example uses plain HTTP rather than HTTPS, credentials and query content could be exposed to interception on the network or captured by intermediaries.

Content

Scanner excerpt · TROUBLESHOOTING.md (reported line 195)May include surrounding context.

bash
# 使用curl直接测试(不处理流式)
curl -X POST http://172.28.20.46:30001/v1/conversation/completion \
  -H "Authorization: 你的token" \
  -H "Content-Type: application/json" \
  -H "Cookie: session=你的cookie" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The packet-capture troubleshooting step recommends tcpdump on the API host/port without warning that HTTP headers and bodies may contain sensitive data, including Authorization tokens, cookies, and user prompts. In this skill context, the API examples already use live auth material over HTTP, so packet capture meaningfully raises exposure risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script hardcodes an Authorization token, a session cookie, and a fixed conversation identifier directly in source code. Embedded secrets can be reused by anyone with code access to impersonate the client, access the backing RAGFlow service, or interact with an existing conversation context, which is especially risky because the endpoint is an internal HTTP service and the credentials appear live rather than illustrative.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

The network request sends user content to an external service over plain HTTP rather than HTTPS, so prompts and credentials in headers may be exposed to interception or tampering on the network. External transmission is expected for a RAG query skill, but the combination of unauthenticated transport, embedded secrets, and potentially sensitive troubleshooting questions makes this materially risky in context.

Content

Scanner excerpt · scripts/query_ragflow.py (reported line 75)May include surrounding context.

python
try:
        # 发送POST请求(启用流式传输,设置较长超时)
        response = requests.post(
            API_URL,
            json=payload,
            headers=headers,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code transmits user-supplied questions together with session credentials to a remote API without any user-facing disclosure, consent, or data-handling warning. In practice this can leak sensitive prompts, operational details, or troubleshooting data to an external/internal service under a shared authenticated session, increasing privacy and cross-user data exposure risks.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

The script sends an authenticated request to a hardcoded internal API endpoint over plain HTTP, which exposes request metadata, tokens, cookies, and response contents to interception on the network path. In the context of a knowledge-base agent skill, this is more dangerous because it normalizes sending authenticated operational data to a remote service and could leak internal conversation context or credentials if reused beyond this trivial test.

Content

Scanner excerpt · scripts/quick_test.py (reported line 66)May include surrounding context.

python
start_time = time()

    try:
        response = requests.post(
            API_URL,
            json=payload,
            headers=headers,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The POST request sends conversation content and authentication headers to a remote API endpoint. The script prints progress information, but it does not clearly disclose before execution that user/system data and credentials will be transmitted over the network.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The entire troubleshooting guide is written in Chinese and does not indicate that language selection is optional or that the skill is intentionally region-specific. Under the policy, forcing a specific language without user opt-in can be a natural-language policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The natural-language instructions and examples are written only in Chinese, and the embedded assistant message is also fixed in Chinese, which effectively constrains interaction to a specific language. There is no indication that users may choose another language or that the locale restriction is intentional and documented.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The script injects a hard-coded Chinese assistant greeting into every request, which biases or constrains the conversation language regardless of user preference. Because no opt-in or language-selection mechanism is provided, this is a locale-policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The script's docstrings and console output are written exclusively in Chinese, which imposes a specific language on users without any opt-in or documented locale constraint. There is no indication that the tool is intentionally limited to a Chinese-speaking or region-specific audience.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script's comments and echoed status messages are entirely in Chinese, and it sends the fixed query text "你好". For a generally usable skill, this imposes a specific language/locale without any user opt-in or documented justification, which matches the natural-language policy concern for forced language choice.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.